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

R语言ggpubr:为分面分组图添加组内均值水平线及仅显示显著组间比较

用ggpubr搞定分面箱线图的两个需求

嘿,刚好我对ggpubr处理这类分面图的需求很熟悉,这就给你一步步解决这两个问题!我会用mtcars数据集做示例,方便你直接复刻测试。

1. 给每个分面添加专属的均值水平线

要实现每个分面有自己的均值线,核心思路是先计算每个分面分组下的均值,再把这些均值数据映射到绘图里:

首先加载需要的包,准备并处理数据:

library(ggpubr)
library(dplyr)

# 把分类变量转成因子,方便绘图分组
df <- mtcars %>%
  mutate(cyl = factor(cyl), gear = factor(gear))

# 计算每个分面(cyl分组)的整体均值
mean_df <- df %>%
  group_by(cyl) %>%
  summarise(mean_val = mean(mpg))

然后绘制箱线图并添加均值线:

ggboxplot(df, x = "gear", y = "mpg", facet.by = "cyl", palette = "jco") +
  # 用geom_hline添加均值线,指定每个分面对应的均值
  geom_hline(data = mean_df, aes(yintercept = mean_val), 
             linetype = "dashed", color = "darkred", linewidth = 0.8)

这样每个分面就会出现一条对应该分组整体均值的红色虚线啦。如果你的需求是每个分面内每个子组的均值线,只需要把group_by(cyl)改成group_by(cyl, gear),再调整geom_hline的映射逻辑即可。

2. 仅在分面内绘制显著的组间比较

这里有个超实用的参数可以直接解决问题:hide.ns = TRUE,它会自动隐藏非显著的比较结果,只保留显著的。当然你也可以提前筛选显著比较对,不过前者更高效:

方法1:自动隐藏非显著结果(推荐)

直接在stat_compare_means()里设置hide.ns = TRUE,同时指定要比较的组对:

ggboxplot(df, x = "gear", y = "mpg", facet.by = "cyl", palette = "jco") +
  stat_compare_means(
    comparisons = list(c("3","4"), c("3","5"), c("4","5")), # 指定所有要比较的组对
    method = "wilcox.test", # 根据你的数据选择检验方法,比如t.test
    hide.ns = TRUE, # 隐藏非显著结果
    label = "p.signif", # 显示显著性标记(*、**等),也可以选"p.format"显示具体p值
    color = "darkblue"
  )

方法2:手动筛选显著比较对(灵活定制)

如果需要更精细的控制(比如只保留p<0.01的结果),可以先做统计检验筛选出显著对,再传给绘图函数:

# 对每个分面做组间检验,筛选p<0.05的显著结果
stats_df <- df %>%
  group_by(cyl) %>%
  do(compare_means(mpg ~ gear, data = ., method = "wilcox.test")) %>%
  filter(p.value < 0.05) # 自定义显著性阈值

# 提取每个分面的显著比较对
comparison_list <- stats_df %>%
  group_split(cyl) %>%
  purrr::map(~ list(.$group1, .$group2) %>% purrr::transpose())

# 逐个绘制分面图再拼接(需要用到patchwork包)
library(patchwork)
plots <- purrr::map2(unique(df$cyl), comparison_list, function(cyl_val, comps) {
  ggboxplot(df %>% filter(cyl == cyl_val), x = "gear", y = "mpg", palette = "jco") +
    stat_compare_means(comparisons = comps, method = "wilcox.test", label = "p.signif") +
    facet_wrap(~cyl)
})
reduce(plots, `+`)

两个需求结合的完整代码

把上面两部分整合起来,就能得到同时带专属均值线和仅显示显著比较的分面箱线图:

library(ggpubr)
library(dplyr)

df <- mtcars %>%
  mutate(cyl = factor(cyl), gear = factor(gear))

mean_df <- df %>%
  group_by(cyl) %>%
  summarise(mean_val = mean(mpg))

ggboxplot(df, x = "gear", y = "mpg", facet.by = "cyl", palette = "jco") +
  geom_hline(data = mean_df, aes(yintercept = mean_val), 
             linetype = "dashed", color = "darkred", linewidth = 0.8) +
  stat_compare_means(
    comparisons = list(c("3","4"), c("3","5"), c("4","5")),
    method = "wilcox.test",
    hide.ns = TRUE,
    label = "p.signif",
    color = "darkblue"
  )

内容的提问来源于stack exchange,提问作者maycca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:54:14