R 测试对空参数使用enquo()的函数
我有一个创建dataframe的函数,但在这个过程中会更改名称。我试图用dplyr qousres处理空列名。我的测试套件如下所示:R 测试对空参数使用enquo()的函数,r,dplyr,R,Dplyr,我有一个创建dataframe的函数,但在这个过程中会更改名称。我试图用dplyr qousres处理空列名。我的测试套件如下所示: dataframe <- data_frame( a = 1:5, b = 6:10 ) my_fun <- function(df, col_name, new_var_name = NULL) { target <- enquo(col_name) c <- df %>% pull(!!target) * 3
dataframe <- data_frame(
a = 1:5,
b = 6:10
)
my_fun <- function(df, col_name, new_var_name = NULL) {
target <- enquo(col_name)
c <- df %>% pull(!!target) * 3 # here may be more complex calculations
# handling NULL name
if (is.null(new_var_name)) {
new_name <- quo(default_name)
} else{
new_name <- enquo(new_name)
}
data_frame(
abc = df %>% pull(!!target),
!!quo_name(new_name) := c
)
}
my_fun(dataframe, a)
我获得了预期的默认名称:
# A tibble: 5 x 2
abc default_name
<int> <dbl>
1 1 3
2 2 6
3 3 9
4 4 12
5 5 15
我错在哪里?这个问题实际上与
quo
和enquo
返回不同的东西无关,而是在你真正想要之前评估对象。如果要使用browser()
单步执行函数,则会在If(is.null(new\u var\u name))
语句中看到错误
当您执行is.null(new\u var\u name)
时,您正在评估作为new\u var\u name
传递的变量,因此现在执行enquo
已经太迟了。这是因为is.null
需要查看变量的值,而不仅仅是变量名本身
一种函数,它不计算传递给函数的参数,但检查参数是否存在缺失()
MrFlick概述的方法不适用于嵌套函数调用。我们可以使用
rlang::quo_is_null
从rlang::quo_is_null
上的文档中可以看出:“当缺少的参数通过enquo()或quos()捕获为quosure时,它们将作为空quosure返回。”。因此,当我们用空quosure嵌套函数调用时,内部函数中对missing
的调用最终会检查空quosure是否为NULL
,并且总是返回FALSE
,因为是quosure的内容为NULL
,而不是quosure本身
我将以下详细函数放在一起,以显示正在发生的情况:
library(dplyr)
library(rlang)
f1 <- function(var = NULL) {
print(paste("substitute shows:", paste(substitute(var), collapse = " ")))
print(paste("missing returns:", missing(var)))
enquo_var <- enquo(var)
print(paste("after enquo:", quo_get_expr(enquo_var)))
print(paste("quo_is_null returns:", rlang::quo_is_null(enquo_var)))
rlang::quo_is_null(enquo_var)
}
f2 <- function(var = NULL) {
f1({{var}})
}
f1(Sepal.Length)
f1()
f2(Sepal.Length)
f2() # this is where `missing` fails.
库(dplyr)
图书馆(rlang)
谢谢!这个函数是plotting函数的一部分,后来我一直坚持使用ggplot中的quosures。在当前版本中,aes
不支持quosures,但我发现ggplot有aes\u string
,它支持常规字符串作为参数而不是公式。
my_fun <- function(df, col_name, new_var_name=NULL) {
target <- enquo(col_name)
c <- df %>% pull(!!target) * 3 # here may be more complex calculations
# handling NULL name
if (missing(new_var_name)) {
new_name <- "default_name"
} else{
new_name <- quo_name(enquo(new_var_name))
}
data_frame(
abc = df %>% pull(!!target),
!!new_name := c
)
}
my_fun(dataframe, a)
my_fun(dataframe, a, NEW_NAME)
library(dplyr)
library(rlang)
f1 <- function(var = NULL) {
print(paste("substitute shows:", paste(substitute(var), collapse = " ")))
print(paste("missing returns:", missing(var)))
enquo_var <- enquo(var)
print(paste("after enquo:", quo_get_expr(enquo_var)))
print(paste("quo_is_null returns:", rlang::quo_is_null(enquo_var)))
rlang::quo_is_null(enquo_var)
}
f2 <- function(var = NULL) {
f1({{var}})
}
f1(Sepal.Length)
f1()
f2(Sepal.Length)
f2() # this is where `missing` fails.