【发布时间】:2020-03-28 17:56:08
【问题描述】:
假设您在 R 函数中有一个参数,可以是:
- 一个原始的 tidyselect 助手,例如
contains("a")、starts_with("a")等, - 与助手的引用列表,
vars(contains("a"))。
如果您是情况 (1) 或 (2),您如何在函数内进行检查?
问题是is_quosures(vars(contains("a"))) 可以工作,但is_quosures(contains("a")) 将不起作用,因为它首先尝试评估函数contains("a"),当单独评估时返回错误!?
library(rlang)
library(dplyr)
is_quosures(vars(contains("a")))
#> [1] TRUE
is_quosures(contains("a"))
#> Error: No tidyselect variables were registered
fo <- function(var) {
is_quosures(var)
}
fo(vars(contains("a")))
#> [1] TRUE
fo(contains("a"))
#> Error: No tidyselect variables were registered
由reprex package (v0.3.0) 于 2019-12-03 创建
用例
您想使用诸如summarise_at(data, var) 之类的函数,并希望使其对将var 指定为直接tidyselect 助手或包装在vars() 调用中的用户具有鲁棒性。我想出解决这个问题的唯一方法是逐案进行 if/then 检查它是否是 quosure (如果不是,则包装到 vars 中),但这在上述情况下将完全失败。
library(rlang)
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
fo <- function(var) {
is_var_closure <- rlang::is_quosures(var)
if(is_var_closure) {
dplyr::summarise_at(iris, var, mean)
} else {
dplyr::summarise_at(iris, quos(var), mean)
}
}
fo(vars(starts_with("Sepal")))
#> Sepal.Length Sepal.Width
#> 1 5.843333 3.057333
fo(starts_with("Sepal"))
#> Error: No tidyselect variables were registered
由reprex package (v0.3.0) 于 2019 年 12 月 3 日创建
【问题讨论】:
-
这里的用例是什么?你想做什么?
-
我同意 Ronak 的评论。为了避免XY problem,您能否提供更多上下文。粗略/幼稚的方法可能是使用
tryCatch来捕获错误,但这可能会修复结果而不是原因。 -
当然,好点,我添加了一个用例,谢谢!