【问题标题】:dplyr group_by - Mix variable names with and without surrounding quotesdplyr group_by - 混合带有和不带引号的变量名
【发布时间】:2021-08-01 22:38:32
【问题描述】:

我希望能够使用 dplyr 的 group_by 来按多列分组,很简单。但是,复杂的是我想创建一个函数,其中一个或多个列始终在分组依据中,并且用户可以选择另一列作为分组依据。到目前为止,我尝试过的方法包括使用始终在组中的列的非字符串规范,并为用户选择的列使用字符串,但我没有尝试过任何工作。这种组合在 SELECT 中似乎可以正常工作,但不能在 GROUP_BY 中正常工作。理想情况下,我宁愿不切换到所有字符串,因为我希望能够利用 dplyr 的一些功能,这些功能允许我选择一系列列。下面是一个例子。

举个简单的例子,我从 iris 数据集开始,并添加了几列,它们的确切含义并不重要。

test_tbl <- iris %>%
  mutate(extra_var1 = ifelse(Sepal.Length >= 5.0, "Yes", "No"),
         extra_var2 = "What")

这是一个对所有变量使用非字符串规范的示例,效果很好:

test_tbl %>%
  select(Species, extra_var1, Sepal.Length, Petal.Width) %>%
  group_by(Species, extra_var1) %>%
  summarize(average.Sepal.Length = mean(Sepal.Length),
            average.Petal.Width = mean(Petal.Width))

但是,我希望能够在一个函数中让用户指定他们是要按 extra_var1 还是 extra_var2 进行分组。这是我的尝试,它不起作用。同样,我相信 select 部分可以正常工作,但 group_by 部分不能。

group_and_summarize <- function(var) {
  test_tbl %>%
    select(Species, var, Sepal.Length, Petal.Width) %>%
    group_by(Species, var) %>%
    summarize(average.Sepal.Length = mean(Sepal.Length),
              average.Petal.Width = mean(Petal.Width))
}

group_and_summarize("extra_var1")

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    这是一种方法:

    library(dplyr)
    
    group_and_summarize <- function(var) {
      test_tbl %>%
        select(Species, {{var}}, Sepal.Length, Petal.Width) %>%
        group_by(Species, {{var}}) %>%
        summarize(average.Sepal.Length = mean(Sepal.Length),
                  average.Petal.Width = mean(Petal.Width))
    }
    
    group_and_summarize(extra_var1)
    #> `summarise()` regrouping output by 'Species' (override with `.groups` argument)
    #> # A tibble: 6 x 4
    #> # Groups:   Species [3]
    #>   Species    extra_var1 average.Sepal.Length average.Petal.Width
    #>   <fct>      <chr>                     <dbl>               <dbl>
    #> 1 setosa     No                         4.67               0.195
    #> 2 setosa     Yes                        5.23               0.28 
    #> 3 versicolor No                         4.9                1    
    #> 4 versicolor Yes                        5.96               1.33 
    #> 5 virginica  No                         4.9                1.7  
    #> 6 virginica  Yes                        6.62               2.03
    

    reprex package (v0.3.0) 于 2021-05-11 创建

    如果您希望用户输入字符串,那么我们可以使用!!! syms()

    group_and_summarize <- function(vars) {
      test_tbl %>%
        select(Species, !!! syms(vars), Sepal.Length, Petal.Width) %>%
        group_by(Species, !!! syms(vars)) %>%
        summarize(average.Sepal.Length = mean(Sepal.Length),
                  average.Petal.Width = mean(Petal.Width))
    }
    
    group_and_summarize(c("extra_var1", "extra_var2"))
    
    #> `summarise()` regrouping output by 'Species', 'extra_var1' (override with `.groups` argument)
    #> # A tibble: 6 x 5
    #> # Groups:   Species, extra_var1 [6]
    #>   Species    extra_var1 extra_var2 average.Sepal.Length average.Petal.Width
    #>   <fct>      <chr>      <chr>                     <dbl>               <dbl>
    #> 1 setosa     No         What                       4.67               0.195
    #> 2 setosa     Yes        What                       5.23               0.28 
    #> 3 versicolor No         What                       4.9                1    
    #> 4 versicolor Yes        What                       5.96               1.33 
    #> 5 virginica  No         What                       4.9                1.7  
    #> 6 virginica  Yes        What                       6.62               2.03
    

    reprex package (v0.3.0) 于 2021-05-11 创建

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-21
      • 2019-01-11
      • 2020-01-02
      • 1970-01-01
      • 1970-01-01
      • 2015-11-12
      相关资源
      最近更新 更多