Bonjour,

Je pars d'un data frame (nommé deps) qui contient des départements, des cycles de visites dans ces départements, et l'année de chacun de ces cycles de visites pour chaque département :
dep cyc visite
33   1 1961
40   1 1961
19   1 1962
32   1 1962
47   1 1962
46   1 1963
...
63   2 1976
15   2 1977
33   2 1977
03   2 1978
09   2 1978
11   2 1978
...
Au maximum, il y a 4 cycles de visite par département (mais parfois 2 ou 3 seulement pour certains départements).

Mon objectif est de transformer ce data frame en un autre data frame contenant les départements en lignes, les années (de la plus ancienne du premier cycle à la plus récente du 4ème cycle), et dans chaque case le nombre d'années entre l'année de la colonne et le dernier passage dans le département (cycle le plus récent).

Avec l'exemple suivant, pour le département 33, ça donnerait :
dep 1961 1962 1963 1964 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 
33    1    2    3    4    6    7    8    9   10   11   12   13   14   15   16    1    2    3    4  
Au passage, on démarre volontairement la différence entre les années à 1. Comme le cycle 2 du département 33 a démarré en 1973, le nombre repart à 1 sur la colonne 1973...

J'ai bien un code pour faire ça, mais il passe par 2 boucles pour aller remplir les "cases" du data frame une à une :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
toto <- reshape(subset(deps, select = c(dep, visite, visite)), idvar = "dep", timevar = "visite", direction = "wide")
 
names(toto) <- c("dep", unique(deps$visite))
toto2 <- merge(toto, subset(deps, cyc == 1, select = c(dep, visite)), all.x = T)
names(toto2)[ncol(toto2)] <- "visite1"
toto2 <- merge(toto2, subset(deps, cyc == 2, select = c(dep, visite)), all.x = T)
names(toto2)[ncol(toto2)] <- "visite2"
toto2 <- merge(toto2, subset(deps, cyc == 3, select = c(dep, visite)), all.x = T)
names(toto2)[ncol(toto2)] <- "visite3"
toto2 <- merge(toto2, subset(deps, cyc == 4, select = c(dep, visite)), all.x = T)
names(toto2)[ncol(toto2)] <- "visite4"
 
toto3 <- toto2
as.integer(names(toto3)[2:45]) < toto3$visite1
for (i in 2:45) {
	for (j in seq(along = 1:nrow(toto3))) {
		if (as.integer(names(toto3)[i]) < toto3[j, "visite1"]) {
			toto3[j, i] <- 0
		} 
		else if(as.integer(names(toto3)[i]) < toto3[j, "visite2"]) {
			toto3[j, i] <- as.integer(names(toto3)[i]) - toto3[j, "visite1"] + 1
		}
		else if(is.na(toto3[j, "visite3"])) {
			toto3[j, i] <- as.integer(names(toto3)[i]) - toto3[j, "visite2"] + 1
		}
		else if(as.integer(names(toto3)[i]) < toto3[j, "visite3"]) {
			toto3[j, i] <- as.integer(names(toto3)[i]) - toto3[j, "visite2"] + 1
		}
		else if(is.na(toto3[j, "visite4"])) {
			toto3[j, i] <- as.integer(names(toto3)[i]) - toto3[j, "visite3"] + 1
		}
		else if(as.integer(names(toto3)[i]) < toto3[j, "visite4"]) {
			toto3[j, i] <- as.integer(names(toto3)[i]) - toto3[j, "visite3"] + 1
		}
		else {
			toto3[j, i] <- as.integer(names(toto3)[i]) - toto3[j, "visite4"] + 1
		}
	}
}
Voyez-vous un moyen plus performant (sans passer par des boucles) pour faire ça ? Mon problème vient du fait que je doive parcourir le data frame en ligne et en colonne, et du coup je ne m'en sors pas avec une combinaison d'apply dans les 2 dimensions...

Merci d'avance de votre aide,

ced