R 测试对空参数使用enquo()的函数

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的函数,但在这个过程中会更改名称。我试图用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 # 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.