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

如何修复sjPlot混合效应模型图的X轴范围与随机效应展示问题?

问题:修复sjPlot绘制混合效应模型图的两个问题

问题背景

用lme4的glmer拟合嵌套随机效应的二项混合模型后,使用sjPlot的plot_model绘图时遇到两个问题:

  1. X轴未延伸至预期的1;
  2. 嵌套在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),
        # -----&gt; Fixed effects intercept, read off of summary
        plogis(-2.0987 + ranef(m_0)[[1]][i,1] + 
                 # ---------------&gt; 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 16:26:10