如何为ggboxplot()添加紧凑字母显示,能否结合cldList()实现
解决方案
- 完全可以实现
cldList()与ggboxplot()的结合,同时也支持封装进lapply()对列表中的所有数据框做批量处理。你原有代码的核心问题是cldList()没有承接dunnTest()的输出结果,无法生成正确的显著性字母。 - 你可以将「Dunn检验→生成CLD字母→绘制带字母的箱线图」整个流程封装为自定义函数,再用
lapply()遍历所有数据框即可,完整可运行代码如下:
library(FSA) library(multcompView) library(rcompanion) library(ggplot2) library(ggpubr) library(tidyr) # 你的示例数据 df_list <- list( `1.3.A` = tibble::tribble( ~Person, ~Height, ~Weight, "Alex", 175, 75, "Gerard", 110, 85, "Clyde", 120, 79 ), `2.2.A` = tibble::tribble( ~Person, ~Height, ~Weight, "Missy", 162, 55, "Britany", 111, 56, "Sussie", 192, 85 ), `1.1.B` = tibble::tribble( ~Person, ~Height, ~Weight, "Luke", 177, 66, "Alex", 169, 69, "Haley", 145, 54 ) ) # 封装单数据框的处理+绘图函数 plot_with_cld <- function(df) { # 1. 执行Dunn检验 dt <- dunnTest(Weight ~ as.factor(Person), method = "bh", data = df) dt_res <- dt$res # 2. 生成紧凑字母显示 cld <- cldList(P.adj ~ Comparison, data = dt_res, threshold = 0.05) colnames(cld)[1] <- "Person" # 对齐列名方便后续匹配 # 3. 计算字母放置位置,避免和箱线重叠 label_pos <- aggregate(Weight ~ Person, data = df, FUN = max) label_pos$y_pos <- label_pos$Weight * 1.05 # 向上偏移5%,可自行调整 cld <- merge(cld, label_pos, by = "Person") # 4. 绘制带显著性字母的箱线图 p <- ggboxplot(df, x = "Person", y = "Weight") + geom_text(data = cld, aes(x = Person, y = y_pos, label = Letter), size = 4) + expand_limits(y = max(df$Weight) * 1.15) + # 调整y轴上限避免字母被截断 labs(x = "个体", y = "体重") # 若需要同时绘制Height+Weight的组合图,对Height重复上述检验加字母逻辑即可 return(p) } # 批量处理所有数据框,输出结果图列表 plot_list <- lapply(df_list, plot_with_cld) # 查看指定数据框的绘图结果,例:第一个数据框的结果 print(plot_list[["1.3.A"]])
注意事项
- 若需要给Height也添加显著性字母,在自定义函数中重复Dunn检验、CLD生成逻辑即可,两个指标的图可以用
ggarrange()拼接。 - 当分组数量较多时(你提到的30个分组),可适当调小
geom_text的size参数,或添加theme(axis.text.x = element_text(angle = 45, hjust = 1))旋转x轴标签避免重叠。 - CLD字母规则:共享相同字母的组无统计学差异(p>0.05),字母不同的组存在显著差异(p<0.05)。
内容的提问来源于stack exchange,提问作者Tyler Ruddenfort
相关产品推荐
相关产品推荐

