【问题标题】:Inconsistent function behavoi in dplyr::mutatedplyr::mutate 中的函数行为不一致
【发布时间】:2018-01-10 12:09:09
【问题描述】:

我想使用 dplyr::mutate 将 p 值添加到数据框,但它不起作用,我不知道为什么。

这行得通:

my_add<-function(x, y) x + y
str(my_add(5, 15))
#> num 20

df <- data.frame(success=c(5,8,4), fail=c(15,13,18))
mutate(df, total=my_add(success, fail))
#>   success fail total
#> 1       5   15    20
#> 2       8   13    21
#>13       4   18    22

但这不是:

my_binom <- function(x, y) binom.test(x, y)$"p.value"
str(my_binom(5, 20))
#> num 0.0414

df <- data.frame(success=c(5,8), total=c(20,21))
mutate(df, p_value=my_binom(success, total))
#>   success total   p_value
#> 1       5    20 0.5810547
#> 2       8    21 0.5810547

df <- data.frame(success=c(5,8,4), total=c(20,21,22))
mutate(df, p_value=my_binom(success, total))
#> Error in mutate_impl(.data, dots) : 
#>   Evaluation error: incorrect length of 'x'.

这两个函数都采用相同的输入并返回一个数字,所以我无法理解这种差异。有人可以告诉我发生了什么吗?谢谢!

会话信息:

sessionInfo()
#> R version 3.4.1 (2017-06-30)
#> Platform: x86_64-apple-darwin15.6.0 (64-bit)
#> Running under: OS X El Capitan 10.11.6
#> 
#> Matrix products: default
#> BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libRlapack.dylib
#> 
#> locale:
#> [1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] bindrcpp_0.2 dplyr_0.7.4 
#> 
#> loaded via a namespace (and not attached):
#>  [1] compiler_3.4.1   magrittr_1.5     assertthat_0.2.0 R6_2.2.2         tools_3.4.1     
#>  [6] glue_1.1.1       tibble_1.3.4     yaml_2.1.14      Rcpp_0.12.14     pkgconfig_2.0.1 
#> [11] rlang_0.1.2      bindr_0.1   

【问题讨论】:

  • this question 的答案之一建议使用rowwise(),这似乎可以解决问题,但并没有让我更接近了解发生了什么
  • 尝试将 2 个向量输入到my_binom。例如:my_binom(c(1,2,3),c(4,5,6))。是否返回单个值?如果是,请仔细改写my_binom;看起来您希望它输出与两个输入长度相同的向量,而不是单个数字。
  • 所以mutate() 所做的只是将指定的列输入指定的函数,然后cbind() 输出?这实际上解释了很多。我认为它是循环遍历行并为每个行进行函数调用。谢谢!
  • 基本正确,是的。 rowwise() 会强制执行您正在考虑的行为,这就是它起作用的原因,但首先将函数矢量化会更有效。

标签: r dplyr


【解决方案1】:
mutate(df, p_value = purrr::map2(success, total, my_binom))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-20
    • 2016-12-22
    • 2018-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多