澄清问题
请阅读r 标记页面顶部的信息,特别是示例应该是独立的、完整的,包括所有输入和库语句、可重现以便其他任何人都可以轻松地运行它们并且最小化。
- 缺少库语句。 R 中没有
lead 函数,因此我们假设正在使用 dplyr。
- 数据框本身缺失,因此我们根据 R 中包含的 BOD 数据框构建示例数据框。
- 为了使这个最小化,我们使用 2 个滞后和 2 个超前,而不是 12 和 12。
以上是在下面的替代部分中完成的。
代码问题
问题中的代码的问题在于它会复制列表的每个组件,修改副本但不更改列表本身。如果我们像这样将修改后的数据框重新插入到列表中,它将起作用。 ## 结尾的行来自问题,其他行是新的或修改的。
dataframes = list(df1,df2,df3,df4) ##
for (i in seq_along(dataframes)) {
df <- dataframes[[i]]
df[paste0("lag", 1:12)] = lapply(1:12, lag, x=df[,2]) ##
df[paste0("lead", 1:12)] = lapply(1:12, lead, x=df[,2]) ##
dataframes[[i]] <- df
}
替代方案
1) 定义一些测试数据,然后使用 mget 创建一个数据帧的命名列表 L,然后遍历名称,在 L 中创建新数据帧,覆盖 L 中的旧数据帧。
虽然不推荐,除非有充分的理由这样做,我们可以使用 listenv(L, .GlobalEnv) 将 L 中的数据帧写回全局环境。
library(dplyr)
# test data
for(i in 1:4) assign(paste0("df", i), i * BOD)
nms <- paste0("df", 1:4)
L <- mget(nms)
for (nm in names(L)) {
L[[nm]][paste0("lag", 1:2)] = lapply(1:2, lag, x=L[[nm]][,2])
L[[nm]][paste0("lead", 1:2)] = lapply(1:2, lead, x=L[[nm]][,2])
}
给予:
str(L)
## List of 4
## $ df1:'data.frame': 6 obs. of 6 variables:
## ..$ Time : num [1:6] 1 2 3 4 5 7
## ..$ demand: num [1:6] 8.3 10.3 19 16 15.6 19.8
## ..$ lag1 : num [1:6] NA 8.3 10.3 19 16 15.6
## ..$ lag2 : num [1:6] NA NA 8.3 10.3 19 16
## ..$ lead1 : num [1:6] 10.3 19 16 15.6 19.8 NA
## ..$ lead2 : num [1:6] 19 16 15.6 19.8 NA NA
## $ df2:'data.frame': 6 obs. of 6 variables:
## ...snip...
2) 我们可以在折叠包中使用flag 来简化此操作。它接受一个领先/落后的向量。创建测试数据后,只需一行代码。它创建一个新列表 L2。原始列表 L 没有被修改。
library(collapse)
# test data
for(i in 1:4) assign(paste0("df", i), i * BOD)
nms <- paste0("df", 1:4)
L <- mget(nms)
L2 <- lapply(L, function(x) cbind(x[1], flag(x[2], seq(-2, 2))))
str(L2)
## List of 4
## $ df1:'data.frame': 6 obs. of 6 variables:
## ..$ Time : num [1:6] 1 2 3 4 5 7
## ..$ F2.demand: num [1:6] 19 16 15.6 19.8 NA NA
## ..$ F1.demand: num [1:6] 10.3 19 16 15.6 19.8 NA
## ..$ demand : num [1:6] 8.3 10.3 19 16 15.6 19.8
## ..$ L1.demand: num [1:6] NA 8.3 10.3 19 16 15.6
## ..$ L2.demand: num [1:6] NA NA 8.3 10.3 19 16
## $ df2:'data.frame': 6 obs. of 6 variables:
## ...snip...