使用ggplot2为箱线图的组间比较添加显著性标记
问题:在分组箱线图中添加组内显著性标记
数据集
set.seed(123) expr_data <- data.frame( cell_line_name = rep(c("CL1", "CL2"), each = 50), GSE_id = rep(c("GSE1", "GSE2"), each = 50), model = rep(c("M1", "M2"), each = 50), expr = rnorm(100), age_group = sample(c('A', 'B'), 100, replace = TRUE) )
数据集样例:
cell_line_name GSE_id model expr age_group 1 CL1 GSE1 M1 -0.34391723 B 2 CL1 GSE1 M1 0.09049665 A 3 CL1 GSE1 M1 1.59850877 A ...
现有绘图代码
已实现基础箱线图,按拼接后的分组作为x轴,age_group区分颜色:
ggplot(expr_data, aes(x = paste0(cell_line_name, '_', GSE_id, '_', model), y = expr, color = age_group)) + geom_boxplot() + geom_point(position = position_jitterdodge(), alpha = 0.5)
遇到的问题
尝试用ggpubr::stat_compare_means添加每个x分组内A、B组的显著性标记,但未成功:
ggplot(expr_data, aes(x = paste0(cell_line_name, '_', GSE_id, '_', model), y = expr, color = age_group)) + geom_boxplot() + geom_point(position = position_jitterdodge(), alpha = 0.5) + ggpubr::stat_compare_means(comparisons = list(c("A", "B")))
解决方案
问题原因
原代码未指定group=age_group,stat_compare_means默认会按x轴的大分组进行比较,而非每个大分组内的age_group亚组;同时直接传入comparisons无法识别亚组的比较范围。
修正代码(两种方案)
方案1:使用ggpubr::stat_compare_means
先将拼接分组转为单独列,再指定分组参数实现组内比较:
library(ggplot2) library(ggpubr) # 创建合并分组列,简化x轴映射 expr_data$group <- paste0(expr_data$cell_line_name, '_', expr_data$GSE_id, '_', expr_data$model) ggplot(expr_data, aes(x = group, y = expr, color = age_group)) + geom_boxplot(position = position_dodge(width = 0.75)) + geom_point(position = position_jitterdodge(jitter.width = 0.2, dodge.width = 0.75), alpha = 0.5) + # 指定group参数,在每个x分组内比较age_group stat_compare_means( aes(group = age_group), method = "t.test", # 可根据数据选择检验方法,如wilcox.test label = "p.signif", # 显示显著性标记,而非具体p值 position = position_dodge(width = 0.75), # 与箱线图的偏移对齐 tip.length = 0.01 )
方案2:使用ggsignif::geom_signif
更灵活地指定每个x分组的比较位置:
library(ggplot2) library(ggsignif) expr_data$group <- paste0(expr_data$cell_line_name, '_', expr_data$GSE_id, '_', expr_data$model) # 获取每个x分组的最大y值,自动适配显著性标记的y位置 y_max <- tapply(expr_data$expr, expr_data$group, max) y_pos <- unname(y_max) + 0.5 ggplot(expr_data, aes(x = group, y = expr, color = age_group)) + geom_boxplot(position = position_dodge(width = 0.75)) + geom_point(position = position_jitterdodge(jitter.width = 0.2, dodge.width = 0.75), alpha = 0.5) + # 为每个x分组添加A/B组的显著性比较 geom_signif( aes(group = age_group), comparisons = list(c("A", "B")), map_signif_level = TRUE, y_position = y_pos, x_position = seq_along(unique(expr_data$group)), tip.length = 0.01 )
说明
- 需确保
position_dodge的宽度一致,保证箱线图、散点和显著性标记对齐。 - 可根据数据分布选择统计检验方法:
t.test适用于正态分布数据,wilcox.test适用于非正态分布数据。 - 若需显示具体p值,可将
map_signif_level = TRUE改为label = "p.value"。
内容的提问来源于stack exchange,提问作者zhang
相关产品推荐
相关产品推荐

