2010-08-24 8 views
27

Lo más probable es que exponga que soy nuevo en R, pero en SPSS, los rezagos de ejecución son muy fáciles. Obviamente, este es un error del usuario, pero ¿qué me falta?Retraso básico en el vector R/dataframe

x <- sample(c(1:9), 10, replace = T) 
y <- lag(x, 1) 
ds <- cbind(x, y) 
ds 

Resultados en:

 x y 
[1,] 4 4 
[2,] 6 6 
[3,] 3 3 
[4,] 4 4 
[5,] 3 3 
[6,] 5 5 
[7,] 8 8 
[8,] 9 9 
[9,] 3 3 
[10,] 7 7 

que pensé que iba a ver:

 x y 
[1,] 4 
[2,] 6 4 
[3,] 3 6 
[4,] 4 3 
[5,] 3 4 
[6,] 5 3 
[7,] 8 5 
[8,] 9 8 
[9,] 3 9 
[10,] 7 3 

Cualquier orientación será muy apreciada.

Respuesta

23

Otra forma de lidiar con esto es mediante el paquete de zoológico, que tiene un método de retardo que se rellenará el resultado con NA:

require(zoo) 
> set.seed(123) 
> x <- zoo(sample(c(1:9), 10, replace = T)) 
> y <- lag(x, -1, na.pad = TRUE) 
> cbind(x, y) 
    x y 
1 3 NA 
2 8 3 
3 4 8 
4 8 4 
5 9 8 
6 1 9 
7 5 1 
8 9 5 
9 5 9 
10 5 5 

El resultado es un objeto de zoo multivariado (que es una matriz mejorada), pero fácilmente convertidos a un data.frame través

> data.frame(cbind(x, y)) 
+2

También tenga en cuenta que si z es una serie de zoológico entonces lag (z, 0: -1) es una serie de zoológico de dos columnas con la serie original y una serie retrasada. Además, coredata (z) devolverá solo la parte de datos de una serie de zoológico y como .data.frame (z) devolverá un marco de datos con la parte de datos de z como contenido de la columna. –

13

lag no cambia los datos, solo cambia la "base de tiempo". x no tiene "base de tiempo", por lo que cbind no funciona como esperaba. Pruebe cbind(as.ts(x),lag(x)) y observe que un "retraso" de 1 cambia los períodos adelante.

Sugeriría usar zoo/xts para series de tiempo. Las viñetas zoo son particularmente útiles.

+0

Ni '' zoo' ni xts' parece ser de valores, donde los consigo? – zwol

+2

'install.packages (" xts ") # esto también instalará zoo' –

6

lag() funciona con series de tiempo, mientras que está tratando de usar matrices desnudas. This old question sugiere el uso de embed lugar, así:

lagmatrix <- function(x,max.lag) embed(c(rep(NA,max.lag), x), max.lag+1) 

por ejemplo

> x 
[1] 8 2 3 9 8 5 6 8 5 8 
> lagmatrix(x, 1) 
     [,1] [,2] 
[1,] 8 NA 
[2,] 2 8 
[3,] 3 2 
[4,] 9 3 
[5,] 8 9 
[6,] 5 8 
[7,] 6 5 
[8,] 8 6 
[9,] 5 8 
[10,] 8 5 
0

Deshazte de lag.Cambiar su línea para y a:

y <- c(NA, x[-1]) 
+7

¡esto no es correcto! Probablemente quisiste decir 'y <- c (NA, cabeza (x, -1))' – TMS

21

que tenía el mismo problema, pero no quiero usar zoológico o XTS, así que escribí un simple lag function for data frames:

lagpad <- function(x, k) { 
    if (k>0) { 
    return (c(rep(NA, k), x)[1 : length(x)]); 
    } 
    else { 
    return (c(x[(-k+1) : length(x)], rep(NA, -k))); 
    } 
} 

Esto puede retrasarse hacia adelante o hacia atrás:

x<-1:3; 
(cbind(x, lagpad(x, 1), lagpad(x,-1))) 
    x  
[1,] 1 NA 2 
[2,] 2 1 3 
[3,] 3 2 NA 
+0

Digamos que quería hacer esta función en un vector pero lo preforma recursivamente para múltiples lags 'lagpad (x, -1: - 216) 'y la salida de esa información en un marco de datos (por ejemplo, lagpad (x, -1) se convierte en la variable # 1 del df, lagpad (x, -2) se convierte en la variable # 2 del df, lagpad (x, -3) se convierte variable # 3 de la df ... y así sucesivamente. ¿Tendría que encontrar 216 columnas o hay una forma más corta de adaptar su código a este escenario? – Danielle

2
tmp<-rnorm(10) 
tmp2<-c(NA,tmp[1:length(tmp)-1]) 
tmp 
tmp2 
2

Esto debe acomodar vectores o matrices, así como retardos negativos:

lagpad <- function(x, k=1) { 
    i<-is.vector(x) 
    if(is.vector(x)) x<-matrix(x) else x<-matrix(x,nrow(x)) 
    if(k>0) { 
     x <- rbind(matrix(rep(NA, k*ncol(x)),ncol=ncol(x)), matrix(x[1:(nrow(x)-k),], ncol=ncol(x))) 
    } 
    else { 
     x <- rbind(matrix(x[(-k+1):(nrow(x)),], ncol=ncol(x)),matrix(rep(NA, -k*ncol(x)),ncol=ncol(x))) 
    } 
    if(i) x[1:length(x)] else x 
} 
1

Uso de las funciones simplemente estándar r esto se puede lograr de una manera mucho más simple:

x <- sample(c(1:9), 10, replace = T) 
y <- c(NA, head(x, -1)) 
ds <- cbind(x, y) 
ds 
0

La forma más fácil para mí ahora parece ser la siguiente:

require(dplyr) 
df <- data.frame(x = sample(c(1:9), 10, replace = T)) 
df <- df %>% mutate(y = lag(x)) 
0

un simple La forma de hacer lo mismo puede ser copiar los datos a un nuevo marco de datos y cambiar el número de índice. Asegúrese de que la tabla original esté indexada secuencialmente sin espacios

p.

tempData <- originalData 
rownames(tempData) <- 2:(nrow(tempData)+1) 

si quieres que en la misma trama de datos como el uso original de una función cbind