R 函数使用 .和〜

R function using . and ~

我正在努力学习在 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 表示 "first thing stuffed into ...",..2 表示 "second thing..." 等等。

所以在你的第一种情况下 .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(.,...),所以它最终出现在 mean.default 的第二个参数中,即 trim,不喜欢它。

第二个函数不是这种情况,其中 ... 参数(在本例中未使用)从初始调用顺利传递到 .f 调用。

回复 "So, in this case, I can't use ~ and ., right?"

...有冲突,不能直接使用。但是,您可以通过将它传递给 .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