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

使用R中group_by执行单样本Wilcoxon检验时p值全部相同的问题

问题描述

我正在处理一个包含36000多个个体、1000多个物种的后代性别比大型数据集,希望检验每个物种的性别比中位数是否显著偏离0.5,采用单样本Wilcoxon检验。

示例数据集代码:

n<-100
dat<-data.frame(species=rep(LETTERS[1:5],n/5), SR=sample((1:100)/100,n,replace=TRUE))

运行以下代码后,所有物种的p值完全相同:

library(dplyr)
res <- dat %>% group_by(species) %>%
do(w=wilcox.test(dat$SR,mu=.5,alternative=("two.sided"))) %>%
summarize(species,wilcox=w$p.value)
res
#OUTPUT#
# # A tibble: 5 x 2
  species wilcox
  <chr>    <dbl>
1 A        0.465
2 B        0.465
3 C        0.465
4 D        0.465
5 E        0.465
错误原因

核心问题是你在wilcox.test中调用了全局的dat$SR,而非当前分组的子数据集。group_by(species)只是对数据做分组标记,但do()里用dat$SR会直接读取整个原始数据集的SR列,导致每个分组都在对全量数据做Wilcoxon检验,最终得到完全相同的p值。

解决方法

以下是几种可行的修正方案,推荐使用新版dplyr的语法:

方案1:修正do()的变量引用

将dat$SR改为.$SR(do()中用.指代当前分组的子数据),或者直接写SR:

library(dplyr)
res <- dat %>% 
  group_by(species) %>%
  do(w = wilcox.test(.$SR, mu = .5, alternative = "two.sided")) %>%
  summarize(species, wilcox_p = w$p.value)

方案2:使用group_modify(推荐,dplyr 1.0.0+)

新版dplyr已逐步弃用do(),更推荐用group_modify处理分组后的自定义操作,逻辑更清晰:

library(dplyr)
res <- dat %>%
  group_by(species) %>%
  group_modify(~ {
    test_result <- wilcox.test(.$SR, mu = 0.5, alternative = "two.sided")
    tibble(wilcox_p = test_result$p.value)
  }) %>%
  ungroup()

方案3:嵌套数据框+purrr(保留更多检验信息)

如果需要同时提取统计量、置信区间等更多结果,可以用嵌套数据框结合purrr的映射操作:

library(dplyr)
library(purrr)
library(tibble)

res <- dat %>%
  group_nest(species) %>%  # 按物种嵌套数据
  mutate(
    test = map(data, ~ wilcox.test(.$SR, mu = 0.5, alternative = "two.sided")),
    wilcox_p = map_dbl(test, "p.value"),  # 提取p值
    w_statistic = map_dbl(test, "statistic")  # 提取检验统计量
  ) %>%
  select(species, wilcox_p, w_statistic) %>%  # 保留需要的列
  ungroup()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 04:37:02