为 df 中的每个变量计算多个滞后并将结果存储到嵌套列表中

Calculate multiple lags for each variable in a df and store the results into nested lists

我有一个 df (data),我想将其作为参数传递给函数 fun.lag_cols 以计算(对于 df 中的每一列)几个滞后。结果必须存储在嵌套列表中,但我的函数似乎缺少(至少)一步。

data <- data.frame(x1 = rnorm(10,0,1)
               , x2 = rnorm(10,2,3)
               , x3 = rnorm(10,6,1))

fun.lag_cols <- function(x, lag_from = 0, lag_to = 2) {
  x <- as.data.frame(x)
  cols_x <- ncol(x)
  lst_lag <- list()
  
  for (i in 1:cols_x) {
    for(j in lag_from:lag_to) {
      lst_lag[[i]] <- dplyr::lag(x[,i],j)
    }
    
  }
  return(lst_lag)
}

output <- fun.lag_cols(data)

在此特定示例中,我希望将 output 视为包含 3 个元素(x1、x2、x3)的列表,每个元素都是一个包含 3 个元素的新列表(每个滞后 0、1、2 ).

我的代码似乎只为每个变量存储了 lag2(通常是最大滞后),显然不是预期的结果。

我对不同的方法持开放态度,只要它们提供最终输出(嵌套列表)即可。

谢谢

我们可以通过在嵌套循环内将元素与 lag 值连接来更改 'lst_lag[[i]]' 的赋值。在函数中,有两个更改 - 1) 初始化具有预定义长度的输出列表 (vector('list', ncol(x))),2) 在嵌套循环内,我们将第 i 个列表元素附加到新的子列表元素通过将现有的 list 与通过将 lag 包装在 list 中创建的新 list 连接起来,同时递归更新相同的列表元素 (<-)

fun.lag_cols <- function(x, lag_from = 0, lag_to = 2) {
  x <- as.data.frame(x)
  cols_x <- ncol(x)
  lst_lag <- vector('list', ncol(x))
  
  for (i in 1:cols_x) {
    for(j in lag_from:lag_to) {
      lst_lag[[i]] <- c(lst_lag[[i]], list(dplyr::lag(x[,i],j)))
    }
    
  }
  return(lst_lag)
}

-测试

fun.lag_cols(data)
[[1]]
[[1]][[1]]
 [1] -1.40431393 -2.22551238  0.06090537  0.77941726  1.10733091  1.20657717  0.71614034 -0.17990135  0.22058894  0.33598415

[[1]][[2]]
 [1]          NA -1.40431393 -2.22551238  0.06090537  0.77941726  1.10733091  1.20657717  0.71614034 -0.17990135  0.22058894

[[1]][[3]]
 [1]          NA          NA -1.40431393 -2.22551238  0.06090537  0.77941726  1.10733091  1.20657717  0.71614034 -0.17990135


[[2]]
[[2]][[1]]
 [1]  1.1334651  1.2385579  1.8930347 -4.7379766  2.0169352  0.7210822 -1.0322536  4.5446643  1.4421923  1.1316508

[[2]][[2]]
 [1]         NA  1.1334651  1.2385579  1.8930347 -4.7379766  2.0169352  0.7210822 -1.0322536  4.5446643  1.4421923

[[2]][[3]]
 [1]         NA         NA  1.1334651  1.2385579  1.8930347 -4.7379766  2.0169352  0.7210822 -1.0322536  4.5446643


[[3]]
[[3]][[1]]
 [1] 4.324912 5.114774 4.517017 7.001338 5.218430 4.408571 7.233504 6.875883 5.848294 4.696724

[[3]][[2]]
 [1]       NA 4.324912 5.114774 4.517017 7.001338 5.218430 4.408571 7.233504 6.875883 5.848294

[[3]][[3]]
 [1]       NA       NA 4.324912 5.114774 4.517017 7.001338 5.218430 4.408571 7.233504 6.875883

已经有一个函数可用于执行此操作,即 data.table 中的 shift,它采用矢量化 n

library(data.table)
shift(data, n = 0:2)

使用lapply

fun.lag_cols <- function(x, lag_from = 0, lag_to = 2) {
  val <- lag_from:lag_to
  lapply(x, function(v) 
    setNames(lapply(val, function(n) dplyr::lag(v, n)), paste0('lag_', val)))
}

fun.lag_cols(data)

#$x1
#$x1$lag_0
# [1] -1.5095832 -0.2638919  0.5986575  3.3043298  0.9471048 -1.2154015
# [7]  0.8921754 -1.6614204 -0.2036500  0.9570701

#$x1$lag_1
# [1]         NA -1.5095832 -0.2638919  0.5986575  3.3043298  0.9471048
# [7] -1.2154015  0.8921754 -1.6614204 -0.2036500

#$x1$lag_2
# [1]         NA         NA -1.5095832 -0.2638919  0.5986575  3.3043298
# [7]  0.9471048 -1.2154015  0.8921754 -1.6614204


#$x2
#$x2$lag_0
# [1] -4.8181366  4.1741754  4.6560021 -0.5167334  1.5284542  8.7717049
# [7] -0.2104695  2.4273092  1.4985899  2.7356401

#$x2$lag_1
# [1]         NA -4.8181366  4.1741754  4.6560021 -0.5167334  1.5284542
# [7]  8.7717049 -0.2104695  2.4273092  1.4985899

#$x2$lag_2
# [1]         NA         NA -4.8181366  4.1741754  4.6560021 -0.5167334
# [7]  1.5284542  8.7717049 -0.2104695  2.4273092

#$x3
#$x3$lag_0
# [1] 7.712619 5.237124 5.798063 5.695696 5.127347 3.789074 5.830557
# [8] 3.801073 5.794048 5.227110

#$x3$lag_1
# [1]       NA 7.712619 5.237124 5.798063 5.695696 5.127347 3.789074
# [8] 5.830557 3.801073 5.794048

#$x3$lag_2
# [1]       NA       NA 7.712619 5.237124 5.798063 5.695696 5.127347
# [8] 3.789074 5.830557 3.801073