select和group_by之间关于引用变量的Dplyr差异?

时间:2017-08-14 15:56:57

标签: r dplyr

在当前版本的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))
  • 为什么selectgroup_by在按值传递参数方面有所不同?
  • 为什么第一个select来电有效,将来会继续有效吗?
  • 为什么第一个group_by电话无效?我试图弄清楚我应该使用quo()enquo()!!的组合来使其发挥作用。

我需要这个,因为我想创建一个将分组变量作为输入参数的函数,如果可能的话,分组变量应该作为字符串给出,因为其他两个函数参数已经作为字符串给出。

1 个答案:

答案 0 :(得分:3)

要将字符串作为符号或未评估的代码传递,您必须先将其解析为符号或quosure。您可以使用sym中的parse_exprrlang进行解析,然后使用!!取消引用:

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

symparse_expr之间的差异以及使用哪一个?

简短的回答:在这种情况下并不重要。

答案很长:

符号是一种引用R对象的方式,基本上是&#34; name&#34;一个对象。因此,sym类似于基础R中的as.nameparse_expr另一方面将某些文本转换为R表达式。这类似于基础R中的parse

表达式可以是任何 R代码,而不是只是引用R对象的代码。因此,您可以解析引用R对象的代码,但如果它引用的对象不存在,则无法将某些随机代码转换为sym

通常,当您的字符串引用某个对象时,您将使用sym(尽管parse_expr也可以使用),并在您尝试解析时使用parse_expr 其他R代码供进一步评估。

对于这个特定的用例,variable应该引用一个对象,因此将其转换为sym会起作用。另一方面,将其解析为表达式也会起作用,因为这是代码,当被group_by取消引用时将在!!内进行评估。