Generando Una Variable de Retraso

Generando una variable de retraso: Hace unos días, mi amigo me preguntó si hay alguna función en R para generar variables de retraso / adelanto en un dato. Frame o hizo algo similar a _n en stata. Le gustaría usar eso para limpiar su conjunto de datos en R.

En el manual de ayuda de stata: _n contiene el número de la observación actual.
Aquí hay un ejemplo para ilustrar lo que  hace:

set obs 10
generate x = _n
generate x_lag1 = x[_n-1]
generate x_lead1 = x[_n+1]

The data generated would be :
x = {1,2,3,4,5,6,7,8,9,10}
x_lag1 = {NA,1,2,3,4,5,6,7,8,9}
x_lead1 = {1,2,3,4,5,6,7,8,9,NA}

La característica clave es que el nuevo vector tiene la misma longitud que el vector original, por lo que podemos usarlo con el vector original u otro vector generado.

Una aplicación es crear una serie MA (solo un ejemplo, es mejor usar la función en cualquier paquete de series temporales para hacerlo)
generar x_ma_1 = (x [_n-1] + x [_n]) / 2

Busqué en Google un tiempo para eso, básicamente hay dos tipos de métodos para generar variables de retraso / adelanto en R: (referencia)

1> Función que genera un vector más corto (por ejemplo, embed (), running () en gtools
2> Función en ts, zoo, xts, dynlm, dlm.

Sin embargo, ambas soluciones no resuelven su problema. Luego escribí una función de “turno” para hacer la tarea:

shift<-function(x,shift_by){
stopifnot(is.numeric(shift_by))
stopifnot(is.numeric(x))

if (length(shift_by)>1) return(sapply(shift_by,shift, x=x))

out<-NULL

abs_shift_by=abs(shift_by)
if (shift_by > 0 )
out<-c(tail(x,-abs_shift_by),rep(NA,abs_shift_by))
else if (shift_by < 0 )
out<-c(rep(NA,abs_shift_by), head(x,-abs_shift_by))

else

out<-x out

}

Tenga en cuenta que el resultado depende de cómo se ordena el data.frame.

# Test
library(testthat)
expect_that(shift(1:10,2),is_identical_to(c(3:10,NA,NA)))
expect_that(shift(1:10,-2), is_identical_to(c(NA,NA,1:8)))
expect_that(shift(1:10,0), is_identical_to(1:10))
expect_that(shift(1:10,0), is_identical_to(1:10))
expect_that(shift(1:10,1:2), is_identical_to(cbind(c(2:10,NA),c(3:10,NA,NA))))

TszKin Julian Chan

Leave a Reply