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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 09:30:56