为什么 group_by_at() 在函数内部时带有字符串向量会失败?

Why does group_by_at() with a string vector fail when inside a function?

我有一个工作流程,在该工作流程中,我将表示列名称的字符串向量提供给在这些列上使用 group_by 的函数。当我用一个列名测试它时它工作,但当我通过它的倍数时失败。

基本设置是这样的:

group_summs <- function(df, grouping_vars) {

  if(length(grouping_vars == 1)) {

    group_var <- ensym(grouping_vars)

    df %>%
      group_by(!! group_var) %>% 
      summarise(n_test = n())

  } else {

    group_vars <- grouping_vars

    df %>% 
      group_by_at(.vars = group_vars) %>% 
      summarise(n_test = n())

  }
}

#Single column test
flights <- nycflights13::flights
col_test <- c("origin")

#This Works
group_summs(flights, col_test)

#Multiple columns test
col_test_2 <- c("origin", "carrier")

#This fails
group_summs(flights, col_Test_2)

因此,作为测试,我可以传递单个列名并将其设为 运行,但是当我 运行 将其设为多个时,我会收到 rlang 错误。

”错误:只能将字符串转换为符号 调用 rlang::last_error() 查看回溯 调用自:rlang::abort(x)"

我真正不明白的是为什么多列示例 运行 正确地位于函数之外,如:

#Runs just fine
col_test_2 <- c("origin", "carrier")
flights %>% group_by_at(.vars = col_test_2) %>% summarise(n_test = n())

函数环境中是否有我不理解的地方,或者这是错误行为?

我正在使用 dplyr (0.8.3) 和 rlang (0.4.0)。

这个问题与 Group by multiple columns in dplyr, using string vector input 非常相似,但该问题的解决方案导致相同的错误,所以我想知道现在是否有更新的解决方案(他们当前的解决方案是 2017 年的)。

条件不正确

length(grouping_vars == 1)

应该是

length(grouping_vars) == 1

-完整代码

group_summs <- function(df, grouping_vars) {

  if(length(grouping_vars) == 1) {

    group_var <- ensym(grouping_vars)

    df %>%
      group_by(!! group_var) %>% 
      summarise(n_test = n())

  } else {

    group_vars <- grouping_vars

    df %>% 
      group_by_at(.vars = group_vars) %>% 
      summarise(n_test = n())

  }
}

group_summs(flights, col_test_2)
# A tibble: 35 x 3
# Groups:   origin [3]
#   origin carrier n_test
#   <chr>  <chr>    <int>
# 1 EWR    9E        1268
# 2 EWR    AA        3487
# 3 EWR    AS         714
# 4 EWR    B6        6557
# 5 EWR    DL        4342
# 6 EWR    EV       43939
# 7 EWR    MQ        2276
# 8 EWR    OO           6
# 9 EWR    UA       46087
#10 EWR    US        4405
# … with 25 more rows

group_summs(flights, col_test)
# A tibble: 3 x 2
#  origin n_test
#  <chr>   <int>
#1 EWR    120835
#2 JFK    111279
#3 LGA    104662

然而,这个条件根本不是必需的,因为 group_by_at 可以长度 >=1

group_summs2 <- function(df, grouping_vars) {


    group_vars <- grouping_vars

    df %>% 
      group_by_at(.vars = group_vars) %>% 
      summarise(n_test = n())


}



group_summs2(flights, col_test)
# A tibble: 3 x 2
#  origin n_test
#  <chr>   <int>
#1 EWR    120835
#2 JFK    111279
#3 LGA    104662

group_summs2(flights, col_test_2)
# A tibble: 35 x 3
# Groups:   origin [3]
#   origin carrier n_test
#   <chr>  <chr>    <int>
# 1 EWR    9E        1268
# 2 EWR    AA        3487
# 3 EWR    AS         714
# 4 EWR    B6        6557
# 5 EWR    DL        4342
# 6 EWR    EV       43939
# 7 EWR    MQ        2276
# 8 EWR    OO           6
# 9 EWR    UA       46087
#10 EWR    US        4405
# … with 25 more rows