【问题标题】:Dplyr difference between select and group_by with respect to quoted variables?在引用变量方面,select 和 group_by 之间的 Dplyr 区别?
【发布时间】:2018-01-22 12:36:24
【问题描述】:

在当前版本的 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()!! 的组合来使其工作。

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

【问题讨论】:

标签: r dplyr


【解决方案1】:

要将字符串作为符号或未评估的代码传递,您必须首先将其解析为符号或quosure。您可以使用symparse_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 对象的方式,基本上是对象的“名称”。所以sym 类似于基础 R 中的as.name。另一方面,parse_expr 将一些文本转换为 R 表达式。这类似于基础 R 中的parse

表达式可以是任何 R 代码,而不是只是 引用R 对象的代码。所以你可以解析引用R对象的代码,但是如果它引用的对象不存在,你就不能把一些随机代码变成sym

一般来说,当你的字符串引用一个对象时你会使用sym(虽然parse_expr也可以),当你试图解析任何其他R时使用parse_expr进一步评估的代码。

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

【讨论】:

  • 谢谢,使用rlang::sym!! 我可以将分组变量作为字符串传递。
  • 我花了一段时间才明白为什么!! 是必要的。 rlang vignette on tidy evaluation 给出了一个帮助我理解的示例:“[...]with quasiquotation:用户可以通过取消引用值来完全绕过符号计算。例如,以下表达式是完全等价的:# Take an expression: dplyr::mutate(mtcars, cyl2 = cyl * 2) #取值:var &lt;- mtcars$cyl * 2dplyr::mutate(mtcars, cyl2 = !! var)"。"
  • 感谢您的解释。你知道symparse_expr 的区别是什么吗?为什么我应该更喜欢其中一个?
  • @tmastny 添加了对两者区别的解释。希望这会有所帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-14
  • 1970-01-01
  • 1970-01-01
  • 2015-05-02
  • 1970-01-01
  • 1970-01-01
  • 2015-09-10
相关资源
最近更新 更多