如何编写自定义管道友好函数?

How to write custom pipe-friendly functions?

我正在尝试使用 magrittr

创建 pipe-friendly functions

例如,我尝试编写一个自定义函数来计算列的平均值:

library(magrittr)
custom_function <-
  function(.data, x) {
   mean(.data$x)
  }

mtcars %>%
 custom_function(mpg)

但是我收到这个错误:

Error in (function(x, i, exact) if (is.matrix(i)) as.matrix(x)[[i]] else .subset2(x,  : 
  object 'mpg' not found

也许我对变量的引用不起作用。我该如何解决这个 .data$x

base R中,我们可以将$更改为[[并将未加引号的列名转换为characterdeparse/substitute

custom_function <- function(.data, x) {
  mean(.data[[deparse(substitute(x))]])
 }

现在,我们应用函数

mtcars %>%
  custom_function(mpg)
#[1] 20.09062

$ 的问题是它实际上是在检查列名 'x' 而没有它存储的关联值。因此,它失败了并且 returns NULL


对于tidyverse,我们可以使用大写运算符({{}})在summarise内进行求值。由于我们只需要一个汇总输出,summarise 可以 return 该单个值,而如果我们需要在原始数据集中创建一个新列,我们需要 mutate。在我们创建汇总列后,只需 pull 该列作为 vector

custom_function <- function(.data, x) {
     .data %>%
         summarise(out = mean({{x}})) %>%
         pull(out)
}

mtcars %>% 
   custom_function(mpg)
[1] 20.09062

.data$x 不引用名称保存在变量 x 中的列,而是引用名为 "x" 的列。使用 .data[[x]] 引用名称为变量 x 中保存的字符串的列,并使用字符串 "mpg".

调用您的函数
library(magrittr)
custom_function <- function(.data, x) mean(.data[[x]])

mtcars %>% custom_function("mpg")
## [1] 20.09062