R中多分类逻辑回归边际效应绘图的基线与刻度问题
解决方案:单独调整子图刻度
一、针对sjPlot::plot_model的处理
方法1:提取底层数据手动绘图(最灵活)
先提取plot_model的预测数据,过滤掉基线类别,再用ggplot手动绘制并设置自由y轴刻度:
# 提取预测数据(return_data=TRUE获取底层数据) pred_data <- plot_model(model_2, type = "pred", terms = "clientelism", return_data = TRUE) # 过滤掉基线类别"0",只保留3个目标类别 pred_data_filtered <- pred_data[pred_data$response.level != "0", ] # 手动绘制边际效应图,每个子图使用独立y轴刻度 library(ggplot2) ggplot(pred_data_filtered, aes(x = clientelism, y = predicted)) + geom_line(linewidth = 1) + geom_ribbon(aes(ymin = conf.low, ymax = conf.high), alpha = 0.2) + facet_wrap(~response.level, scales = "free_y") + # 每个子图y轴自由缩放 labs(x = "Clientelism", y = "Predicted Probability") + theme_bw()
如果需要手动指定第三类的刻度,比如第三类概率范围在0~0.05,可以修改scale_y_continuous:
# 假设第三类的response.level是"3" third_class_range <- range(pred_data_filtered$predicted[pred_data_filtered$response.level == "3"]) ggplot(pred_data_filtered, aes(x = clientelism, y = predicted)) + geom_line(linewidth = 1) + geom_ribbon(aes(ymin = conf.low, ymax = conf.high), alpha = 0.2) + facet_wrap(~response.level, scales = "free_y") + scale_y_continuous( breaks = function(x) { # 针对第三类手动设置刻度 if (all(x >= third_class_range[1], x <= third_class_range[2])) { seq(third_class_range[1], third_class_range[2], length.out = 4) } else { waiver() # 其他类别使用默认刻度 } } ) + labs(x = "Clientelism", y = "Predicted Probability") + theme_bw()
方法2:直接修改plot_model返回的ggplot对象
如果不想手动重绘,可直接修改plot_model的输出,开启自由y轴:
p <- plot_model(model_2, type = "pred", terms = "clientelism") + facet_wrap(~response.level, scales = "free_y") # 替换原facet设置 # 可选:过滤基线类别 p$data <- p$data[p$data$response.level != "0", ] print(p)
二、针对marginaleffects::plot_cap的处理
用ggh4x包实现更精准的子图刻度控制:
library(marginaleffects) library(ggh4x) # 用于更灵活的分面刻度设置 # 生成初始图 cap_plot <- plot_cap(model_2, condition = "clientelism", type = "probs") + facet_wrap(~group) # 提取数据,确定第三类的概率范围 cap_data <- cap_plot$data # 替换成你的第三类名称,比如"3" third_group_name <- "3" third_range <- range(cap_data$estimate[cap_data$group == third_group_name]) # 修改绘图,设置自由y轴并手动指定第三类刻度 cap_plot_final <- cap_plot + facet_wrap2(~group, scales = list(y = "free")) + # 每个子图y轴独立 scale_y_continuous( breaks = function(x) { if (all(x >= third_range[1], x <= third_range[2])) { seq(third_range[1], third_range[2], by = 0.01) # 按需求设置刻度间隔 } else { waiver() } } ) + # 可选:过滤基线类别"0" filter(!group == "0") print(cap_plot_final)
关键说明
- 开启
scales = "free_y"是核心,让每个子图的y轴自动适配自身数据范围,解决小概率类别显示平线的问题。 - 若需更精细的刻度控制,结合
ggh4x::facet_wrap2和自定义breaks函数即可实现单独调整第三类的刻度。
内容的提问来源于stack exchange,提问作者Jorissimo
相关产品推荐
相关产品推荐

