如何制作同时支持带引号和不带引号的参数的 tidyverse 函数?

How can you make tidyverse functions that support both quoted and unquoted arguments?

我知道如何创建支持对名为 'variable' 的参数进行准引号的函数 {对未引用的函数参数使用 dplyr::enquo(variable) 或需要您引用参数的函数 {使用 rlang::sym("variable")}。有没有一种简单的方法可以使函数同时支持引用和未引用的参数?

例如,dplyr::select() 允许 select(mtcars, mpg)select(mtcars, "mpg")。构建一个可以做任何事情的功能的最佳实践是什么?一个考虑因素是对数据屏蔽的影响,我不确定在构建更复杂的函数时是否需要考虑这一点。

我一直在 github 页面中寻找基本的 dplyr 函数,但是像 select 这样的简单函数依赖于一个全新的包 (tidyselect),所以发生了很多事情。在Tidy测评书上也没有看到明确的解释。下面是一个 hack 函数,它同时支持带引号和不带引号的参数,但这不是一个可靠的解决方案。我相信有更简单的方法。

library(dplyr)

data(mtcars)

test_func <- function(variable) {
  if(nrow(count(mtcars, {{variable}})) == 1) {
    variable <- rlang::sym(variable)
  }
  count(mtcars, {{variable}})
}

all_equal(
  test_func(cyl),
  test_func("cyl")
)

如果需要同时处理 quoted/unquoted,请使用 ensym

test_func <- function(variable) {  

    dplyr::count(mtcars, !!rlang::ensym(variable))    

  }

-测试

test_func(cyl)
#  cyl  n
#1   4 11
#2   6  7
#3   8 14
test_func('cyl')
#  cyl  n
#1   4 11
#2   6  7
#3   8 14

注意:最好将数据也作为函数的参数