You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R中合并多次lm回归训练输出至单个数据框的技术问询

我完全懂你要做的事——重复上千次拆分数据集训练线性模型,然后把所有结果规整到数据框里做后续分析,这在做模型稳定性验证或者蒙特卡洛模拟的时候太常用了!下面我用mtcars数据集给你写个完整的示例,一步步帮你实现需求:

方法一:Base R 原生实现

如果习惯用Base R的话,我们可以用循环来完成重复抽样、建模和结果存储:

# 设置核心参数
n_repeats <- 1000  # 重复次数
train_prop <- 0.63 # 训练集比例
data <- mtcars     # 示例数据集

# 初始化存储结果的结构
# 1. 存储系数:每行对应一次重复,每列对应一个模型变量
coef_matrix <- matrix(NA, nrow = n_repeats, ncol = length(coef(lm(mpg ~ ., data = data))))
colnames(coef_matrix) <- names(coef(lm(mpg ~ ., data = data)))

# 2. 存储R²:每个元素对应一次重复的R²值
r_squared_vec <- numeric(n_repeats)

# 3. 存储拟合值:用列表存储每次重复的拟合值(因为每次训练集大小可能略有差异)
fit_values_list <- vector("list", n_repeats)

# 开始循环执行
for (i in 1:n_repeats) {
  # 随机拆分训练集索引
  train_indices <- sample(nrow(data), size = floor(train_prop * nrow(data)))
  train_data <- data[train_indices, ]
  
  # 训练线性模型(这里以mpg为因变量,其他所有变量为自变量,你可以根据需求修改公式)
  fit <- lm(mpg ~ ., data = train_data)
  
  # 提取并存储系数
  coef_matrix[i, ] <- coef(fit)
  
  # 提取并存储R²
  r_squared_vec[i] <- summary(fit)$r.squared
  
  # 提取并存储拟合值,同时标记重复ID和原数据行号
  fit_values_list[[i]] <- data.frame(
    repeat_id = i,
    original_row = train_indices,
    fitted_value = predict(fit)
  )
}

# 把结果转成整洁的数据框
# 系数+R²的汇总表
model_summary_df <- cbind(as.data.frame(coef_matrix), 
                          repeat_id = 1:n_repeats,
                          r_squared = r_squared_vec)

# 拟合值的合并表
fitted_values_df <- do.call(rbind, fit_values_list)

方法二:Tidyverse + Broom 更简洁的实现

如果你熟悉tidyverse生态,用purrr做批量处理、broom整理模型结果会更高效,代码可读性也更强:

library(tidyverse)
library(broom)

# 设置参数
n_repeats <- 1000
train_prop <- 0.63
data <- mtcars

# 生成1000次抽样的索引列表
sample_indices <- map(1:n_repeats, ~sample(nrow(data), floor(train_prop * nrow(data))))

# 批量处理:抽样→建模→提取结果
results <- map2_dfr(1:n_repeats, sample_indices, function(repeat_id, indices) {
  train_data <- data[indices, ]
  fit <- lm(mpg ~ ., data = train_data)
  
  # 提取系数(转成宽格式)
  coef_df <- tidy(fit) %>%
    pivot_wider(names_from = term, values_from = estimate) %>%
    mutate(repeat_id = repeat_id)
  
  # 提取模型整体指标(包括R²)
  model_metrics <- glance(fit) %>%
    select(r.squared, adj.r.squared) %>%
    mutate(repeat_id = repeat_id)
  
  # 提取拟合值
  fitted_df <- augment(fit) %>%
    mutate(repeat_id = repeat_id, original_row = indices) %>%
    select(repeat_id, original_row, fitted_value = .fitted)
  
  # 返回三个结果部分,方便后续拆分
  list(
    model_summary = left_join(coef_df, model_metrics, by = "repeat_id"),
    fitted_values = fitted_df
  )
})

# 拆分出最终的数据框
model_summary_df <- results %>% pluck("model_summary") %>% bind_rows()
fitted_values_df <- results %>% pluck("fitted_values") %>% bind_rows()

一些注意事项

  • 如果你需要的是测试集的预测值,只需要把predict(fit)改成predict(fit, newdata = data[-indices, ]),同时存储测试集的行号即可。
  • 对于你的1000条观测的数据集,1000次循环生成的拟合值数据框会有大约63万行,这在R里完全可以轻松处理,不用担心内存问题。
  • 两种方法的核心逻辑都是给每个重复的结果打上唯一ID,这样后续合并、分析时能准确对应每次建模的结果。

内容的提问来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:54:47