首页 > 解决方案 > 在 R 中为 dplyr 的 mutate 缩放一个函数

问题描述

我想计算 R 中四个人的二比例检验。

> example <- data.frame(x = 41:44, y = 43:46, z = c(100,100,100,100), w = c(101,101,101,101))
> example
   x  y   z   w
1 41 43 100 101
2 42 44 100 101
3 43 45 100 101
4 44 46 100 101

具体来说,我想要prop.test函数的 p 值

> prop.test(c(41,43), c(100,101))$p.value
[1] 0.9336564

添加到每一行。我想继续使用mutatefrom 的功能dplyr,它可以让我轻松地做这样的事情:

> example %>% mutate(total = x + y + z + w)
   x  y   z   w total
1 41 43 100 101   285
2 42 44 100 101   287
3 43 45 100 101   289
4 44 46 100 101   291

但是,这并没有达到我对矢量化函数的预期,比如sum().

> example %>% mutate(total = sum(x,y,z,w))
   x  y   z   w total
1 41 43 100 101  1152
2 42 44 100 101  1152
3 43 45 100 101  1152
4 44 46 100 101  1152
> example %>% mutate(just_z = sum(z))
   x  y   z   w just_z
1 41 43 100 101    400
2 42 44 100 101    400
3 43 45 100 101    400
4 44 46 100 101    400

如图所示,矢量化sum()函数获取整个列z,而不是仅读取z相应行上的值。结果,prop.test我试图运行的结果出乎意料:

> example %>% mutate(p = prop.test(c(x,y), c(z,w))$p.value)
   x  y   z   w         p
1 41 43 100 101 0.9989672
2 42 44 100 101 0.9989672
3 43 45 100 101 0.9989672
4 44 46 100 101 0.9989672

我可以通过一些可怕的程序编程或列表理解来得到我的答案:

> to_vec(for(i in 1:length(example))
+     prop.test(c(example$x[i], example$y[i]),
+               c(example$z[i], example$w[i]))$p.value)
[1] 0.9336564 0.9349922 0.9362936 0.9375628

但这种方法不优雅。有没有办法“缩放”矢量化函数或mutate仅对行成员进行操作?

标签: rdplyr

解决方案


对于此类操作,您可以使用rowwise

library(dplyr)
example %>% rowwise() %>% mutate(p = prop.test(c(x,y), c(z,w))$p.value)

#      x     y     z     w     p
#  <int> <int> <dbl> <dbl> <dbl>
#1    41    43   100   101 0.934
#2    42    44   100   101 0.935
#3    43    45   100   101 0.936
#4    44    46   100   101 0.938

pmap来自 的变体purrr

example %>% mutate(p = purrr::pmap_dbl(., 
               ~{x <- c(...);prop.test(x[1:2], x[3:4])$p.value}))

推荐阅读