如何修复sjPlot混合效应模型图的X轴范围与随机效应展示问题?
问题:修复sjPlot绘制混合效应模型图的两个问题
问题背景
用lme4的glmer拟合嵌套随机效应的二项混合模型后,使用sjPlot的plot_model绘图时遇到两个问题:
- X轴未延伸至预期的1;
- 嵌套在
File中的Person_anon随机效应未以单独细灰线展示(期望效果类似用base R循环绘制的随机效应线条)。
模型与初始绘图代码
library(lme4) library(sjPlot) m_0 <- glmer(Preselected_0 ~ Shift_Altnt_Ratio_Q + (Shift_Altnt_Ratio_Q | File / Person_anon), family = "binomial", data = df) summary(m_0) plot_model(m_0, type = "eff", terms = c("Shift_Altnt_Ratio_Q"), ci.lvl = .68, line.size = 1.2, title = "" )
期望的随机效应线条效果(base R实现)
for (i in seq(nrow(ranef(m_0)[[1]]))) { lines(seq(0, 1, 0.05), # -----> Fixed effects intercept, read off of summary plogis(-2.0987 + ranef(m_0)[[1]][i,1] + # ---------------> Fixed effects slope, read off of summary (seq(0, 1, 0.05)*(12.9791 +ranef(m_0)[[1]][i,2])) ), col=rgb(0,0,0,70,maxColorValue=255)) }
解决方案
1. 修复X轴范围问题
plot_model默认根据数据中的变量实际范围设置X轴,要强制X轴覆盖0到1,有两种方法:
方法一:在plot_model中直接指定范围
通过terms参数的[xmin:xmax]语法,强制设定X轴区间:
plot_model(m_0, type = "eff", terms = c("Shift_Altnt_Ratio_Q [0:1]"), # 强制X轴从0到1 ci.lvl = .68, line.size = 1.2, title = "")
方法二:用ggplot2扩展调整
sjPlot的绘图基于ggplot2,可将绘图结果存为对象后,用xlim()修改:
p <- plot_model(m_0, type = "eff", terms = c("Shift_Altnt_Ratio_Q"), ci.lvl = .68, line.size = 1.2, title = "") p + xlim(0, 1)
2. 添加嵌套随机效应的线条
sjPlot默认不会自动展示所有嵌套随机效应的单独线条,需手动提取参数并结合ggplot2的geom_line()添加,完整代码如下:
library(lme4) library(sjPlot) library(ggplot2) library(dplyr) # 拟合模型 m_0 <- glmer(Preselected_0 ~ Shift_Altnt_Ratio_Q + (Shift_Altnt_Ratio_Q | File / Person_anon), family = "binomial", data = df) # 生成基础效应图(同时解决X轴范围问题) p <- plot_model(m_0, type = "eff", terms = c("Shift_Altnt_Ratio_Q [0:1]"), ci.lvl = .68, line.size = 1.2, title = "") # 提取固定效应参数 fixef_vals <- fixef(m_0) int_fix <- fixef_vals[1] slope_fix <- fixef_vals[2] # 提取嵌套随机效应(File:Person_anon层面的截距和斜率) ranef_vals <- ranef(m_0)$`File:Person_anon` ranef_df <- as.data.frame(ranef_vals) %>% mutate(group_id = row.names(.)) # 生成X轴序列(与原base R循环一致) x_seq <- seq(0, 1, 0.05) # 构建随机效应预测数据框 ranef_preds <- expand.grid(x = x_seq, group_id = ranef_df$group_id) %>% left_join(ranef_df, by = "group_id") %>% mutate( # 计算线性预测值并转换为概率(plogis对应logit链接) pred_prob = plogis(int_fix + `(Intercept)` + x * (slope_fix + Shift_Altnt_Ratio_Q)) ) # 添加随机效应细灰线到基础图 p + geom_line(data = ranef_preds, aes(x = x, y = pred_prob, group = group_id), color = rgb(0,0,0,70,maxColorValue=255), linewidth = 0.5)
说明:
- 直接从模型提取固定效应,无需手动输入数值,适配性更强;
- 用
rgb(0,0,0,70,maxColorValue=255)实现原base R代码中的半透明灰色线条; linewidth = 0.5设置细线条,与期望效果一致;- 通过
expand.grid生成所有随机效应组的X序列,确保每个组都有完整线条。
内容的提问来源于stack exchange,提问作者Chris Ruehlemann
相关产品推荐
相关产品推荐

