用数据(它的一个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混合起来。
只是由于亚历克斯的评论了一些说明。 你有困难,了解什么是怎么回事的原因是,很多东西都在一行内完成。 所以它总是打破下来一个好主意。
什么是我们真正想要的? 我们希望有一个新的列lagret
和语法在data.table添加新列如下:
DT[, lagret := xxx]
其中xxx
必须与任何你想在栏填写了lagret
。 因此,如果我们只是想要一个新的栏位,让我们行,我们可能只需要调用
DT[, lagret := seq(from=1, to=nrow(DT))]
在这里,我们真正想要的滞后值logret
,但我们必须考虑到,有许多股票在这里。 这就是为什么我们做一个自我联接,即我们加入data.table DT
与本身的列stock_id
和date
,但因为我们希望每个股票的前值,我们使用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
现在由一个周期滞后。 但是实际上我们希望,在新的一列lagret
在DT
,所以我们只是通过调用得到该列[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日)。
更新:
在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
感谢马修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