【问题标题】:Why does group_by_at() with a string vector fail when inside a function?为什么在函数内部时带有字符串向量的 group_by_at() 会失败?
【发布时间】:2019-12-25 01:21:26
【问题描述】:

我有一个工作流程,其中我将表示列名的字符串向量提供给在这些列上使用 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 年开始)。

【问题讨论】:

    标签: r dplyr rlang


    【解决方案1】:

    条件不正确

    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
    

    【讨论】:

    • 因此,由于解决方案(顺便感谢一下)与问题的标题和设置几乎无关,因此保持原样是否有益?
    • @adamkemberling 您可以保留它,因为该解决方案提供了多种解决方法。这将有助于澄清一些概念
    猜你喜欢
    • 2021-06-23
    • 2012-02-01
    • 1970-01-01
    • 2023-03-21
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    相关资源
    最近更新 更多