0

使用R 3.2.2dplyr 0.7.2我试图弄清楚如何有效地使用group_by作为字符向量提供的字段。

选择很容易我可以像这样通过字符串选择一个字段

(function(field) { 
  mpg %>% dplyr::select(field) 
})("cyl")

像这样通过多个字符串的多个字段

(function(...) { 
  mpg %>% dplyr::select(!!!quos(...)) 
})("cyl", "hwy")

和多个字段通过一个长度 > 1 的字符向量,像这样

(function(fields) {  
  mpg %>% dplyr::select(fields)  
})(c("cyl", "hwy"))

由于group_by我无法真正找到一种方法来为多个字符串执行此操作,因为如果我设法获得输出,它最终会按我提供的字符串进行分组。

我设法像这样按一个字符串分组

(function(field) {  
  mpg %>% group_by(!!field := .data[[field]]) %>% tally() 
})("cyl")

这已经很丑陋了。

有谁知道我必须写什么才能运行

(function(field) {...})("cyl", "hwy")

(function(field) {...})(c("cyl", "hwy"))

分别?!!我尝试了, !!!, UQ, enquo, quos,等的各种组合unlist......并将它们保存在中间变量中,因为这有时似乎有所作为,但无法让它发挥作用。

4

1 回答 1

5

select()在 dplyr 中非常特别。它不接受,但列位置。这就是唯一接受字符串的主要动词。(从技术上讲,当您提供像cylselect 这样的裸名称时,它实际上会被评估为自己的名称,而不是数据框中的向量。)

如果您希望您的函数采用简单的字符串,而不是简单的表达式或符号,则不需要引号。只需从字符串创建符号并取消引用它们:

myselect <- function(...) {
  syms <- syms(list(...))
  select(mtcars, !!! syms)
}
mygroup <- function(...) {
  syms <- syms(list(...))
  group_by(mtcars, !!! syms)
}

myselect("cyl", "disp")
mygroup("cyl", "disp")

要调试取消引用,请使用expr()并检查表达式是否正确:

syms <- syms(list("cyl", "disp"))
expr(group_by(mtcars, !!! syms))
#> group_by(mtcars, cyl, disp)    # yup, looks right!

有关更多信息,请参阅此演讲(我们将更新编程小插图以使概念更清晰):https ://schd.ws/hosted_files/user2017/43/tidyeval-user.pdf 。

最后,请注意,许多动词都有一个_at后缀变体,可以毫不费力地接受字符串和字符向量:

group_by_at(mtcars, c("cyl", "disp"))
于 2017-07-26T16:57:50.180 回答