2012-05-29 15 views
6

Tengo el siguiente marco de datos.¿Cómo llegar a las n filas anteriores en un marco de datos?

date id value 
2012-01-01 1 0.3 
2012-01-01 2 0.5 
2012-01-01 3 0.2 
2012-01-01 4 0.8 
2012-01-01 5 0.2 
2012-01-01 6 0.8 
2012-01-01 7 0.1 
2012-01-01 8 0.4 
2012-01-01 9 0.3 
2012-01-01 10 0.2 

Hay varias fechas y para cada fecha, tengo 10 valores de identificación como se muestra arriba y un campo de valor. Lo que me gustaría hacer es que para cada identificación encuentre los n valores previos en el campo "valor". Por ejemplo, si n = 3, entonces quiero que la salida sea la siguiente.

date id value value1 value2 value3 
2012-01-01 1 0.3 NA NA NA 
2012-01-01 2 0.5 NA NA NA 
2012-01-01 3 0.2 NA NA NA 
2012-01-01 4 0.8 0.2 0.5 0.3 
2012-01-01 5 0.2 0.8 0.2 0.5 
... 

¿Hay una manera fácil de conseguir esto a través de plyr o utilizando mapply? Muchas gracias de antemano.

Respuesta

6

Usted puede hacer esto con bastante facilidad utilizando funciones de base:

id <- 1:10 
value <- c(0.3,0.5,0.2,0.8,0.2,0.8,0.1,0.4,0.3,0.2) 
test <- data.frame(id,value) 

test$valprev1 <- c(rep(NA,1),head(test$value,-1)) 
test$valprev2 <- c(rep(NA,2),head(test$value,-2)) 
test$valprev3 <- c(rep(NA,3),head(test$value,-3)) 

Resultado

id value valprev1 valprev2 valprev3 
1 1 0.3  NA  NA  NA 
2 2 0.5  0.3  NA  NA 
3 3 0.2  0.5  0.3  NA 
4 4 0.8  0.2  0.5  0.3 
5 5 0.2  0.8  0.2  0.5 
6 6 0.8  0.2  0.8  0.2 
7 7 0.1  0.8  0.2  0.8 
8 8 0.4  0.1  0.8  0.2 
9 9 0.3  0.4  0.1  0.8 
10 10 0.2  0.3  0.4  0.1 

cometido un error aquí anteriormente - que aquí es una versión sapply en una función:

prevrows <- function(data,n) {sapply(1:n,function(x) c(rep(NA,x),head(data,-x)))} 
prevrows(test$value,3) 

que da solo esto:

 [,1] [,2] [,3] 
[1,] NA NA NA 
[2,] 0.3 NA NA 
[3,] 0.5 0.3 NA 
[4,] 0.2 0.5 0.3 
[5,] 0.8 0.2 0.5 
[6,] 0.2 0.8 0.2 
[7,] 0.8 0.2 0.8 
[8,] 0.1 0.8 0.2 
[9,] 0.4 0.1 0.8 
[10,] 0.3 0.4 0.1 

A continuación, puede aplicar esto a cada conjunto de fechas en los datos de la siguiente manera:

result <- tapply(test$value,test$date,prevrows,3) 

que da un montón de listas para cada fecha fijada. Se podría rowbind estas arriba para añadir de nuevo a su conjunto de datos con:

data.frame(test,do.call(rbind,result)) 
+0

Se ve bien. Como la concisión ofrecida por el enfoque funcional de tapply/sapply & do.call. Todavía estoy tratando de hacer que mi cabeza piense en esas líneas. – broccoli

3

Usando data.table v1.9.5 + esto es tan simple como:

library(data.table) 
setDT(dt) 

lags <- dt[, shift(value, n = c(1,2,3))] 

o para añadirlos como columnas adicionales en la misma data.table:

dt[, c("lag1", "lag2", "lag3") := shift(value, n = c(1,2,3))] 
Cuestiones relacionadas