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

如何在R中实现带Bonferroni校正p值的分组多元线性回归?

分组回归与Bonferroni校正p值实现方案

问题描述

用户提供样本数据:

dad <- data.frame(type = c("new", "new", "old", "new", "old", "new", "old", "old", "new", "new"),
                   outcome = c(68,76,57,67,89,98,99,120,99,67),
                  loan1=c(98000 ,56668,67000,87999,87945, 89768, 65738, 87547, 78937, 20000),
                  loan2 =c(56768,45679, 23453, 87673, 56749, 45783, 67836, 54673, 45379, 78483),
                  house=c("semi", "detached", "town", "semi", "town", "town", "semi", "detached", "semi", "town"))

需求:针对每种house类型分别运行多元线性回归模型(实际场景为7组,初始自变量相同,通过向后逐步选择得到最终模型),对所有模型的p值进行Bonferroni校正,询问现有代码是否能实现,以及正确的实现方法。

用户现有示例代码:

#Example 
full <- lm(outcome ~loan1+loan2,data = subset(dad, house=="semi"))
summary(full)
tab_model(full)

解决方案

你提供的现有代码只能单独运行某一组的回归、查看未校正的结果,无法直接获取Bonferroni校正后的p值。下面是完整的实现步骤:

1. 分组运行向后逐步回归模型

先按house分组,对每组数据运行向后逐步选择的回归模型:

# 加载必要包
library(MASS)
library(broom)

# 按house分组,批量运行向后逐步回归
group_models <- lapply(split(dad, dad$house), function(df) {
  # 初始全模型
  full_model <- lm(outcome ~ loan1 + loan2, data = df)
  # 向后逐步选择(trace=FALSE关闭过程输出)
  step_model <- stepAIC(full_model, direction = "backward", trace = FALSE)
  return(step_model)
})

2. 提取所有原始p值

从每个模型中提取自变量的p值,统一收集:

# 提取所有模型的自变量p值(排除截距项)
all_pvals <- lapply(group_models, function(model) {
  tidy(model) %>% 
    filter(term != "(Intercept)") %>% 
    pull(p.value)
})

# 将所有p值合并为一个向量,用于后续校正
flat_pvals <- unlist(all_pvals)

3. 执行Bonferroni校正

Bonferroni校正的核心是将原始p值乘以总检验次数(即所有模型中自变量的总数):

# 计算总检验次数
total_tests <- length(flat_pvals)
# 执行Bonferroni校正
corrected_pvals <- p.adjust(flat_pvals, method = "bonferroni")

4. 整合校正结果并展示

将校正后的p值对应回原模型的自变量,生成结构化结果:

# 把校正p值匹配到对应模型的自变量上
result_list <- mapply(function(model, p_corr) {
  tidy(model) %>% 
    filter(term != "(Intercept)") %>% 
    mutate(corrected_p.value = p_corr) %>% 
    select(term, estimate, std.error, statistic, p.value, corrected_p.value)
}, group_models, split(corrected_pvals, rep(names(group_models), sapply(all_pvals, length))), SIMPLIFY = FALSE)

# 查看任意组的结果,比如semi组
print(result_list[["semi"]])

5. 用tab_model展示校正结果(可选)

如果想用tab_model展示带校正p值的结果,可手动添加校正列后输出:

library(sjPlot)

# 给每个模型添加校正p值属性
for(i in seq_along(group_models)) {
  model <- group_models[[i]]
  corr_p <- corrected_pvals[grepl(names(group_models)[i], names(corrected_pvals))]
  attr(model, "corrected_p") <- corr_p
}

# 自定义输出,包含校正p值
tab_model(group_models, 
          show.p = TRUE,
          show.stat = TRUE,
          add.lines = list(
            "校正p值" = sapply(group_models, function(x) paste(round(attr(x, "corrected_p"), 4), collapse = "; "))
          ))

关键说明

  • Bonferroni校正的检验次数是所有模型中需要检验的自变量总数,不是模型的组数。比如你有7个模型,每个最终保留2个自变量,总检验次数就是14次。
  • 如果每组逐步回归保留的自变量数量不同,上述代码会自动适配,无需手动调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 10:13:06