在当前版本的dplyr中,select
参数可以通过值传递:
variable <- "Species"
iris %>%
select(variable)
# Species
#1 setosa
#2 setosa
#3 setosa
#4 setosa
#5 setosa
#6 setosa
#...
但group_by
参数不能通过值传递:
iris %>%
group_by(variable) %>%
summarise(Petal.Length = mean(Petal.Length))
# Error in grouped_df_impl(data, unname(vars), drop) :
# Column `variable` is unknown
documented dplyr::select behaviour是
iris %>% select(Species)
记录的documented dplyr::group_by behaviour是
iris %>%
group_by(Species) %>%
summarise(Petal.Length = mean(Petal.Length))
select
和group_by
在按值传递参数方面有所不同?select
来电有效,将来会继续有效吗?group_by
电话无效?我试图弄清楚我应该使用quo()
,enquo()
和!!
的组合来使其发挥作用。我需要这个,因为我想创建一个将分组变量作为输入参数的函数,如果可能的话,分组变量应该作为字符串给出,因为其他两个函数参数已经作为字符串给出。
答案 0 :(得分:3)
要将字符串作为符号或未评估的代码传递,您必须先将其解析为符号或quosure。您可以使用sym
中的parse_expr
或rlang
进行解析,然后使用!!
取消引用:
library(dplyr)
variable <- rlang::sym("Species")
# variable <- rlang::parse_expr("Species")
iris %>%
group_by(!! variable) %>%
summarise(Petal.Length = mean(Petal.Length))
!!
是UQ()
的快捷方式,它取消引用表达式或符号。这允许variable
仅在其被调用的范围内进行评估,即group_by
。
sym
和parse_expr
之间的差异以及使用哪一个?
简短的回答:在这种情况下并不重要。
答案很长:
符号是一种引用R对象的方式,基本上是&#34; name&#34;一个对象。因此,sym
类似于基础R中的as.name
。parse_expr
另一方面将某些文本转换为R表达式。这类似于基础R中的parse
。
表达式可以是任何 R代码,而不是只是引用R对象的代码。因此,您可以解析引用R对象的代码,但如果它引用的对象不存在,则无法将某些随机代码转换为sym
。
通常,当您的字符串引用某个对象时,您将使用sym
(尽管parse_expr
也可以使用),并在您尝试解析时使用parse_expr
其他R代码供进一步评估。
对于这个特定的用例,variable
应该引用一个对象,因此将其转换为sym
会起作用。另一方面,将其解析为表达式也会起作用,因为这是代码,当被group_by
取消引用时将在!!
内进行评估。