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
相关产品推荐
相关产品推荐

