如何不使用ggeffects预测值,用ggplot复现回归预测可视化图?
解决marginaleffects与ggeffects预测值不一致的问题,并用ggplot复现目标图
核心问题原因
ggeffects的predict_response默认会生成参考预测网格:对指定的连续变量生成均匀序列点,分类变量取所有水平,其余协变量固定为均值(连续)或参考类别(分类);而marginaleffects的predictions默认使用原始数据集的全部观测,导致预测值分布与ggeffects不同。只需手动生成与ggeffects一致的预测网格即可解决。
完整代码流程
1. 加载包与数据处理
library(ggeffects) library(tidyverse) library(marginaleffects) # 导入并清洗efc数据集 data(efc) efc_clean <- efc %>% mutate( c161sex = factor(c161sex, levels = c(1, 2), labels = c("Male", "Female")), c172code = factor(c172code, levels = c(1, 2, 3), labels = c("Low", "Medium", "High")) ) %>% drop_na(c12hour, c161sex, c172code)
2. 拟合交互项模型
假设因变量为照顾者年龄(e17age),模型包含c12hour、c161sex、c172code的三向交互:
mod <- lm(e17age ~ c12hour * c161sex * c172code, data = efc_clean)
3. 用ggeffects生成目标预测值与图(作为参照)
# 获取目标预测数据 mydf_ggeffects <- predict_response(mod, terms = c("c12hour", "c161sex", "c172code")) # 绘制目标图 plot(mydf_ggeffects)
4. 用marginaleffects生成一致的预测值
# 生成与ggeffects匹配的预测网格:c12hour取10个均匀点,分类变量取所有水平,其余协变量取均值/参考类别 pred_grid <- datagrid( model = mod, c12hour = seq(min(efc_clean$c12hour), max(efc_clean$c12hour), length.out = 10), c161sex = unique(efc_clean$c161sex), c172code = unique(efc_clean$c172code), newdata = efc_clean ) # 获取标准化预测值 mydf_marginaleffects <- predictions(mod, newdata = pred_grid) %>% select(c12hour, c161sex, c172code, predicted, conf.low, conf.high)
5. 用ggplot复现目标图
ggplot(mydf_marginaleffects, aes(x = c12hour, y = predicted)) + # 绘制回归线与置信区间 geom_line(aes(color = c161sex, linetype = c172code), linewidth = 1) + geom_ribbon(aes(ymin = conf.low, ymax = conf.high, fill = c161sex), alpha = 0.2, color = NA) + # 设置标签与主题 labs( x = "Weekly Care Hours", y = "Predicted Caregiver Age", color = "Gender", linetype = "Care Level", fill = "Gender" ) + theme_minimal()
关键调整点
- 必须用
datagrid定义预测网格,确保与ggeffects的变量取值逻辑一致 - 连续变量
c12hour的序列长度(默认10个点)要与ggeffects匹配 - 分类变量需包含所有水平,其余协变量由
datagrid自动处理为均值/参考类别
内容的提问来源于stack exchange,提问作者mariann
相关产品推荐
相关产品推荐

