使用group_by和summarise进行并行wilcox.test

9

必须有一种R的方法可以使用group_by并行调用wilcox.test来处理多个观测值。我花了很多时间阅读相关资料,但仍然无法找到一个可以胜任任务的wilcox.test调用方法。下面是使用magrittr管道和summarize()的示例数据和代码。

library(dplyr)
library(magrittr)

# create a data frame where x is the dependent variable, id1 is a category variable (here with five levels), and id2 is a binary category variable used for the two-sample wilcoxon test
df <- data.frame(x=abs(rnorm(50)),id1=rep(1:5,10), id2=rep(1:2,25))

# make sure piping and grouping are called correctly, with "sum" function as a well-behaving example function 
df %>% group_by(id1) %>% summarise(s=sum(x))
df %>% group_by(id1,id2) %>% summarise(s=sum(x))

# make sure wilcox.test is called correctly 
wilcox.test(x~id2, data=df, paired=FALSE)$p.value

# yet, cannot call wilcox.test within pipe with summarise (regardless of group_by). Expected output is five p-values (one for each level of id1)
df %>% group_by(id1) %>% summarise(w=wilcox.test(x~id2, data=., paired=FALSE)$p.value) 
df %>% summarise(wilcox.test(x~id2, data=., paired=FALSE))

# even specifying formula argument by name doesn't help
df %>% group_by(id1) %>% summarise(w=wilcox.test(formula=x~id2, data=., paired=FALSE)$p.value)

错误信息如下: buggy调用导致此错误。
Error in wilcox.test.formula(c(1.09057358373486, 
    2.28465932554436, 0.885617572657959,  : 'formula' missing or incorrect

感谢您的帮助;我希望这对于有类似问题的人也有所帮助。


1
其他答案更完整,但为了列出所有可能的解决方案:df %>% group_by(id1) %>% summarise(w=wilcox.test(x[id2==1], x[id2==2], paired=FALSE)$p.value) - dalloliogm
@dalloliogm 你的解决方案对我来说最好,因为在我的情况下id1是非数字的,而你的解决方案仍然有效。我先前尝试使用页面上其他地方显示的do()函数,但是出现了错误。 - Peurke
2个回答

17

使用do函数(在加载dplyr库后调用?do)即可轻松完成您的任务。使用您的数据,链将如下所示:

df <- data.frame(x=abs(rnorm(50)),id1=rep(1:5,10), id2=rep(1:2,25))
df <- tbl_df(df)
res <- df %>% group_by(id1) %>% 
       do(w = wilcox.test(x~id2, data=., paired=FALSE)) %>% 
       summarise(id1, Wilcox = w$p.value)

输出

res
Source: local data frame [5 x 2]

    id1    Wilcox
  (int)     (dbl)
1     1 0.6904762
2     2 0.4206349
3     3 1.0000000
4     4 0.6904762
5     5 1.0000000

请注意,我在group_bysummarize之间添加了do函数。
希望这有所帮助。


1
优秀的答案使用了原问题中提到的group_by和pipes。我选择了@patrickmdnet的回答作为官方答案,因为它优雅的dplyr方法可以直接应用于我的更复杂的真实数据框架,而这个框架在这里列出的group_by/do管道方法中出现了一些未知的问题。 - curious lab rat

1
您可以使用基本的R语言实现此操作(尽管结果是一个笨重的列表):
by(df, df$id1, function(x) { wilcox.test(x~id2, data=x, paired=FALSE)$p.value })

或者使用dplyr:
ddply(df, .(id1), function(x) { wilcox.test(x~id2, data=x, paired=FALSE)$p.value })

  id1        V1
1   1 0.3095238
2   2 1.0000000
3   3 0.8412698
4   4 0.6904762
5   5 0.3095238

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接