如何使用ggpubr包geom_signif实现卡方检验显著性标注
报错原因
geom_signif()默认检验逻辑为按x轴分组比较y值的分布,原生不支持直接传入计数数据自动构造列联表运行卡方检验,原代码存在两处逻辑错误:comparisons参数传入值维度混乱,同时混入x轴类别(A、D)和fill映射的变量名(count1、count2),函数无法识别比较分组- 直接传入
test = "chisq.test"时,函数默认将两组y值向量作为检验输入,而非构造列联表,完全不符合卡方检验的输入要求,因此触发缺失值报错
实现方案
方案1:自定义检验函数适配geom_signif
针对列联表卡方检验的输入要求,自定义检验函数传入geom_signif,直接在绘图流程中完成计算和标注,示例代码如下:
library(ggplot2) library(ggpubr) library(data.table) # 读入示例数据 df_test <- data.frame(cat = c("A","D","R"), count1 = c(10,12,23),count2 = c(9,3,4)) melt_count <- data.table::melt(df_test, id.vars = "cat") # 自定义卡方检验函数,适配geom_signif的输入输出格式 chisq_test_2x2 <- function(data, ...) { # 从分组数据构造2×2列联表 contig_tab <- xtabs(value ~ variable + cat, data = data) test_res <- chisq.test(contig_tab) # 返回函数要求的p值结果格式 data.frame(p.value = test_res$p.value) } # 绘图 ggplot(melt_count, aes(x = cat, fill = variable, y = value)) + geom_bar(stat = "identity", position = "dodge", width = 0.7) + geom_signif( # 仅传入x轴上需要两两比较的类别对 comparisons = list(c("A","D"), c("A","R"), c("D","R")), test = chisq_test_2x2, # 手动指定标注y轴位置,避免和柱子遮挡 y_position = c(36, 42, 48), # 直接用星号标注显著性水平 map_signif_level = TRUE, tip_length = 0.01 )
注意:如果列联表存在期望频数小于5的格子,将自定义函数中的chisq.test替换为fisher.test即可切换为费舍尔精确检验,更适配小样本计数场景。
方案2:使用ggstatsplot原生支持计数检验标注
如果不需要严格限制用ggpubr,可使用ggplot生态的ggstatsplot包,其内置的条形图函数原生支持计数数据的卡方/费舍尔检验,无需自定义函数,自动完成检验计算和标注:
library(ggstatsplot) ggbarstats( data = melt_count, x = cat, y = value, fill = variable, # 指定使用参数检验即卡方检验 type = "parametric", conf.level = 0.95, position = ggplot2::position_dodge(width = 0.7), # 关闭默认的冗余信息输出 results.subtitle = FALSE )
补充说明
你的分析目标为验证count2(count1子集)的类别富集,本质是比较不同cat类别下count2占对应类别总计数(count1)的比例是否存在统计学差异,不要在comparisons参数中混传不同美学映射维度的分组值,geom_signif默认仅沿x轴维度完成组间比较。
内容的提问来源于stack exchange,提问作者Tkastyle
相关产品推荐
相关产品推荐

