【发布时间】:2020-08-12 21:29:33
【问题描述】:
我知道如何为名为“变量”的参数{使用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")
)
【问题讨论】:
-
这种 UI 没有任何用处,因为您无法将字符串保存在变量中并以正常方式引用它。如果您真的想这样做,请按照 akrun 的建议使用
ensym(),它实现的语义与=的 LHS 或library()函数中的语义相同。 -
我承认支持这两种类型并不是一个巨大的收获,而且我对这种方法的缺点很感兴趣。
ensym()会在哪些情况下失败?如果您需要将符号存储为变量(例如在 ggplot 中进行标记),您能否不将符号转换回字符串? -
不利的一面是,如果有人看到
foo("bar"),他们可能会尝试quux <- "bar"; foo(quux),但他们会感到困惑,因为它不能以相同的方式工作。