编程时如何使用dplyr::group_by与多个组

How to use dplyr::group_by with multiple groups when programming

好吧,这是以前工作的代码突然中断的那些日子之一。这是相关代码的代表:

test = data.frame(factor1 = sample(1:5, 10, replace=T),
                  factor2 = sample(letters[1:5], 10, replace=T),
                  variable = sample(100:200, 10))

group_vars = c('factor1','factor2') %>% paste(., collapse = ',')

> test %>% dplyr::group_by_(group_vars)
Error in parse(text = x) : <text>:1:8: unexpected ','
1: factor1,
           ^

现在我发誓这一直有效到今天。当然,dplyr 无论如何都在尝试取消 'x_' 函数,但我尝试将我能想到的所有内容插入 group_by()- 使用 !!、!!!、sym 的组合(), quo(), enquo() 等,想不通。我试过不将列名粘贴在一起,充其量只是采用第一个并忽略其他所有内容。我最常收到以下错误消息:

Error: Column <chr> must be length 10 (the number of rows) or one, not 2

我还阅读了 Hadley 的 dplyr 编程指南 (https://dplyr.tidyverse.org/articles/programming.html),该指南似乎涵盖了这个问题,只是我在内部生成列名并且不接受它们作为函数的参数。有没有人遇到过这个问题或者理解引用足以知道解决这个问题的方法?

此外,需要说明的是,这在仅使用单个分组变量时有效。问题在于多个组。

谢谢!

我们可以直接使用 group_by_at[=23 中的向量,而不是 pasteing 和使用 group_by_(已弃用 - 但它不会工作,因为它需要 NSE) =]

library(dplyr)
group_vars <- c('factor1','factor2')
test %>%
     group_by_at(group_vars)
# A tibble: 10 x 3
# Groups:   factor1, factor2 [10]
#   factor1 factor2 variable
#     <int> <fct>      <int>
# 1       1 d            145
# 2       5 e            119
# 3       4 a            181
# 4       3 e            155
# 5       3 d            164
# 6       3 b            135
# 7       4 e            137
# 8       4 d            197
# 9       2 d            142
#10       2 c            110

或者另一种选择是将 symsrlang 转换为符号并在 group_by

内计算 (!!!)
test %>%
      group_by(!!! rlang::syms(group_vars))

如果我们按照paste的路线走,那么一个选项是parse_expr(来自rlang

group_vars = c('factor1','factor2') %>% paste(., collapse = ';')
test %>%
      group_by(!!! rlang::parse_exprs(group_vars))
# A tibble: 10 x 3
# Groups:   factor1, factor2 [10]
#   factor1 factor2 variable
#     <int> <fct>      <int>
# 1       1 d            145
# 2       5 e            119
# 3       4 a            181
# 4       3 e            155
# 5       3 d            164
# 6       3 b            135
# 7       4 e            137
# 8       4 d            197
# 9       2 d            142
#10       2 c            110