13

次のようなデータ(その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とdatesがあります。このデータテーブルの形状を変更して、すべての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を混同せずに構築するのが非常に難しいと感じています。

4

3 に答える 3

21

アレックスのコメントによるいくつかの追加メモ。ここで何が起こっているのかを理解するのが難しいのは、多くのことが 1 行で行われるからです。そのため、物事を分解することは常に良い考えです。

私たちは実際に何を望んでいますか?新しいlagret列が必要で、data.table に新しい列を追加する構文は次のとおりです。

DT[, lagret := xxx]

どこxxxに列に入れたいものを入力する必要がありますlagret。したがって、行を提供する新しい列が必要な場合は、単に呼び出すことができます

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

ここで、実際には の遅れた値が必要ですがlogret、ここには多くの株があることを考慮する必要があります。そのため、自己結合を行います。つまり、data.tableDTをそれ自体と列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現在、1 ピリオド遅れています。しかし、実際には の新しい列lagretDTそれが必要なので、[[3L]] を呼び出してその列を取得し (これは、3 番目の列を取得することを意味します)、この新しい列に名前を付けます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それでは、最初の在庫の 2 日間を削除して、このような現実的な例を作成してみましょう。

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機能するかについてのドキュメントをご覧ください。一言で言えば、以前の値 (ここlogretでは 1 月 5 日) が見つからない場合、利用可能な最後の値 (ここでは 1 月 3 日から) が取得されます。

于 2012-09-11T09:52:44.873 に答える
2

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
于 2012-07-12T13:38:49.600 に答える