R 函数使用 .和~

标签 r purrr

我正在尝试学习在 R 中使用 ~.

在下面的代码中,使用和不使用 ~ 编写的函数相同。。我不明白第一个出现的函数中发生了什么错误。

#FIRST FUNCTION
col_summary2 <- function(.x, .f, ...){
  .x <- purrr::keep(.x, is.numeric)
  purrr::map_dbl(.x, ~.f(., ...))
}

col_summary2(mtcars,mean) #Error in mean.default(., ...) : 'trim' must be numeric of length one

#SECOND FUNCTION
col_summary2 <- function(.x, .f, ...){
  .x <- purrr::keep(.x, is.numeric)
  purrr::map_dbl(.x, function(x) .f(x, ...))
}

col_summary2(mtcars,mean) #mpg        cyl       disp         hp       drat         wt       qsec         vs      am       gear       carb
                          #20.090625   6.187500 230.721875 146.687500   3.596563   3.217250  17.848750   0.437500 0.406250   3.687500   2.812500 

最佳答案

在第一种情况下,您的参数在内部传递给 purrr::as_mapper :

as_mapper(~f(., ...))
# function (..., .x = ..1, .y = ..2, . = ..1) 
#   f(., ...)

这意味着它的行为就像您编写的一样:

purrr::map_dbl(.x, function(..., .x = ..1, .y = ..2, . = ..1) f(., ...))

创建的函数有一个...参数(它总是有,即使.f没有它)。

.x.y. 参数实际上是从 ... 中提取的,因为 ..1 表示“第一个东西塞进 ...”,..2 表示“第二个东西...”等等。

因此,在第一种情况下 .x 通过 ... 传递,并最终以 . 结束。

col_summary3 <- function(.x, .f, ...){
  .x <- purrr::keep(.x, is.numeric)
  purrr::map_dbl(.x, ~{print(list(...));.f(., ...)})
}
col_summary3(mtcars,mean) 
# [[1]]
# [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4 10.4
# [17] 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7 15.0 21.4
#  Error in mean.default(., ...) : 'trim' must be numeric of length one 

.x 最终被馈送到 .f 的第一个参数,并通过 .f(.,...) 馈送到第二个参数code>,所以它最终出现在 mean.default 的第二个参数中,即 trim,它不喜欢它。

第二个函数的情况并非如此,其中 ... 参数(在本例中未使用)从初始调用顺利传递到 .f打电话。

回复“那么,在这种情况下,我不能使用 ~ 和 .,对吧?”

您不能直接使用它,因为与...有冲突。不过,您可以通过将其传递给 .y 参数并使用 purr::invoke 来绕过它,但这对于下一个必须阅读它的人来说非常意味着: )。

col_summary4 <- function(.x, .f, ...){
  .x <- purrr::keep(.x, is.numeric)
  purrr::map_dbl(.x, ~ invoke(.f, .y, .), .y=list(...))
}

col_summary4(mtcars,mean) 
# mpg        cyl       disp         hp       drat         wt       qsec         vs         am       gear       carb 
# 20.090625   6.187500 230.721875 146.687500   3.596563   3.217250  17.848750   0.437500   0.406250   3.687500   2.812500 

col_summary4(mtcars,mean, trim = 0.3)
# mpg         cyl        disp          hp        drat          wt        qsec          vs          am        gear        carb 
# 19.1785714   6.4285714 214.5071429 136.2857143   3.5971429   3.2467857  17.7600000   0.3571429   0.2857143   3.5714286   2.6428571 

关于R 函数使用 .和~,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51362474/

相关文章:

r - 将 purrr 列表中的数据帧绑定(bind)在一起

r - 对 big.matrix 进行子集化的正确方法

r - 有条件地将数据框中的值更改为其列名

r - 在 purrr 的 map() 函数中使用 levene_test?

r - 如何迭代添加列以使用半修改名称重新编码

r - 使用 purrr 中的 "keep"或 "discard"根据两个条件过滤列表

r - 使用查找表更改数据框多列中的值

java - 无法使用 mailR 包通过 Outlook.com 发送电子邮件

r - 向数据框添加排名列

r - 有没有更好的方法来检查列表中的所有元素是否都已命名?