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

如何在R的分组ggplot图上添加配对t检验的p值

针对分组配对t检验并添加p值到箱线图的实现方案

示例数据

fish_IDcolorinsttime
1blueinst_0136
1greeninst_040
1redinst_0111
1yellowinst_020
1blueinst_3112
1greeninst_313
1redinst_315
1yellowinst_390
2blueinst_0110
2greeninst_080
2redinst_011
2yellowinst_034
2blueinst_319
2greeninst_3130
2redinst_315
2yellowinst_388

问题背景

我拥有大量上述格式的fish_ID数据,需要针对每种颜色组,对inst_0和inst_3的time均值做配对t检验。已用以下代码绘制分组箱线图:

library(ggplot2)
library(ggprism)

ggplot(mydata , aes(x = factor(inst), y = time, fill = color)) +
 geom_boxplot(position = position_dodge(width = 0.75)) +
 scale_fill_manual(values = c("blue" = "blue", "green" = "green", "red" = "red", "yellow" = 
 "yellow")) +
 theme_prism()

现在需要将各颜色组的配对t检验p值添加到图中,不清楚如何针对每个颜色组完成inst_0与inst_3的两两比较。


实现方案

步骤1:计算各颜色组的配对t检验p值

先将数据转换为宽格式,确保同一fish_ID+color组合下同时存在inst_0和inst_3的观测,再按颜色分组执行配对t检验:

library(dplyr)
library(tidyr)

# 转换为宽格式,保留配对数据
wide_data <- mydata %>%
  pivot_wider(names_from = inst, values_from = time) %>%
  na.omit()  # 移除缺失配对的样本

# 按颜色分组计算配对t检验p值,并格式化标签
p_values <- wide_data %>%
  group_by(color) %>%
  summarize(
    p_val = t.test(inst_0, inst_3, paired = TRUE)$p.value,
    # 生成可读性强的p值标签,支持星号或数值显示
    p_label = case_when(
      p_val < 0.001 ~ "***",
      p_val < 0.01 ~ "**",
      p_val < 0.05 ~ "*",
      TRUE ~ "ns"
      # 若需要显示具体数值,替换为:sprintf("p = %.3f", p_val)
    )
  )

步骤2:将p值添加到箱线图中

推荐使用ggsignif包手动指定比较位置,或用ggpubr包自动适配分组布局:

方法1:用ggsignif手动控制标记位置

install.packages("ggsignif")
library(ggsignif)

# 定义每个颜色组的配对比较位置(适配position_dodge(width=0.75)的布局)
color_x_pos <- c(blue = 0.8, green = 0.95, red = 1.1, yellow = 1.25)
y_offset <- max(mydata$time) + c(10, 15, 20, 25)  # 避免标记与箱线图重叠

ggplot(mydata, aes(x = factor(inst), y = time, fill = color)) +
  geom_boxplot(position = position_dodge(width = 0.75)) +
  scale_fill_manual(values = c("blue" = "blue", "green" = "green", "red" = "red", "yellow" = "yellow")) +
  theme_prism() +
  # 添加配对t检验p值标记
  geom_signif(
    data = p_values,
    aes(
      xmin = color_x_pos, 
      xmax = color_x_pos + 1, 
      annotations = p_label, 
      y_position = y_offset
    ),
    manual = TRUE,
    tip_length = 0.01,
    textsize = 4
  )

方法2:用ggpubr自动适配分组

install.packages("ggpubr")
library(ggpubr)

ggplot(mydata, aes(x = factor(inst), y = time, fill = color)) +
  geom_boxplot(position = position_dodge(width = 0.75)) +
  scale_fill_manual(values = c("blue" = "blue", "green" = "green", "red" = "red", "yellow" = "yellow")) +
  theme_prism() +
  stat_compare_means(
    aes(group = color),
    method = "t.test",
    paired = TRUE,
    label = "p.signif",  # 显示星号,若要数值用"p.format"
    position = position_dodge(width = 0.75),
    hide.ns = TRUE  # 可选:隐藏无显著性的标记
  )

注意事项

  • 确保数据为配对设计:每个fish_ID在同一color下同时有inst_0和inst_3的观测,否则配对t检验不适用。
  • 可根据图的高度调整y_offset参数,避免p值标记与箱线图或异常值重叠。
  • 若需要校正多重比较,可在计算p值时添加p.adjust()函数,比如p_val = p.adjust(t.test(inst_0, inst_3, paired = TRUE)$p.value, method = "bonferroni")。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 18:35:21