řdata.table分组为滞后回归(R data.table grouping for lagge

2019-06-26 03:27发布

用数据(它的一个data.table对象)表如下所示:

      date         stock_id logret
   1: 2011-01-01        1  0.001
   2: 2011-01-02        1  0.003
   3: 2011-01-03        1  0.005
   4: 2011-01-04        1  0.007
   5: 2011-01-05        1  0.009
   6: 2011-01-06        1  0.011
   7: 2011-01-01        2  0.013
   8: 2011-01-02        2  0.015
   9: 2011-01-03        2  0.017
  10: 2011-01-04        2  0.019
  11: 2011-01-05        2  0.021
  12: 2011-01-06        2  0.023
  13: 2011-01-01        3  0.025
  14: 2011-01-02        3  0.027
  15: 2011-01-03        3  0.029
  16: 2011-01-04        3  0.031
  17: 2011-01-05        3  0.033
  18: 2011-01-06        3  0.035

上述可被创建为:

DT = data.table(
   date=rep(as.Date('2011-01-01')+0:5,3) , 
   stock_id=c(1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3),
  logret=seq(0.001, by=0.002, len=18));

setkeyv(DT,c('stock_id','date'))

当然,真正的表是有更多的stock_ids和日期大。 的宗旨,以重塑这个数据表,使得我可以1天滞后(或先前交易日在周末的情况下)与它们相应的log_returns运行所有stockid log_returns的消退。

最终的结果会是什么样子:

      date         stock_id logret lagret
   1: 2011-01-01        1  0.001    NA
   2: 2011-01-02        1  0.003    0.001
   3: 2011-01-03        1  0.005    0.003
   ....
  16: 2011-01-04        3  0.031  0.029
  17: 2011-01-05        3  0.033  0.031
  18: 2011-01-06        3  0.035  0.033

我发现这个数据结构,真正棘手打造没有我stockid混合起来。

Answer 1:

只是由于亚历克斯的评论了一些说明。 你有困难,了解什么是怎么回事的原因是,很多东西都在一行内完成。 所以它总是打破下来一个好主意。

什么是我们真正想要的? 我们希望有一个新的列lagret和语法在data.table添加新列如下:

DT[, lagret := xxx]

其中xxx必须与任何你想在栏填写了lagret 。 因此,如果我们只是想要一个新的栏位,让我们行,我们可能只需要调用

DT[, lagret := seq(from=1, to=nrow(DT))]

在这里,我们真正想要的滞后值logret ,但我们必须考虑到,有许多股票在这里。 这就是为什么我们做一个自我联接,即我们加入data.table DT与本身的列stock_iddate ,但因为我们希望每个股票的前值,我们使用date-1 。 需要注意的是,我们必须首先设置键做这样的连接:

setkeyv(DT,c('stock_id','date'))
DT[list(stock_id,date-1)]
    stock_id       date logret
 1:        1 2010-12-31     NA
 2:        1 2011-01-01  0.001
 3:        1 2011-01-02  0.003
 4:        1 2011-01-03  0.005
 5:        1 2011-01-04  0.007
 6:        1 2011-01-05  0.009
...

正如你所看到的,我们现在有我们想要的东西。 logret现在由一个周期滞后。 但是实际上我们希望,在新的一列lagretDT ,所以我们只是通过调用得到该列[3L](这意味着没有别的然后让我的第三列),并将其命名这个新列lagret

DT[,lagret:=DT[list(stock_id,date-1),logret][[3L]]]
          date stock_id logret lagret
 1: 2011-01-01        1  0.001     NA
 2: 2011-01-02        1  0.003  0.001
 3: 2011-01-03        1  0.005  0.003
 4: 2011-01-04        1  0.007  0.005
 5: 2011-01-05        1  0.009  0.007
...

这已经是正确的解决方案。 在这个简单的例子,我们不需要roll=TRUE ,因为有在日期没有间隙。 然而,在(如上面提到的,例如,当我们有周末),一个更现实的例子,可能有差距。 因此,让我们只是删除两天的做出这样一个现实的例子DT的第一只股票:

DT <- DT[-c(4, 5)]
setkeyv(DT,c('stock_id','date'))
DT[,lagret:=DT[list(stock_id,date-1),logret][[3L]]]
          date stock_id logret lagret
 1: 2011-01-01        1  0.001     NA
 2: 2011-01-02        1  0.003  0.001
 3: 2011-01-03        1  0.005  0.003
 4: 2011-01-06        1  0.011     NA
 5: 2011-01-01        2  0.013     NA
...

正如你所看到的,现在的问题是,我们没有为一月6日的值。 这就是为什么我们使用roll=TRUE

DT[,lagret:=DT[list(stock_id,date-1),logret,roll=TRUE][[3L]]]
          date stock_id logret lagret
 1: 2011-01-01        1  0.001     NA
 2: 2011-01-02        1  0.003  0.001
 3: 2011-01-03        1  0.005  0.003
 4: 2011-01-06        1  0.011  0.005
 5: 2011-01-01        2  0.013     NA
...

只要有如何的文档的外观roll=TRUE作品完全一样。 简而言之:如果无法找到以前的值(这里logret一月5日),它只是需要最后可用的(这里从1月3日)。



Answer 2:

更新:

在data.table,目前开发的版本v1.9.5 , shift()被实现#965 ,这在目前采用两种类型的type = "lag" (缺省)和type = "lead" 。 见?shift更多的使用情况。

有了这个,我们可以简单地这样做:

# type="lag" may be omitted, as it is the default.
require(data.table) ## 1.9.5+
DT[, lagret := shift(logret, 1L, type="lag"), by=stock_id]
#           date stock_id logret lagret
#  1: 2011-01-01        1  0.001     NA
#  2: 2011-01-02        1  0.003  0.001
#  3: 2011-01-03        1  0.005  0.003
#  4: 2011-01-04        1  0.007  0.005
#  5: 2011-01-05        1  0.009  0.007
#  6: 2011-01-06        1  0.011  0.009
#  7: 2011-01-01        2  0.013     NA
#  8: 2011-01-02        2  0.015  0.013
#  9: 2011-01-03        2  0.017  0.015
# 10: 2011-01-04        2  0.019  0.017
# 11: 2011-01-05        2  0.021  0.019
# 12: 2011-01-06        2  0.023  0.021
# 13: 2011-01-01        3  0.025     NA
# 14: 2011-01-02        3  0.027  0.025
# 15: 2011-01-03        3  0.029  0.027
# 16: 2011-01-04        3  0.031  0.029
# 17: 2011-01-05        3  0.033  0.031
# 18: 2011-01-06        3  0.035  0.033


Answer 3:

感谢马修Dowle的建议,我能够使用以下命令:

DT[,lagret:=DT[list(stock_id,date-1),logret,roll=TRUE][[3L]]]

结果是:

             date stock_id logret lagret
 1: 2011-01-01        1  0.001     NA
 2: 2011-01-02        1  0.003  0.001
 3: 2011-01-03        1  0.005  0.003
 4: 2011-01-04        1  0.007  0.005
 5: 2011-01-05        1  0.009  0.007
 6: 2011-01-06        1  0.011  0.009
 7: 2011-01-01        2  0.013     NA
 8: 2011-01-02        2  0.015  0.013
 9: 2011-01-03        2  0.017  0.015
10: 2011-01-04        2  0.019  0.017
11: 2011-01-05        2  0.021  0.019
12: 2011-01-06        2  0.023  0.021
13: 2011-01-01        3  0.025     NA
14: 2011-01-02        3  0.027  0.025
15: 2011-01-03        3  0.029  0.027
16: 2011-01-04        3  0.031  0.029
17: 2011-01-05        3  0.033  0.031
18: 2011-01-06        3  0.035  0.033


文章来源: R data.table grouping for lagged regression