如何在箱线图中展示TukeyHSD输出的p adj值而非t检验p值?
在箱线图上展示TukeyHSD调整后p值的方法
针对你要展示Fair切工与其他四类切工的Tukey事后检验调整p值的需求,直接用stat_compare_means确实无法实现,得先提取TukeyHSD的结果,再手动添加到图上。下面是完整的代码流程,用R自带的diamonds数据集演示:
1. 加载包并整理数据
先安装/加载需要的工具包,再筛选出目标切工类别:
# 首次使用请安装包 install.packages(c("tidyverse", "ggpubr")) library(tidyverse) library(ggpubr) # 仅保留我们关注的切工组 diamonds_sub <- diamonds %>% filter(cut %in% c("Fair", "Good", "Very Good", "Premium", "Ideal"))
2. 执行ANOVA与Tukey事后检验
先做单因素方差分析,再通过TukeyHSD计算调整后p值,最后提取Fair与其他组的对比结果:
# 单因素方差分析模型 aov_fit <- aov(price ~ cut, data = diamonds_sub) # 运行Tukey事后检验 tukey_out <- TukeyHSD(aov_fit) # 提取Fair相关的对比结果,整理成适合绘图的格式 tukey_p <- as.data.frame(tukey_out$cut) %>% rownames_to_column("comparison") %>% # 筛选所有包含Fair的对比组 filter(str_detect(comparison, "Fair")) %>% # 拆分对比的两组名称 separate(comparison, c("g1", "g2"), sep = "-") %>% # 统一基准组为Fair,同时设置标注的y轴位置(避免与箱线图重叠) mutate( target_group = ifelse(g1 == "Fair", g2, g1), y_pos = max(diamonds_sub$price) * 1.1 + seq(0, 4000, length.out = nrow(.)) ) %>% select(target_group, adj_p = `p adj`, y_pos)
3. 绘制箱线图并添加p值
这里提供两种实现方式,按需选择:
方式一:用ggplot原生函数添加标注
ggplot(diamonds_sub, aes(x = cut, y = price)) + geom_boxplot(fill = "#69b3a2") + # 嵌入Tukey调整后的p值 geom_text( data = tukey_p, aes(x = target_group, y = y_pos, label = paste0("p = ", round(adj_p, 4))), color = "red", size = 4 ) + labs(title = "钻石价格 vs 切工(Tukey事后检验p值)", x = "切工等级", y = "价格") + theme_bw()
方式二:用ggpubr的stat_pvalue_manual(更专业的统计标注)
该方法会自动添加连线指向对比组,展示更直观:
# 整理成stat_pvalue_manual要求的数据格式 tukey_p_gg <- tukey_p %>% mutate( group1 = "Fair", group2 = target_group, p = adj_p, y.position = y_pos ) ggboxplot(diamonds_sub, x = "cut", y = "price", fill = "#69b3a2") + stat_pvalue_manual( tukey_p_gg, # 自动处理极小p值的显示 label = ifelse(p < 0.001, "p < 0.001", paste0("p = ", round(p, 4))), tip.length = 0.02 ) + labs(title = "钻石价格 vs 切工(Tukey事后检验调整p值)", x = "切工等级", y = "价格") + theme_bw()
注意事项
- 如果你的数据集价格最大值不同,可调整
y_pos的乘数,确保标注在箱线图上方且不重叠。 - 极小p值直接显示
p < 0.001比长小数更易读,代码中已包含该逻辑。
内容的提问来源于stack exchange,提问作者tassones
相关产品推荐
相关产品推荐

