Si, es buena y muy limpia en su lectura.

Reshape, es una de esas partes que siempre me gustaron pero nunca uso.

Javier Marcuzzi

El 12/03/14 06:40, Carlos Ortega escribió:
> Muy buena solución!
>
> Saludos,
> Carlos Ortega
> www.qualityexcellence.es
>
>
> El 12 de marzo de 2014, 10:07, "Olivier Nuñez" <onunez@unex.es> escribió:
>
>> Llego tarde al hilo, pero creo que se llega rápidamente al resultado con la
>> complicidad del paquete "reshape2". Si DT es el data.table que escojo
>> Francisco como
>> ejemplo:
>>
>>> DT
>>      ID YEAR CANTIDAD
>> 1: 100 2005        1
>> 2: 100 2005        2
>> 3: 100 2007        1
>> 4: 100 2007        1
>> 5: 100 2007        1
>> 6: 120 2006        1
>> 7: 120 2006        5
>> 8: 120 2006        1
>> 9: 120 2007        3
>>
>>> require(reshape2)
>>> temp=dcast.data.table(DT,ID~YEAR,sum,value.var="CANTIDAD")
>>> temp
>>      ID 2005 2006 2007
>> 1: 100    3    0    3
>> 2: 120    0    7    3
>>
>>> res=melt(temp,id.var="ID")
>>> setkey(res,ID,variable)
>>> res
>>      ID variable value
>> 1: 100     2005     3
>> 2: 100     2006     0
>> 3: 100     2007     3
>> 4: 120     2005     0
>> 5: 120     2006     7
>> 6: 120     2007     3
>>> res[,cumsum:=cumsum(value),by=ID]
>>> res
>>      ID variable value cumsum
>> 1: 100     2005     3      3
>> 2: 100     2006     0      3
>> 3: 100     2007     3      6
>> 4: 120     2005     0      0
>> 5: 120     2006     7      7
>> 6: 120     2007     3     10
>>
>>> subset(res,cumsum>0)
>>      ID variable value cumsum
>> 1: 100     2005     3      3
>> 2: 100     2006     0      3
>> 3: 100     2007     3      6
>> 4: 120     2006     7      7
>> 5: 120     2007     3     10
>>
>> Un saludo. Olivier
>>
>>> 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]]
>>>
>>> _______________________________________________
>>> R-help-es mailing list
>>> R-help-es@r-project.org
>>> https://stat.ethz.ch/mailman/listinfo/r-help-es
>>>
>>
>> --
>> ____________________________________
>>
>>
>> Olivier G. Nuñez
>> Email: onunez@unex.es
>> http://kolmogorov.unex.es/~onunez
>> Tel : +34 663 03 69 09
>> Departamento de Matemáticas
>> Universidad de Extremadura
>>
>>
>> ____________________________________
>>
>>
>>
>>
>
>
>
> _______________________________________________
> R-help-es mailing list
> R-help-es@r-project.org
> https://stat.ethz.ch/mailman/listinfo/r-help-es


	[[alternative HTML version deleted]]

