Tidy Eval:不可能在嵌套函数中使用 {{var}} 吗?

Tidy Eval: Using {{var}} inside a nesting function not possible?

我试图在我的函数中使用 tidyr::complete,同时使用 {{}} 提供变量名。这很好用,但是,当我添加一个嵌套函数来组合两个变量时,我得到了一个错误。请参阅下面的最小示例。

library(tidyverse)
library(rlang)

df <- tibble(
  group1 = c(1:2, 1),
  group2 = c("c", "c", "c"),
  item_id = c(1:2, 2),
  item_name = c("a", "b", "b"),
  value1 = 1:3,
  value2 = 4:6
)

my_complete <- function(data, var1, var2, var3, var4, var5, var6){
  data %>%
    tidyr::complete({{var1}}, {{var3}})
}

my_complete(df, var1 = group1, var2 = group2, var3 = item_id, var4 = item_name, var5 = value1, var6 = value2)

这有效,输出是:

# A tibble: 4 x 6
  group1 item_id group2 item_name value1 value2
   <dbl>   <dbl> <chr>  <chr>      <int>  <int>
1      1       1 c      a              1      4
2      1       2 c      b              3      6
3      2       1 NA     NA            NA     NA
4      2       2 c      b              2      5

然而,当我将两个变量与嵌套结合起来时,我得到了一个错误。


my_complete_nesting <- function(data, var1, var2, var3, var4, var5, var6){
  data %>%
    tidyr::complete(nesting({{var1}}, {{var2}}), nesting({{var3}}, {{var4}}))
}

my_complete_nesting(df, var1 = group1, var2 = group2, var3 = item_id, var4 = item_name, var5 = value1, var6 = value2)
 Error in .f(.x[[i]], ...) : object 'group1' not found 

也许我遗漏了一些东西,但我无法让它工作。我以为我了解如何使用 {{}}。当我使用 variable <- enquo(variable)!!variable 的替代表达式时,我遇到了同样的问题。因此,不是 {{}} 导致了问题,而是我在这里使用 tidy eval 的方式。 我想获得以下输出:

df %>%
  tidyr::complete(nesting(group1, group2), nesting(item_id, item_name))

# A tibble: 4 x 6
  group1 group2 item_id item_name value1 value2
   <dbl> <chr>    <dbl> <chr>      <int>  <int>
1      1 c            1 a              1      4
2      1 c            2 b              3      6
3      2 c            1 a             NA     NA
4      2 c            2 b              2      5

我真的很感激能帮我解决这个问题。也许我只是遗漏了一些东西,但我似乎找不到问题所在。

谢谢!

这实际上是一个您不想使用quosures的例子。一个 quosure 捕获一个表达式以及应该计算它的上下文。在您的情况下,它捕获全局环境,其中 group1 未定义 。这就是当 nesting() 尝试解析表达式时出现“找不到对象”错误的原因。

因为您希望 group1 在数据框的上下文中进行评估(而不是在全局上下文中),所以此处使用的正确机制是 ensym():

my_complete_nesting <- function(data, var1, var2, var3, var4, var5, var6){
  data %>%
    tidyr::complete(nesting(!!ensym(var1), !!ensym(var2)), 
                    nesting(!!ensym(var3), !!ensym(var4)))

}

## Now works
my_complete_nesting(df, var1 = group1, var2 = group2, 
                    var3 = item_id, var4 = item_name, 
                    var5 = value1, var6 = value2)