How to pass multiple group_by arguments and a dynamic variable argument to a dplyr function

后端 未结 1 1627
执念已碎
执念已碎 2021-01-16 01:53

I am trying to pass multiple group_by arguments to a dplyr function as well as a named variable. In understand that I need to use a quosure for dplyr to understand the vari

相关标签:
1条回答
  • 2021-01-16 02:13

    You haven't provided sample data, but your function works when modified to use the mtcars data frame.

    library(tidyverse)
    library(formattable)
    
    quantileMaker3 <- function(data, calcCol, ...) {
      groupCol <- quos(...)
      calcCol <- enquo(calcCol)
    
      data %>%
        group_by(!!!groupCol) %>%
        summarise('25%' = currency(quantile(!!calcCol, probs = 0.25), digits = 2L),
                  '50%' = currency(quantile(!!calcCol, probs = 0.50), digits = 2L),
                  '75%' = currency(quantile(!!calcCol, probs = 0.75), digits = 2L),
                  avg = currency(mean(!!calcCol), digits = 2L),
                  nAgencies = n_distinct(cyl), 
                  nFTEs = sum(hp)
        )
    }
    
    quantileMaker3(mtcars, mpg, cyl)
    
    # A tibble: 3 x 7
        cyl `25%`             `50%`             `75%`             avg               nAgencies nFTEs
      <dbl> <S3: formattable> <S3: formattable> <S3: formattable> <S3: formattable>     <int> <dbl>
    1    4. $22.80            $26.00            $30.40            $26.66                    1  909.
    2    6. $18.65            $19.70            $21.00            $19.74                    1  856.
    3    8. $14.40            $15.20            $16.25            $15.10                    1 2929.
    

    With multiple grouping arguments:

    quantileMaker3(mtcars, mpg, cyl, vs)
    
    # A tibble: 5 x 8
    # Groups:   cyl [?]
        cyl    vs `25%`             `50%`             `75%`             avg               nAgencies nFTEs
      <dbl> <dbl> <S3: formattable> <S3: formattable> <S3: formattable> <S3: formattable>     <int> <dbl>
    1    4.    0. $26.00            $26.00            $26.00            $26.00                    1   91.
    2    4.    1. $22.80            $25.85            $30.40            $26.73                    1  818.
    3    6.    0. $20.35            $21.00            $21.00            $20.57                    1  395.
    4    6.    1. $18.03            $18.65            $19.75            $19.12                    1  461.
    5    8.    0. $14.40            $15.20            $16.25            $15.10                    1 2929.
    

    Incidentally, you can avoid multiple calls to quantile by using nesting. This won't work if any of the output columns are of class formattable (which is what the currency function returns), so I've changed the function to create strings for the currency-format columns.

    quantileMaker3 <- function(data, calcCol, ..., quantiles=c(0.25,0.5,0.75)) {
    
      groupCol <- quos(...)
      calcCol <- enquo(calcCol)
    
      data %>%
        group_by(!!!groupCol) %>%
        summarise(values = list(paste0("$", sprintf("%1.2f", quantile(!!calcCol, probs=quantiles)))),
                  qnames = list(sprintf("%1.0f%%", quantiles*100)),
                  nAgencies = n_distinct(cyl), 
                  nFTEs = sum(hp),
                  avg = paste0("$", sprintf("%1.2f", mean(!!calcCol)))
        ) %>% 
        unnest %>% 
        spread(qnames, values) 
    }
    
    quantileMaker3(mtcars, mpg, cyl, vs)
    
    # A tibble: 5 x 8
    # Groups:   cyl [3]
        cyl    vs nAgencies nFTEs avg    `25%`  `50%`  `75%` 
      <dbl> <dbl>     <int> <dbl> <chr>  <chr>  <chr>  <chr> 
    1    4.    0.         1   91. $26.00 $26.00 $26.00 $26.00
    2    4.    1.         1  818. $26.73 $22.80 $25.85 $30.40
    3    6.    0.         1  395. $20.57 $20.35 $21.00 $21.00
    4    6.    1.         1  461. $19.12 $18.03 $18.65 $19.75
    5    8.    0.         1 2929. $15.10 $14.40 $15.20 $16.25
    
    0 讨论(0)
提交回复
热议问题