r - 测试使用 enquo() 作为 NULL 参数的函数

标签 r dplyr

我有一个创建数据框的函数,但在此过程中更改了名称。我正在尝试使用 dplyr quosures 处理空列名。我的测试套件如下所示:

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

如果我尝试传递名称,则会出现错误:
my_fun(dataframe, a, NEW_NAME)
Error in my_fun(dataframe, a, NEW_NAME) : object 'NEW_NAME' not found

我哪里错了?

最佳答案

这个问题实际上与 quo 无关。和 enquo返回不同的东西,这真的是关于在你真正想要之前评估对象。如果您要使用 browser()要逐步执行您的函数,您会看到错误发生在 if (is.null(new_var_name))陈述。

当您这样做时is.null(new_var_name) ,您正在评估作为 new_var_name 传递的变量所以现在为时已晚 enquo它。那是因为 is.null需要查看变量的值而不仅仅是变量名称本身。

一个不计算传递给函数的参数但检查它是否存在的函数 missing() .

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)

关于r - 测试使用 enquo() 作为 NULL 参数的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48504942/

相关文章:

使用 dplyr/tidyverse 删除基于多列的重复行?

r - 基于 R 中的其他列创建列序列

r - 崩溃R包: rearraning or reposition columns in custom order

r - R 是否有像 python 中那样的断言语句?

r - 从文档中隐藏 'internal' 数据集(R CMD 检查)

r - 传播多列 [tidyr]

r - 在函数中获取过滤器以进行整洁的评估

r - 基于第二列增加列

r - 计算 data.table 中的 `by` 子句

r - 如何按组计算相关性