Ответ 1
Просто некоторые дополнительные примечания из-за комментария Alex. Причина, по которой вам трудно понять, что происходит здесь, заключается в том, что многое делается в одной строке. Поэтому всегда полезно сломать вещи.
Чего мы действительно хотим? Нам нужен новый столбец 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 января), он просто берет последний доступный (здесь с 3 января).