2012-05-29 15 views
6

Ho il seguente frame di dati.Ottenere le precedenti n-righe in un frame di dati?

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 

Ci sono diverse date e per ogni data, ho 10 valori di ID come mostrato sopra e un campo di valori. Quello che vorrei fare è che ogni id trovi i precedenti valori n nel campo "valore". Ad esempio, se n = 3, voglio che l'output sia come segue.

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 
... 

C'è un modo semplice per arrivare a questo tramite plyr o utilizzando mapply? Grazie mille in anticipo.

risposta

6

È possibile farlo abbastanza facilmente utilizzando funzioni 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)) 

Risultato

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 

Ha fatto un errore qui in precedenza - qui è una versione sapply in una funzione:

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

Che dà proprio questo:

 [,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 

È quindi possibile applicare questo ad ogni serie di date nei dati in questo modo:

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

che dà un sacco di liste per ciascuna data fissata. Si potrebbe rowbind questi in su per l'aggiunta di nuovo al set di dati con:

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

Sembra buono. Come la tenacia offerta dall'approccio funzionale di tapply/sapply e do.call. Sto ancora cercando di convincermi a pensare su quelle righe. – broccoli

3

Utilizzando data.table v1.9.5 + Questo è il più semplice:

library(data.table) 
setDT(dt) 

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

o ad appendere loro come colonne aggiuntive nella stessa data.table:

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