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

如何批量对多列数据执行Mann-Whitney U检验(wilcox.test)

批量执行Mann-Whitney U检验的解决方案

问题背景

现有数据集包含分组列Group(分为A、B两组)及43列元素数值数据,部分数据含NA值。手动拆分数据集为A、B子集后对单列执行Mann-Whitney U检验(wilcox.test)效率极低,直接传入数据框或多列时出现'x' must be numeric错误,需要批量执行检验的方法。

数据集示例:

AreaAlCdCu
A100000.230
A150000.525
ANANaNA
B80001.155
B110000.240
B130000.140

部分数据的dput结构:

structure(list(Group = c("A", "A", "A", "A", 
"A", "B", "B", "B", "B", "B", "B"
), Al = c(NA, NA, NA, 18100, 18400, 32500, 33200, 31200, 
17400, 13900, 14400), As = c(NA, NA, NA, 16.9, 14.6, 8.83, 8.59, 
8.42, 13.4, 13.5, 13.7), B = c(NA, NA, NA, 18, 16, 14, 14, 11, 
53, 87, 58), Bi = c(NA, NA, NA, 0.13, 0.12, 0.57, 0.55, 0.52, 0.22, 
0.18, 0.21), Ca = c(NA, NA, NA, 5950, 5480, 6220, 6230, 5950, 
6850, 8170, 7000), Cd = c(NA, NA, NA, 0.2, 0.2, 0.2, 0.2, 0.18, 
0.31, 0.36, 0.46)), row.names = c(1L, 2L, 3L, 4L, 5L, 40L, 41L, 
42L, 43L, 44L, 45L), class = c("tbl_df", "tbl", "data.frame"))

手动单列检验代码:

# Data是上述数据框
Area_A <- subset(Data, Group %in% c("A"))
Area_B <- subset(Data, Group %in% c("B"))

WhitneyU_Al <- wilcox.test(Area_A$Al, Area_B$Al, na.rm = TRUE, paired = FALSE, exact = FALSE)

尝试的批量代码(报错):

WhitneyU <- wilcox.test(Area_A, Area_B, na.rm = TRUE, paired = FALSE, exact = FALSE)
# OR
WhitneyU <- wilcox.test(Area_A[2:43], Area_B[2:43], na.rm = TRUE, paired = FALSE, exact = FALSE)

解决方案

第一步:数据预处理(解决'x' must be numeric错误)

首先检查并转换所有待检验列的数值类型,将字符串型的"Na"替换为标准NA,并确保列是numeric类型:

# 用tidyverse实现
library(tidyverse)

Data_cleaned <- Data %>%
  mutate(across(-Group, ~ ifelse(.x == "Na", NA, .x) %>% as.numeric()))

# 用base R实现
Data_cleaned <- Data
for(col in setdiff(names(Data_cleaned), "Group")){
  Data_cleaned[[col]] <- as.numeric(ifelse(Data_cleaned[[col]] == "Na", NA, Data_cleaned[[col]]))
}

第二步:批量执行检验

方法1:Base R 实现(无需额外包)

使用lapply遍历所有数值列,对每列执行wilcox.test:

# 获取所有待检验的列名(排除Group列)
test_cols <- setdiff(names(Data_cleaned), "Group")

# 批量执行检验
wilcox_results <- lapply(test_cols, function(col){
  x <- Data_cleaned[Data_cleaned$Group == "A", col]
  y <- Data_cleaned[Data_cleaned$Group == "B", col]
  wilcox.test(x, y, na.rm = TRUE, paired = FALSE, exact = FALSE)
})

# 给结果命名,方便查看
names(wilcox_results) <- test_cols

# 查看指定列结果,比如Al
wilcox_results$Al

方法2:Tidyverse 实现(结果结构化)

使用purrr::map结合dplyr,将检验结果整理成数据框格式,便于后续分析:

library(purrr)
library(dplyr)

# 批量执行并整理结果为数据框
wilcox_df <- Data_cleaned %>%
  select(-Group) %>%
  map_dfr(function(col){
    x <- col[Data_cleaned$Group == "A"]
    y <- col[Data_cleaned$Group == "B"]
    res <- wilcox.test(x, y, na.rm = TRUE, paired = FALSE, exact = FALSE)
    tibble(
      statistic = res$statistic,
      p_value = res$p.value,
      method = res$method
    )
  }, .id = "element")

# 查看结构化结果
print(wilcox_df)

结果说明

  • Base R方法返回列表格式的检验结果,可通过列名直接调取单条结果;
  • Tidyverse方法返回结构化数据框,更适合批量查看、筛选或可视化统计结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 10:40:37