Search code examples
dplyrlazy-evaluationtidyeval

Using tidyeval's braces with a dplyr::group_by


I wanted to pass a vector of strings to purrr::map to generate a list of tables.

library(tidyverse)
library(magrittr)

names(mtcars) %>% 
  extract(8:10) %>% 
  map(
   function(i)

     mtcars %>% 
     group_by({{i}}) %>% 
     tally
   )

but this returns objects grouped on a character string, not the variable name.

This works

names(mtcars) %>% 
  extract(8:10) %>% 
  map(
    function(i)

      mtcars %>% 
      group_by(get(i)) %>% 
      tally
    )

but I was hoping for a solution with a more idiomatically tidy approach.


Solution

  • Use !!sym(i) instead. I don't fully understand why this works, but I guess you need to create a symbol from your string first and then have to quasi-quote it in order to be able to replace it with your placeholder in the function. If this makes sense.

    
    library(tidyverse)
    
    names(mtcars)[8:10] %>% 
      map(
        function(i)
    
          mtcars %>% 
          group_by(!!sym(i)) %>% 
          tally
      )
    #> [[1]]
    #> # A tibble: 2 x 2
    #>      vs     n
    #>   <dbl> <int>
    #> 1     0    18
    #> 2     1    14
    #> 
    #> [[2]]
    #> # A tibble: 2 x 2
    #>      am     n
    #>   <dbl> <int>
    #> 1     0    19
    #> 2     1    13
    #> 
    #> [[3]]
    #> # A tibble: 3 x 2
    #>    gear     n
    #>   <dbl> <int>
    #> 1     3    15
    #> 2     4    12
    #> 3     5     5
    

    Created on 2019-11-25 by the reprex package (v0.2.1)