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

使用箱线图时无法计算带结精确p值的技术咨询

问题描述

我有多个癌症数据集,以基因为行、样本为列,每个数据集包含标记为Response的治疗响应样本和NoResponse的无响应样本。我想用带facet_wrap的箱线图,结合Wilcoxon检验,分析每个数据集里两组样本的关键基因表达差异,但运行代码时出现了一系列警告,且发现有39行数据被移除(但我确认数据中没有非有限值)。想搞清楚这些警告的含义,以及Wilcoxon检验里的“带结(ties)”是什么意思。

运行时警告

Warning messages:
1: Removed 39 rows containing non-finite values (stat_signif). 
2: In wilcox.test.default(c(1904, 736, 26, 43, 420, 336, 105, 569,  :
  cannot compute exact p-value with ties
3: In wilcox.test.default(c(162, 23, 94, 25, 22, 1, 19, 148, 76, 48,  :
  cannot compute exact p-value with ties
4: In wilcox.test.default(c(0.0143552929770701, 0.739848102699327,  :
  cannot compute exact p-value with ties
5: In wilcox.test.default(c(110, 204, 164, 437), c(33, 15, 239, 65,  :
  cannot compute exact p-value with ties
6: In wilcox.test.default(c(14, 96, 8, 31, 89, 1, 168, 20, 574, 0,  :
  cannot compute exact p-value with ties
7: Removed 39 rows containing non-finite values (stat_boxplot). 
8: Position guide is perpendicular to the intended axis. Did you mean to specify a different guide `position`? 

所用R函数代码

showgene <- function(gene) {
  
  dt = data.frame(expr=c(t(dataset1[gene,]),t(dataset2[gene,]), t(dataset3[gene,]),t(dataset4[gene,]),
                                 t(dataset5[gene,]),t(dataset6[gene,]),t(dataset7[gene,]),t(dataset8[gene,]),t(dataset9[gene,])
                                 ,t(dataset10[gene,]),t(dataset11[gene,]),t(dataset12[gene,]),t(dataset13[gene,]),t(dataset15[gene,]),
                                 t(dataset16[gene,]) ,t(dataset20[gene,]),t(dataset21[gene,])),
                          response=Response,  dataSet=c(rep('data1',ncol(dataset1)),
                                                      rep('data2',ncol(dataset2)),
                                                      rep('data3',ncol(dataset3)),
                                                      rep('data4',ncol(dataset4)),
                                                      rep('data5',ncol(dataset5)),
                                                      rep('data6',ncol(dataset6)),
                                                      rep('data7',ncol(dataset7)),
                                                      rep('data8',ncol(dataset8)),
                                                      rep('data9',ncol(dataset9)),
                                                      rep('data10',ncol(dataset10)),
                                                      rep('data11',ncol(dataset11)),
                                                      rep('data12',ncol(dataset12)),
                                                      rep('data13',ncol(dataset13)),
                                                      rep('data15',ncol(dataset15)),
                                                      rep('data16',ncol(dataset16)),
                                                      rep('data20',ncol(dataset20)),
                                                      rep('data21',ncol(dataset21))))
  
  dt[['expr']] = as.numeric(as.character(dt[['expr']]))
  
  facetplot = dt %>% ggplot(aes(response, expr, fill = response)) +
    facet_wrap(~dataSet, scales = 'free') + 
    labs(x = 'Clinical outcome', y = 'Expression') +
    ggtitle(gene) + theme(plot.title = element_text(hjust = 0.5)) +
    stat_compare_means(comparisons = my_comparisons, vjust = 1.2, method = "wilcox.test") 
  
  
  boXplots = facetplot + geom_boxplot()
  return(boXplots)
  
}

showgene('CD274')

数据集示例(dt)

structure(list(expr = c(1484, 290, 1421, 251, 203, 888, 608, 
1203, 1340, 1021, 182, 170, 291, 401, 140, 117, 582, 1177, 191, 
152, 111, 24, 187, 705, 1122, 694, 224, 1122, 501, 268, 1277, 
270, 705, 276, 88, 157, 2564, 25, 251, 255, 484, 96, 37, 180, 
169, 949, 1477, 128, 321, 32.164880027492, 30.5002842845929, 
30.3194383690632, 31.2055296895404, 31.9247612316469, 30.6333196961515, 
30.0292937311801, 30.9803064773279, 30.0890307092925, 31.6247367596842, 
30.2033356286348), response = c("NoResponse", "NoResponse", "Response", 
"NoResponse", "NoResponse", "NoResponse", "NoResponse", "Response", 
"NoResponse", "NoResponse", "NoResponse", "NoResponse", "NoResponse", 
"NoResponse", "Response", "Response", "NoResponse", "Response", 
"NoResponse", "NoResponse", "NoResponse", "NoResponse", "NoResponse", 
"Response", "NoResponse", "NoResponse", "Response", "Response", 
"NoResponse", "NoResponse", "NoResponse", "NoResponse", "NoResponse", 
"NoResponse", "NoResponse", "Response", "NoResponse", "NoResponse", 
"NoResponse", "NoResponse", "NoResponse", "NoResponse", "NoResponse", 
"NoResponse", "NoResponse", "NoResponse", "NoResponse", "Response", 
"NoResponse", "Response", "NoResponse", "NoResponse", "NoResponse", 
"Response", "Response", "NoResponse", "NoResponse", "Response", 
"Response", "NoResponse"), dataSet = c("data1", "data1", "data1", 
"data1", "data1", "data1", "data1", "data1", "data1", "data1", 
"data1", "data1", "data1", "data1", "data1", "data1", "data1", 
"data1", "data1", "data1", "data1", "data1", "data1", "data1", 
"data1", "data1", "data1", "data1", "data1", "data1", "data1", 
"data1", "data1", "data1", "data1", "data1", "data1", "data1", 
"data1", "data1", "data1", "data1", "data1", "data1", "data1", 
"data1", "data1", "data1", "data1", "data2", "data2", "data2", 
"data2", "data2", "data2", "data2", "data2", "data2", "data2", 
"data2")), row.names = c(NA, 60L), class = "data.frame")
问题解答

1. 关于“移除39行含非有限值”的警告(警告1、7)

你确认数据里没有NA、NaN或Inf,但出现这个警告,大概率是类型转换失败导致的隐性非有限值:

  • 你用了dt[['expr']] = as.numeric(as.character(dt[['expr']])),如果原始expr列里有无法转成数值的字符串(比如空字符串、非数字字符),转换后会变成NA,这些NA就会被ggplot的stat_signif和stat_boxplot识别为非有限值并移除。
  • 另外检查Response向量和各个数据集的样本数是否匹配:你手动拼接response=Response,如果Response的长度和所有数据集的总样本数(sum(ncol(dataset1),ncol(dataset2),...))不一致,会导致循环填充,可能引入异常值,进而在转换或绘图时被判定为非有限值。

2. Wilcoxon检验的“带结(ties)”警告(警告2-6)

什么是“结(ties)”?

在Wilcoxon秩和检验(Mann-Whitney U检验)中,结指的是两组数据中存在相同的数值。比如你的表达数据里,不同样本的基因表达量完全一样,这就是结。

为什么会出现这个警告?

Wilcoxon检验的精确p值计算依赖于所有观测值都是唯一的假设——因为它基于秩的排列组合。当有结存在时,精确的排列组合数无法准确计算,所以R会提示无法计算精确p值,转而使用近似方法(正态近似)来计算p值,这个近似结果依然是有效的,只是不是“精确”值而已。

3. 位置指南方向错误的警告(警告8)

这个警告来自stat_compare_means的标注位置设置:你用了vjust=1.2,但因为x轴是分类变量(response是两组),vjust控制的是垂直方向位置,而标注可能需要水平调整(hjust),或者stat_compare_means的默认位置和你的绘图方向不匹配。可以尝试调整position参数,比如设置position = position_dodge(width = 0.8),或者改用hjust来调整标注位置。

解决建议

  • 排查数据转换问题:运行sum(is.na(dt$expr))查看有多少NA,再检查原始数据集的expr列是否有非数字内容;同时验证length(Response)是否等于sum(sapply(list(dataset1,dataset2,...),ncol)),确保样本数匹配。
  • 处理Wilcoxon的结问题:如果想消除警告,可以在wilcox.test里添加exact=FALSE参数,明确告诉R使用近似方法。在stat_compare_means里可以通过method.args = list(exact = FALSE)来传递这个参数:
    stat_compare_means(comparisons = my_comparisons, vjust = 1.2, method = "wilcox.test", method.args = list(exact = FALSE))
    
  • 修正位置警告:调整stat_compare_means的位置参数,比如:
    stat_compare_means(comparisons = my_comparisons, hjust = 0.5, method = "wilcox.test", method.args = list(exact = FALSE))
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:54:26