R语言三层循环存储回归模型结果至列表的错误分析与修正
多轮回归迭代中三层循环存储重复结果的原因与修正方法
我在R中执行多轮面板回归迭代,需要调整两个参数:i(取值为1、3、5)和k(取值为"time"、"twoways"),计划将6组参数组合对应的模型结果存入列表。但原三层循环代码运行后,列表的每个元素都存储了相同的结果。我已经掌握了使用外部索引的解决方案,现在需要明确原三层循环的问题根源,并获取保留三层循环结构的代码修正方法。
原三层循环代码
library("plm") set.seed(123) ## 生成随机数据集 n <- 100 y <- rnorm(n, mean = 0, sd = 1) x1 <- rnorm(n, mean = 5, sd = 2) x2 <- rnorm(n, mean = -2, sd = 3) x3 <- rnorm(n, mean = 1, sd = 0.5) df <- data.frame(y, x1 ,x2 ,x3) id_values <- 1:4 time_values <- 1999:2002 combinations <- expand.grid(ID = id_values, TIME = time_values) panel_data <- merge(combinations, df, by = c("ID", "TIME"), all.x = TRUE) panel_data[is.na(panel_data)] <- 0 ## 回归模型部分 model <- vector('list', length = 6) for (j in c(1:6)) { for (i in c(1,3,5)) { for (k in c("time", "twoways")) { model[[j]] <- plm(log(y) ~ lag(log(x1),i) + lag(log(x2),i) + lag(log(x3),i), model = "within", effect = k, data = panel_data) print(" +++***+++***+++***+++***+++***+++***+++ ") print(c("滞后阶数", i)) print(summary(model[[j]], vcov.=vcovSSC(model[[j]]))) } } }
注:原代码中log(x)为笔误,已修正为log(x1)
原三层循环的问题根源
原代码的核心问题是最外层j循环与内层i、k循环完全独立:
- 每一次
j循环时,内层的i会遍历1、3、5,k会遍历"time"、"twoways",即内层会完整执行6次模型拟合; - 但
model[[j]]会被内层循环的每一次迭代覆盖,最终model[[j]]只保留了内层循环最后一次的结果(即i=5、k="twoways"的模型); - 当
j从1到6循环结束后,列表的6个元素全部被最后一次内层迭代的结果覆盖,因此所有元素内容完全相同。
保留三层循环结构的修正代码
要保留三层循环结构,需要让j的索引与i、k的组合一一绑定,不能让j独立循环。我们可以先生成所有i和k的参数组合,再用j遍历组合列表,每次取出对应参数执行模型:
library("plm") set.seed(123) ## 生成随机数据集 n <- 100 y <- rnorm(n, mean = 0, sd = 1) x1 <- rnorm(n, mean = 5, sd = 2) x2 <- rnorm(n, mean = -2, sd = 3) x3 <- rnorm(n, mean = 1, sd = 0.5) df <- data.frame(y, x1 ,x2 ,x3) id_values <- 1:4 time_values <- 1999:2002 combinations <- expand.grid(ID = id_values, TIME = time_values) panel_data <- merge(combinations, df, by = c("ID", "TIME"), all.x = TRUE) panel_data[is.na(panel_data)] <- 0 ## 生成所有i和k的参数组合 param_combinations <- expand.grid(i = c(1,3,5), k = c("time", "twoways")) model <- vector('list', length = nrow(param_combinations)) ## 保留三层循环结构的修正代码 for (j in 1:nrow(param_combinations)) { # 取出当前j对应的i和k值 current_i <- param_combinations$i[j] current_k <- param_combinations$k[j] # 内层循环保留结构,仅遍历当前j对应的单个参数值 for (i in current_i) { for (k in current_k) { model[[j]] <- plm(log(y) ~ lag(log(x1),i) + lag(log(x2),i) + lag(log(x3),i), model = "within", effect = k, data = panel_data) print(" +++***+++***+++***+++***+++***+++***+++ ") print(c("滞后阶数", i)) print(summary(model[[j]], vcov.=vcovSSC(model[[j]]))) } } }
说明:这里的内层i和k循环仅遍历当前j对应的单个参数值,既保留了三层循环的结构,又保证每个j对应唯一的i、k组合,不会出现结果覆盖问题。
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

