如何将使用enquo()创建的动态变量名传递给dplyr的mutate以进行评估?

5

我正在创建一个工作流程,其中包含重命名、按条件选择和使用我在管道之前提供的名称进行突变的相同操作步骤。

我已经成功使用 enquo()!! (bang bang) 将列重命名为我想要的字符串,然后再次选择它,但是当我到达突变步骤时,它要么将文本字符串重复为列值,要么无法评估。

我在下面重新创建了代码:

#Testing rename, select, and mutate use cases for enquo()

#Load packages
library(dplyr)
library(rlang)
library(magrittr)

#Create name I want to pass
new_var <- quo("new_name")

#Create Test Data
t1 <- tibble(Year = c(2000:2004),
             old_name = c(NA, 1, 1, 1, NA))

我可以使用quo_name():=来重命名列。

t1 %>% 
  rename( !! quo_name(new_var) := old_name)

我可以使用!!来进行选择。
t1 %>% 
  rename( !! quo_name(new_var) := old_name) %>% 
  select(Year, !!new_var)

但是我不能在mutate中调用那列并使用值。

t1 %>% 
  rename( !! quo_name(new_var) := old_name) %>% 
  select(Year, !!new_var) %>% 
  mutate(test_var = (!! new_var))
2个回答

6
'new_var'对象是一个字符串的quosure。提取字符串,将其转换为符号,然后进行评估。
t1 %>% 
   rename( !! quo_name(new_var) := old_name) %>% 
   select(Year, !!new_var) %>% 
   mutate(testvar = !! rlang::sym(rlang::quo_name(new_var)))
# A tibble: 5 x 3
#   Year new_name testvar
#  <int>    <dbl>   <dbl>
#1  2000       NA      NA
#2  2001        1       1
#3  2002        1       1
#4  2003        1       1
#5  2004       NA      NA

此外,如果我们从未加引号的形式开始处理quosure中的new_var,那么OP的代码就能够正常工作。
new_var = quo(new_name)
t1 %>% 
     rename(!! new_var := old_name) %>% 
     select(Year, !!new_var) %>% 
     mutate(testvar = !! new_var)
# A tibble: 5 x 3
#   Year new_name testvar
#  <int>    <dbl>   <dbl>
#1  2000       NA      NA
#2  2001        1       1
#3  2002        1       1
#4  2003        1       1
#5  2004       NA      NA

1
这也可以运行,并保留了我的原始“new_var <- enquo("new_name")”代码。 - Adam Kemberling

2
尝试将第一行替换为:

new_var <- sym("new_name")

在这种情况下,您现有的代码应该可以运行,但您也可以简化它,例如:

t1 %>% 
  rename( !! new_var := old_name) %>% 
  select(Year, !! new_var) %>% 
  mutate(test_var = (!! new_var))

不客气!如果答案有帮助的话,考虑接受/点赞它。 - arg0naut91

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接