不均匀的“移位”:具有多个周期内和ID观察的导联/滞后

时间:2015-07-21 20:16:02

标签: r data.table

shift的使用被充分记录为获取变量的超前和滞后值的一种方法,但我努力将这种逻辑扩展到我在每个时期内有多个观察的情况部分或全部ID。

示例:

dt<-data.table(id=rep(1:2,c(6,3)),
               pd=rep(rep(1:3,2),c(1:3,1,1,1)),
               firm=c(rep(c("01","02"),c(4,2)),
                      c("04","05","06")))

基本方法是错误的:

dt[,paste0("firm_",c("lag","lead")):=
 .(shift(firm),shift(firm,type="lead")),by=id]
> dt
   id pd firm firm_lag firm_lead
1:  1  1   01       NA        01
2:  1  2   01       01        01
3:  1  2   01       01        01
4:  1  3   01       01        02 #all lags should be 01 for id 1 in pd 3
5:  1  3   02       01        02 #all leads should be NA for id 1 in pd 3
6:  1  3   02       02        NA
7:  2  1   04       NA        05
8:  2  2   05       04        06
9:  2  3   06       05        NA

我目前的解决方法是进行自我合并:

dt[setkey(unique(dt)[,.(pd,shift(firm),shift(firm,type="lead")),by=id],id,pd),
   c("lag","lead"):=.(i.V2,i.V3)]
> dt
   id pd firm lag lead
1:  1  1   01  NA   01
2:  1  2   01  01   01
3:  1  2   01  01   01
4:  1  3   01  01   NA
5:  1  3   02  01   NA
6:  1  3   02  01   NA
7:  2  1   04  NA   05
8:  2  2   05  04   06
9:  2  3   06  05   NA

这是正确的,但它非常混乱。有没有更简单的方法来实现这一目标?

1 个答案:

答案 0 :(得分:3)

这是没有合并的一种方式:

dt[,c("lag","lead"):={
  r <- rleid(pd)
  x <- .SD[,firm[1],by=pd]$V1
  lapply(c("lag","lead"), function(y) x[shift(r,type=y)] )
}, by=id]

就性能而言,可能比.SD行更快。我会尝试ave(firm,pd,FUN=function(x)x[1]),例如。