回归公式两种指定方式结果差异原因及循环实现咨询
动态生成公式在mice+geeglm中结果不一致的问题及循环实现方案
问题核心
在处理多重插补后的重复测量数据时,直接编写回归公式(Cal ~ a)与通过as.formula动态生成公式调用geeglm,得到的回归结果不一致,即使公式文本完全相同。
原因分析
问题出在公式的环境作用域:
- 当在
with(imputed_data, ...)外部生成formula对象时,该公式的绑定环境是全局环境(.GlobalEnv)。调用geeglm时,会优先在全局环境中查找变量,而非imputed_data内部的插补数据集,导致实际使用的是原始含缺失值的数据,而非插补后的数据。 - 直接在
with内部编写公式时,公式的绑定环境是imputed_data的内部环境,能正确引用插补后的完整数据集,因此结果正确。
解决方法
方法1:在with内部动态生成公式
将公式生成逻辑放在with的代码块中,确保公式的环境与插补数据一致:
var <- "a" rg2 <- with(imputed_data, { formula <- as.formula(paste0("Cal ~ ", var)) geeglm(formula, family = binomial, id = d, corstr = "independence") }) summary(rg2)
方法2:使用reformulate简化公式生成
reformulate可以直接在with内部生成目标公式,代码更简洁:
var <- "a" rg2 <- with(imputed_data, geeglm( reformulate(var, response = "Cal"), family = binomial, id = d, corstr = "independence" )) summary(rg2)
循环封装回归的经验
1. 批量处理自变量
定义自变量列表,用lapply实现批量回归(比for循环更简洁,自动存储结果):
# 定义需要循环的自变量 indep_vars <- c("a", "b", "c") # 批量执行回归并存储结果 reg_list <- lapply(indep_vars, function(var) { with(imputed_data, geeglm( reformulate(var, response = "Cal"), family = binomial, id = d, corstr = "independence" )) }) # 为结果列表命名,方便后续索引 names(reg_list) <- indep_vars
2. 批量提取结果
使用broom包的tidy函数可以快速提取所有回归的系数、p值等统计量,便于汇总分析:
library(broom) # 提取每个回归的汇总结果 reg_tables <- lapply(reg_list, tidy, conf.int = TRUE) # 合并为数据框 library(dplyr) bind_rows(reg_tables, .id = "predictor")
3. 扩展到多因变量
如果需要处理多个因变量,可以嵌套循环:
dep_vars <- c("Cal", "另一个因变量") indep_vars <- c("a", "b", "c") # 双重循环处理所有组合 full_reg_list <- lapply(dep_vars, function(dep) { lapply(indep_vars, function(indep) { with(imputed_data, geeglm( reformulate(indep, response = dep), family = binomial, id = d, corstr = "independence" )) }) }) names(full_reg_list) <- dep_vars
内容的提问来源于stack exchange,提问作者Luo Z
相关产品推荐
相关产品推荐

