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

箱线图添加t检验显著性标记:启用facet_grid后失效问题咨询

分面后ggpubr显著性标记不显示的问题

这不是bug,核心原因是stat_compare_means的计算逻辑和分面的适配问题,具体分两种场景说明:

场景1:所有分面X轴分组一致(原始代码)

你原始代码中启用facet_grid(~ fct_rev(Z), scales = "free", space = "free")后,stat_compare_means默认基于整个数据集计算比较对的p值,但分面后每个子图仅显示当前Z对应的数据,且scales="free"让每个分面的x轴独立。此时只需让stat_compare_means按分面分组计算,添加group = Z参数即可:

修正后的代码:

library(ggpubr)
library(ggplot2)
library(forcats)

# 生成样本数据
set.seed(123)
data <- data.frame(
  X = rep(c("A", "B", "C"), each = 10),
  Y = rep(c("D", "E", "F"), each = 10),
  Z = rep(c("G", "H", "I"), each = 10),
  value = c(rnorm(30, mean = 5), rnorm(30, mean = 7), rnorm(30, mean = 9))
)

# 创建绘图
p <- ggplot(data, aes(x = X, y = value, group = X)) +
  geom_boxplot() +
  facet_grid(~ fct_rev(Z), scales = "free", space = "free") +
  stat_compare_means(
    method = "t.test",
    comparisons = list(c("A", "B"), c("A", "C"), c("B", "C")),
    label = "p.signif",
    size = 3,
    group = Z  # 按分面分组计算显著性
  ) +
  scale_y_continuous(expand = expansion(mult = c(0.3, 0.3)))

print(p)

添加group = Z后,stat_compare_means会在每个分面内独立计算指定比较对的显著性,标记即可正常显示。

场景2:不同分面X轴分组不一致(真实场景)

你更新后的代码存在两个关键问题:

  1. 数据生成时每个子数据集的Z重复次数错误(应为30行而非10行);
  2. comparisons中的组名与分面内的X标签不匹配(比如分面G的X是"A xx"、"B yy",但你写了c("A xx", "B"),不存在"B"这个组)。

针对这种每个分面X标签不同的场景,需为每个分面单独指定对应的比较对,推荐用循环生成子图再拼接:

修正后的代码:

library(ggpubr)
library(ggplot2)
library(purrr)
library(gridExtra)
library(forcats)

# 生成正确的样本数据
set.seed(123)
data1 <- data.frame(
  X = rep(c("A xx", "B yy", "C zz"), each = 10),
  Z = rep("G", 30),
  value = c(rnorm(10, mean = 5), rnorm(10, mean = 7), rnorm(10, mean = 9))
)

data2 <- data.frame(
  X = rep(c("A pp", "B qq", "C rr"), each = 10),
  Z = rep("H", 30),
  value = c(rnorm(10, mean = 5), rnorm(10, mean = 7), rnorm(10, mean = 9))
)

data3 <- data.frame(
  X = rep(c("A xx", "B ee", "C ff"), each = 10),
  Z = rep("I", 30),
  value = c(rnorm(10, mean = 5), rnorm(10, mean = 7), rnorm(10, mean = 9))
)

data <- rbind(data1, data2, data3)

# 为每个分面定义专属的比较对
comp_list <- list(
  G = list(c("A xx", "B yy"), c("A xx", "C zz"), c("B yy", "C zz")),
  H = list(c("A pp", "B qq"), c("A pp", "C rr"), c("B qq", "C rr")),
  I = list(c("A xx", "B ee"), c("A xx", "C ff"), c("B ee", "C ff"))
)

# 循环生成每个分面的子图
plots <- map(names(comp_list), function(z) {
  sub_data <- subset(data, Z == z)
  ggplot(sub_data, aes(x = X, y = value, group = X)) +
    geom_boxplot() +
    stat_compare_means(
      method = "t.test",
      comparisons = comp_list[[z]],
      label = "p.signif",
      size = 3
    ) +
    scale_y_continuous(expand = expansion(mult = c(0.3, 0.3))) +
    labs(title = z) +
    theme_bw()
})

# 拼接所有子图
grid.arrange(grobs = plots, nrow = 1)

总结

  • 分面后显著性标记不显示,本质是stat_compare_means的计算范围与分面分组逻辑不匹配,并非bug;
  • 同分组分面:添加group = 分面变量即可适配;
  • 异分组分面:必须为每个分面单独指定匹配的比较对,循环生成子图再拼接是最稳妥的实现方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 07:57:10