使用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
相关产品推荐
相关产品推荐

