En primer lugar, muchas gracias Carlos, Javier Rubén y Daniel por vuestra ayuda. He
aprendido mucho con cada una de vuestras sugerencias.
En particular, gracias a Carlos Ortega por el código con el segundo bucle. Está
curradÃsimo y me ha parecido muy buena la idea de separarlo en dos bucles. Lo he
aplicado a mis datos y obtengo:
ID YEAR CUSUM
1 100 2005 3
2 100 2006 3
3 100 2007 9
4 120 2006 7
5 120 2007 3
Que es casi lo que busco, pues lo que persigo obtener (diculpa Carlos porque me era
difÃcil explicar con palabras y de forma resumida el objetivo) es lo siguiente:
ID YEAR CUSUM
1 100 2005 3
2 100 2006 3 (se incorporan 0 datos nuevos: siguen habiendo 3 acumulados)
3 100 2007 6 (se incorporan 3 datos nuevos: hay 6 acumulados)
4 120 2006 7
5 120 2007 10 (se incorporan 3 datos nuevos: hay 10 acumulados)
Carlos, he usado tú código sobre el data frame:
# Mi data frame: datos2
datos2 <- data.frame(ID = c(rep(100,5),rep(120,4)),
FECHA = c("02/08/2005", "19/10/2005", "09/02/2007", "25/10/2007","29/10/2007",
"11/05/2006", "17/08/2006", "15/10/2006", "16/04/2007"),
CANTIDAD = c(1, 2, 1, 1, 1, 1, 5, 1, 3))
class(datos2$FECHA) # Es un factor
datos2$FECHA <- as.Date(datos2$FECHA,"%d/%m/%Y")
class(datos2$FECHA) # Ahora ya es una fecha
# Código
library(sqldf)
df.tmp <- sqldf("select ID,YEAR, sum(CANTIDAD) as cusum from datos2 group by ID,YEAR
order by ID,YEAR")
for(i in 1:nrow(df.tmp)) {
if(i==1 ) {
df.tmp$difID[i] <- 0
df.tmp$difYE[i] <- 0
}
else{
if(df.tmp$ID[i]!=df.tmp$ID[i-1] & (df.tmp$YEAR[i]-df.tmp$YEAR[i-1] <0)) {
df.tmp$difID[i] <- 0
df.tmp$difYE[i] <- 0
} else {
df.tmp$difID[i] <- df.tmp$ID[i] - df.tmp$ID[i-1]
df.tmp$difYE[i] <- df.tmp$YEAR[i] - df.tmp$YEAR[i-1]
}
}
}
#df.tmp (Lo comento porque no es el resultado finalmente buscado)
#------- Segundo bucle para introducir filas en los saltos de años
# Introduzco filas cuando el salto de años sea mayor que 2...
df.new <- 0
for(i in 1:nrow(df.tmp)) {
#Copio la fila tal cual cuando la diferencia en años es 0 o menor que dos.
if(df.tmp$difYE[i] < 2) {
df.new <- rbind(df.new, c(df.tmp$ID[i] , df.tmp$YEAR[i],df.tmp$cusum[i]))
} else {
# Si la diferencia en años es mayor que dos, ciclo en años y teniendo
# en cuenta que cusum se acumula...
cusum.cont <- df.tmp$cusum[i-1]
for(j in 1:(df.tmp$difYE[i]-1) ) {
df.new <- rbind(df.new, c(df.tmp$ID[i] , df.tmp$YEAR[i-1]+j
,df.tmp$cusum[i-1]))
cusum.cont <- cusum.cont + df.tmp$cusum[i-1]
}
# Y tras ciclar copio la fila en la que estaba
df.new <- rbind(df.new, c(df.tmp$ID[i] ,
df.tmp$YEAR[i],df.tmp$cusum[i]+cusum.cont))
}
}
# df.tmp (Lo comento al ser un data frame intermedio)
# Data frame finalmente buscado: df.new
df.new <- df.new[2:nrow(df.new),]
row.names(df.new) <- NULL
df.new <- as.data.frame(df.new)
names(df.new) <- c('ID', 'YEAR','CUSUM')
df.new
[[alternative HTML version deleted]]