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)
我试图在我的函数中使用 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)