Use un valor de la fila anterior en un cálculo R data.table

Quiero crear una nueva columna en una tabla de datos calculada a partir del valor actual de una columna y la anterior de otra. ¿Es posible acceder a las filas anteriores?

P.ej:

> DT  DT ABC 1: 1 10 100 2: 2 20 200 3: 3 30 300 4: 4 40 400 5: 5 50 500 > DT[, D := C + BPreviousRow] # What is the correct code here? 

La respuesta correcta debe ser

 > DT ABCD 1: 1 10 100 NA 2: 2 20 200 210 3: 3 30 300 320 4: 4 40 400 430 5: 5 50 500 540 

Con shift() implementado en v1.9.6 , esto es bastante sencillo.

 DT[ , D := C + shift(B, 1L, type="lag")] # or equivalently, in this case, DT[ , D := C + shift(B)] 

De NOTICIAS :

  1. La nueva función shift() implementa un lead/lag rápido de vector , list , data.frames o data.tables . Se necesita un argumento de type que puede ser “lag” (predeterminado) o “lead” . Permite un uso muy conveniente junto con := o set() . Por ejemplo: DT[, (cols) := shift(.SD, 1L), by=id] . Por favor, eche un vistazo a ?shift para obtener más información.

Ver el historial de respuestas anteriores.

Varias personas han respondido la pregunta específica. Vea el código a continuación para una función de propósito general que uso en situaciones como esta que pueden ser útiles. En lugar de solo obtener la fila anterior, puede ir tantas filas en el “pasado” o “futuro” como desee.

 rowShift <- function(x, shiftLen = 1L) { r <- (1L + shiftLen):(length(x) + shiftLen) r[r<1] <- NA return(x[r]) } # Create column D by adding column C and the value from the previous row of column B: DT[, D := C + rowShift(B,-1)] # Get the Old Faithul eruption length from two events ago, and three events in the future: as.data.table(faithful)[1:5,list(eruptLengthCurrent=eruptions, eruptLengthTwoPrior=rowShift(eruptions,-2), eruptLengthThreeFuture=rowShift(eruptions,3))] ## eruptLengthCurrent eruptLengthTwoPrior eruptLengthThreeFuture ##1: 3.600 NA 2.283 ##2: 1.800 NA 4.533 ##3: 3.333 3.600 NA ##4: 2.283 1.800 NA ##5: 4.533 3.333 NA 

Usando dplyr puedes hacer:

 mutate(DT, D = lag(B) + C) 

Lo que da:

 # ABCD #1: 1 10 100 NA #2: 2 20 200 210 #3: 3 30 300 320 #4: 4 40 400 430 #5: 5 50 500 540 

Basado en el comentario anterior de @Steve Lianoglou, ¿por qué no solo?

 DT[, D:= C + c(NA, B[.I - 1]) ] # ABCD # 1: 1 10 100 NA # 2: 2 20 200 210 # 3: 3 30 300 320 # 4: 4 40 400 430 # 5: 5 50 500 540 

Y evite usar seq_len o head o cualquier otra función.

Siguiendo la solución de Arun, se pueden obtener resultados similares sin referirse a .N

 > DT[, D := C + c(NA, head(B, -1))][] ABCD 1: 1 10 100 NA 2: 2 20 200 210 3: 3 30 300 320 4: 4 40 400 430 5: 5 50 500 540 

Agregué un argumento de relleno y cambié algunos nombres y lo llamé shift . https://github.com/geneotwig/geneotwig/blob/master/R/shift.R

Aquí está mi solución intuitiva:

Su dataframe

df = data.frame (A = 1: 5, B = seq (10,50,10), C = seq (100,500, 100))

Ahora crea la nueva columna

df $ D = c (NA, cabeza (df $ B, 4) + cola (df $ C, 4))

Aquí 4 es el número de filas menos 1. Si tiene, por ejemplo, 1000 filas, entonces 4 debe reemplazarse por 999. nrow (df) le proporciona el número de filas en un dataframe o en un vector. De manera similar, si desea tomar valores aún anteriores, reste de nrow 2, 3, … etc, y también ponga NA al principio. Espero que esto ayude.