簡體   English   中英

R data.table分組用於滯后回歸

[英]R data.table grouping for lagged regression

帶有數據的表(它是一個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和日期。 目的是重新整形這個數據表,以便我可以運行所有stockid log_returns及其對應的log_returns的回歸,滯后為1天(或者在周末的情況下交易前一天)。

最終結果如下:

      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。

由於Alex的評論,還有一些額外的注釋。 你很難理解這里發生的事情是很多事情都是在一條線上完成的。 因此,打破局面總是一個好主意。

我們真正想要的是什么? 我們想要一個新的列lagret和在data.table中添加新列的語法如下:

DT[, lagret := xxx]

其中xxx必須用列lagret任何內容填充。 因此,如果我們只想要一個給我們行的新列,我們就可以調用

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

在這里,我們實際上想要logret的滯后值,但我們必須考慮到這里有很多股票。 這就是我們進行自我連接的原因,即我們通過列stock_iddate加入data.table DT ,但由於我們想要每個股票的先前值,我們使用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現在滯后了一個時期。 但是我們實際上想要在DT的新列lagret中,所以我們只需調用[[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
...

正如您所看到的,現在的問題是我們沒有1月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如何正常工作的文檔。 簡而言之:如果它找不到以前的值(這里是1月5日的logret ),它只需要最后一個(從1月3日開始)。

更新:

在data.table,目前開發的版本v1.9.5shift()被實現#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

感謝Matthew 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM