R - 如何最有效地 lag/lead data.table 中的多个列

R - How do I lag/lead multiple columns in a data.table by multiple periods most efficiently

有一个大的 data.table 存储一个日期列(每月),然后是一堆在各个 subjects/IDs 的各个日期测量的不同兴趣变量。现在我想为这些变量的一个子集(只有一些列)添加新计算的列,这些列导致 AND 滞后这些列 multiple 个周期全部在一次。那可行吗? 请参阅下面的一些示例数据的说明,这些示例数据代表了我的 table 的高级结构以及我到目前为止所做的尝试

Date        ID   Var_A   Var_B   Var_C
2000-01-31  1    100     500     1000
2000-02-28  1    200     600     1100
2000-03-31  1    300     700     1200
2000-04-30  1    400     800     1300 
2000-01-31  2    100     500     1000
2000-02-28  2    200     600     1100
2000-03-31  2    300     700     1200
2000-04-30  2    400     800     1300

dt[, `:=`(Var_A_Lag_1 = shift(Var_A_Lag_1, 1),
          Var_A_Lead_1 = shift(Var_A_Lead_1, 1, type = 'lead'),
          Var_A_Lag_2 = shift(Var_A_Lag_1, 2),
          Var_A_Lead_2 = shift(Var_A_Lead_1, 2, type = 'lead'),
          Var_B_Lag_1 = shift(Var_B_Lag_1, 1),
          Var_B_Lead_1 = shift(Var_B_Lead_1, 1, type = 'lead'),
          Var_B_Lag_2 = shift(Var_B_Lag_1, 2),
          Var_B_Lead_2 = shift(Var_B_Lead_1, 2, type = 'lead')),
   by = ID]

但这不是很有效率吗?我尝试了一些我认为非常直观并且可以工作但运气不好的东西。

cols_to_edit <- which(sapply(dt, is.numeric))
cols_to_edit <- colnames(dt[, cols_to_edit, with = FALSE])

# col names od shifted variables
col_names_lag_1 <- paste(cols_to_edit, "lag_1", sep = "_")
col_names_lag_2 <- paste(cols_to_edit, "lag_2", sep = "_")
col_names_lead_1 <- paste(cols_to_edit, "lead_1", sep = "_")
col_names_lead_2 <- paste(cols_to_edit, "lead_2", sep = "_")

# colnames for differences 
col_names_lag_1_d <- paste("d", cols_to_edit, "lag_1", sep = "_")
col_names_lag_2_d <- paste("d", cols_to_edit, "lag_2", sep = "_")
col_names_lead_1_d <- paste("d", cols_to_edit, "lead_1", sep = "_")
col_names_lead_2_d <- paste("d", cols_to_edit, "lead_2", sep = "_")

# Execute the shift command
dt_2[, (col_names_lag_1) := shift(cols_to_edit, 1), by = ID] 
# would have repeated for all new columns as defined above but it is not working. 

我基本上希望这个 table 中的所有数字变量都移动,比如在任一方向上分别移动 1 和 2。然后应将新计算的值分配给由上面声明的名称向量命名的列。在这里找不到与我的案例类似的任何其他问题。您有任何想法或知道执行此操作的最佳做​​法吗?

上下文: 这些变量是选定的指标作为回归模型的输入,要求输入以该格式提供。

这个 for 小循环怎么样:

cols <- grep("Var", names(dt), value = TRUE)
for ( i in 1:2 ) { # update for the number of shifts
  
  lag_names <- paste(cols, "Lag", i, sep = "_")
  dt[, (lag_names) := lapply(.SD, shift, i, type = "lag"), .SDcols = cols]
  
  lead_names <- paste(cols, "Lead", i, sep = "_")
  dt[, (lead_names) := lapply(.SD, shift, i, type = "lead"), .SDcols = cols]
  
}