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

在分面ggplot多因子数据中添加成对t检验p值的技术问题

在嵌套分面箱线图中添加成对t检验P值

针对你嵌套分组(Compound/conc/method)的箱线图需求,以下是完整的R代码方案,用于在每个分面子组内对不同时间点做成对t检验并标注P值:

1. 加载依赖包与数据预处理

首先确保所需包已安装,然后读取并整理数据:

# 安装所需包(首次运行)
install.packages(c("tidyverse", "ggpubr", "ggsignif", "ggh4x"))

# 加载包
library(tidyverse)
library(ggpubr)
library(ggsignif)
library(ggh4x)

# 读取数据(替换为你的CSV文件路径)
df <- read.csv("your_data_file.csv") %>%
  # 转换为因子变量,保证分组顺序正确
  mutate(
    Time = factor(Time, levels = c("Day1", "Day2", "Day3")), # 按实际时间点命名调整
    SampleID = factor(SampleID), # 关键:每个样本的唯一标识,用于成对检验匹配
    Compound = factor(Compound),
    conc = factor(conc, levels = c("LOW", "HIGH_QC")),
    method = factor(method)
  )

2. 批量计算成对t检验P值

定义函数,按每个分面组(Compound/conc/method)批量计算时间点两两比较的成对t检验结果,并做多重比较校正:

compute_pairwise_p <- function(sub_data) {
  # 生成所有时间点的两两组合
  time_pairs <- combn(levels(sub_data$Time), 2, simplify = FALSE)
  
  # 遍历组合计算检验结果
  map_dfr(time_pairs, function(pair) {
    # 筛选当前时间点组合的数据,并保留有完整成对样本的记录
    filtered <- sub_data %>%
      filter(Time %in% pair) %>%
      group_by(SampleID) %>%
      filter(n() == 2) %>%
      ungroup()
    
    # 样本量不足时返回无显著性标记
    if(n_distinct(filtered$SampleID) < 3) {
      return(tibble(
        group1 = pair[1], group2 = pair[2],
        p.value = NA, p.adj = NA, label = "n.s."
      ))
    }
    
    # 执行成对t检验
    t_result <- t.test(Value ~ Time, data = filtered, paired = TRUE)
    # Bonferroni校正多重比较
    adj_p <- p.adjust(t_result$p.value, method = "bonferroni")
    
    # 生成可读性强的P值标签
    label <- case_when(
      adj_p < 0.001 ~ "***",
      adj_p < 0.01 ~ "**",
      adj_p < 0.05 ~ "*",
      TRUE ~ "n.s."
    )
    
    tibble(
      group1 = pair[1], group2 = pair[2],
      p.value = t_result$p.value, p.adj = adj_p, label = label
    )
  }) %>%
    # 添加分面分组标识,用于后续匹配绘图
    mutate(
      Compound = unique(sub_data$Compound),
      conc = unique(sub_data$conc),
      method = unique(sub_data$method)
    )
}

# 按分面分组计算所有P值
p_results <- df %>%
  group_by(Compound, conc, method) %>%
  group_modify(~compute_pairwise_p(.x)) %>%
  ungroup()

3. 绘制分面箱线图并标注P值

结合ggboxplot和geom_signif,将P值精准添加到对应分面的时间点之间:

ggboxplot(df, x = "Time", y = "Value",
          fill = "Time", palette = "jco", # 可根据需求更换配色
          outlier.shape = 1) +
  # 嵌套分面设置(与你的原始代码对齐)
  facet_grid2(Compound ~ conc + method, scales = "free_y") +
  # 添加成对检验P值
  geom_signif(
    data = p_results,
    aes(xmin = group1, xmax = group2, annotations = label, y_position = Inf),
    y_jjust = -0.1, # 调整P值在图上方的位置
    tip_length = 0.01, # 缩短显著性标记的竖线长度
    manual = TRUE # 手动指定比较对与标签
  ) +
  # 美化主题
  theme_bw() +
  theme(
    strip.background = element_rect(fill = "#f0f0f0"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    legend.position = "none"
  )

关键说明

  • 成对检验的核心:必须用SampleID确保每个样本在不同时间点的数据一一匹配,否则成对t检验结果无效。
  • 多重比较校正:这里用Bonferroni方法,你也可以替换为holm或fdr等更宽松的校正方式,修改p.adjust的method参数即可。
  • 缺失数据处理:函数中加入了样本量判断,避免因数据缺失导致的检验报错,不足3组成对样本时标记为n.s.(无显著性)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:09:53