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

如何为带多facet的ggplot2图表添加Tukey检验显著性标注

R ggplot分面图表添加Tukey检验显著性标注解决方案

方案1:字母体系显著性标注(适合多组同时比较,最常用)

首先加载所需依赖包:

library(tidyverse)
library(emmeans)
library(multcomp)
library(multcompView)

先计算每个分面、每个Location下不同Obs的Tukey检验结果,同时计算标注的摆放位置:

# 按分面变量variable、x轴变量Location分组,单独做统计检验
stat_res <- long %>%
  group_by(variable, Location) %>%
  nest() %>%
  mutate(
    # 拟合ANOVA模型
    aov_mod = map(data, ~aov(value ~ Obs, data = .x)),
    # 做Tukey事后检验
    tukey = map(aov_mod, ~emmeans(.x, pairwise ~ Obs, adjust = "tukey")),
    # 提取显著性字母
    letters = map(tukey, ~multcomp::cld(.x$emmeans, Letters = letters, alpha = 0.05) %>% as.data.frame()),
    # 计算每个分组的最大值,标注放在最大值上方10%的位置避免遮挡
    max_val = map(data, ~max(.x$value)*1.1)
  ) %>%
  unnest(c(letters, max_val)) %>%
  # 对齐分组名称,和绘图数据保持一致
  rename(Obs = 3) %>%
  mutate(Obs = str_trim(Obs))

把标注层加到原来的ggplot代码里即可:

p + 
  geom_text(data = stat_res, 
            aes(x = Location, y = max_val, label = .group, color = Obs),
            position = position_dodge2(width = 1, preserve = "single"),
            show.legend = F, size = 3.5)

如果需要调整标注的位置,修改max_val的计算系数即可,比如要更高就改成max(.x$value)*1.15。

方案2:星号显著性标注(适合指定两两比较)

之前用geom_signif()失败大概率是没有匹配分组的dodge位置,你需要手动指定每个比较的位置,示例代码如下:
首先定义你需要比较的组对,示例如下:

# 先定义比较组,这里以每个Location下Sun和Rain比较、Rain和Cloud比较为例
comp_list <- list(
  c("Sun", "Rain"),
  c("Rain", "Cloud")
)

p +
  ggsignif::geom_signif(
    aes(group = Obs),
    comparisons = comp_list,
    step_increase = 0.1,
    position = position_dodge(width = 0.75),
    test = "tukey",
    tip_length = 0,
    map_signif_level = T # 自动把p值转成星号
  )

如果需要适配分面,你可以构建一个包含分面变量、比较组、标注位置的标注数据框,传入geom_signif()的data参数即可。

注意:示例代码中的示例数据是随机生成的,你运行时得到的显著性结果可能和示例不同,属于正常情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:45:04