多重插补数据集下lmer模型生成池化边际效应的问题
问题原因
该问题是两个特性叠加导致的:
ggeffect()和ggpredict()底层逻辑和返回结构不同:ggpredict()是ggeffects包原生开发的预测函数,对所有适配模型类返回的结果都遵循统一的结构标准,内置了预测值、标准误、自由度等池化必需的元数据;而ggeffect()是对effects包Effect()函数的封装,返回的ggeffect类对象结构会随模型类变化,针对lmer返回的混合模型结果,缺少pool_predictions()要求的标准化属性。- 混合模型的
ggeffect()边际效应结果,默认没有携带多重插补池化所需的变异估计相关字段,和lm类的ggeffect结果结构不一致,导致池化函数无法正常读取计算所需的数值。
解决方法
有两种可行方案可以获得lmer模型的池化边际效应:
方案1:用ggpredict()指定参数模拟边际效应(优先推荐)
你需要的均值±1标准差的边际效应,本质是计算固定效应时纳入随机效应方差的估计结果,直接用ggpredict()时指定type = "re"(即包含随机效应的变异),返回结果可以直接用pool_predictions()池化,同时可以通过terms参数直接指定目标变量的取值为均值±1标准差,和你使用ggeffect()的需求完全匹配:
predictions_fix <- lapply(1:5, function(i) { m4 <- lmer(bmi ~ age + chl + (1|hyp), data = complete(imp, action = i)) # terms参数中[meansd]指定返回目标变量均值、+1SD、-1SD对应的结果 ggpredict(m4, terms = "age [meansd]", type = "re") }) pool_predictions(predictions_fix)
该方案得到的结果和ggeffect()返回的边际效应几乎一致,且完全兼容现有池化逻辑,不需要额外手动处理。
方案2:手动提取ggeffect结果完成池化
如果你必须使用ggeffect()的计算逻辑,可以手动从每个插补数据集的ggeffect结果中提取预测值和标准误,用mice包的pool.scalar()函数遵循鲁宾规则手动完成池化:
# 提取每个插补的ggeffect结果 pred_list <- lapply(1:5, function(i) { m4 <- lmer(bmi ~ age + chl + (1|hyp), data = complete(imp, action = i)) eff <- ggeffect(m4, "age") return(data.frame( x = eff$x, predicted = eff$predicted, std.error = eff$std.error )) }) # 按效应分组分别池化 unique_x <- unique(pred_list[[1]]$x) pooled_res <- lapply(unique_x, function(x_val) { q <- sapply(pred_list, function(d) d$predicted[d$x == x_val]) u <- sapply(pred_list, function(d) d$std.error[d$x == x_val]^2) pool_out <- pool.scalar(q, u, n = nrow(complete(imp, 1))) return(data.frame( x = x_val, predicted = pool_out$qbar, std.error = sqrt(pool_out$t), conf.low = pool_out$qbar - 1.96 * sqrt(pool_out$t), conf.high = pool_out$qbar + 1.96 * sqrt(pool_out$t) )) }) pooled_res <- do.call(rbind, pooled_res)
得到的pooled_res就是池化后的边际效应结果,可以直接用于后续绘图。
内容的提问来源于stack exchange,提问作者riepenha
相关产品推荐
相关产品推荐

