Using tidyeval with purrr - unquoting inside .f

purrr
tidyeval

#1

Hello all,

I have a situation that I’m a little confused about. I think if I could understand the contrived situation below, then I could figure out my issue.

Essentially, when I use map(x, function(x) { !!x }) with tidyeval I get the result that I expect. When I try to use the purrr shortcut, i.e., map(x, ~ { !!. }) I get an error. I don’t understand why. If anybody has insight that they care to share, I would really appreciate it!

A reprex is below:


library(tidyverse)
#> ── Attaching packages ─────────────────────────────────────────────────────────────────── tidyverse 1.2.1 ──
#> ✔ ggplot2 2.2.1     ✔ purrr   0.2.4
#> ✔ tibble  1.3.4     ✔ dplyr   0.7.4
#> ✔ tidyr   0.7.2     ✔ stringr 1.2.0
#> ✔ readr   1.1.1     ✔ forcats 0.2.0
#> ── Conflicts ────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
#> ✖ dplyr::filter() masks stats::filter()
#> ✖ dplyr::lag()    masks stats::lag()

data(mtcars)
               
vars <- quos(am, vs)

# This works as expected:

map_df(vars, function(x){
  mtcars %>%
    group_by(!!x) %>%
    summarise(mean(mpg))
})
#> # A tibble: 4 x 3
#>      am `mean(mpg)`    vs
#>   <dbl>       <dbl> <dbl>
#> 1     0    17.14737    NA
#> 2     1    24.39231    NA
#> 3    NA    16.61667     0
#> 4    NA    24.55714     1

# I'm not sure why this doesn't work:

purrr::map_df(vars, ~{
  mtcars %>%
    group_by(!! .) %>%
    summarise(mean(mpg))
})
#> Error in mutate_impl(.data, dots): Column `structure(list(mpg = c(21, 21, 22.8, 21.4, 18.7, 18.1, 14.3, 
#> 24.4, 22.8, 19.2, 17.8, 16.4, 17.3, 15.2, 10.4, 10.4, 14.7, 32.4, 
#> 30.4, 33.9, 21.5, 15.5, 15.2, 13.3, 19.2, 27.3, 26, 30.4, 15.8, 
#> 19.7, 15, 21.4), cyl = c(6, 6, 4, 6, 8, 6, 8, 4, 4, 6, 6, 8, 
#> 8, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 4, 4, 4, 8, 6, 8, 4), 
#>     disp = c(160, 160, 108, 258, 360, 225, 360, 146.7, 140.8, 
#>     167.6, 167.6, 275.8, 275.8, 275.8, 472, 460, 440, 78.7, 75.7, 
#>     71.1, 120.1, 318, 304, 350, 400, 79, 120.3, 95.1, 351, 145, 
#>     301, 121), hp = c(110, 110, 93, 110, 175, 105, 245, 62, 95, 
#>     123, 123, 180, 180, 180, 205, 215, 230, 66, 52, 65, 97, 150, 
#>     150, 245, 175, 66, 91, 113, 264, 175, 335, 109), drat = c(3.9, 
#>     3.9, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92, 3.92, 
#>     3.07, 3.07, 3.07, 2.93, 3, 3.23, 4.08, 4.93, 4.22, 3.7, 2.76, 
#>     3.15, 3.73, 3.08, 4.08, 4.43, 3.77, 4.22, 3.62, 3.54, 4.11
#>     ), wt = c(2.62, 2.875, 2.32, 3.215, 3.44, 3.46, 3.57, 3.19, 
#>     3.15, 3.44, 3.44, 4.07, 3.73, 3.78, 5.25, 5.424, 5.345, 2.2, 
#>     1.615, 1.835, 2.465, 3.52, 3.435, 3.84, 3.845, 1.935, 2.14, 
#>     1.513, 3.17, 2.77, 3.57, 2.78), qsec = c(16.46, 17.02, 18.61, 
#>     19.44, 17.02, 20.22, 15.84, 20, 22.9, 18.3, 18.9, 17.4, 17.6, 
#>     18, 17.98, 17.82, 17.42, 19.47, 18.52, 19.9, 20.01, 16.87, 
#>     17.3, 15.41, 17.05, 18.9, 16.7, 16.9, 14.5, 15.5, 14.6, 18.6
#>     ), vs = c(0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 
#>     0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1), am = c(1, 
#>     1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
#>     0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1), gear = c(4, 4, 4, 3, 
#>     3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 
#>     3, 3, 4, 5, 5, 5, 5, 5, 4), carb = c(4, 4, 1, 1, 2, 1, 4, 
#>     2, 2, 4, 4, 3, 3, 3, 4, 4, 4, 1, 2, 1, 1, 2, 2, 4, 2, 1, 
#>     2, 2, 4, 6, 8, 2)), .Names = c("mpg", "cyl", "disp", "hp", 
#> "drat", "wt", "qsec", "vs", "am", "gear", "carb"), row.names = c("Mazda RX4", 
#> "Mazda RX4 Wag", "Datsun 710", "Hornet 4 Drive", "Hornet Sportabout", 
#> "Valiant", "Duster 360", "Merc 240D", "Merc 230", "Merc 280", 
#> "Merc 280C", "Merc 450SE", "Merc 450SL", "Merc 450SLC", "Cadillac Fleetwood", 
#> "Lincoln Continental", "Chrysler Imperial", "Fiat 128", "Honda Civic", 
#> "Toyota Corolla", "Toyota Corona", "Dodge Challenger", "AMC Javelin", 
#> "Camaro Z28", "Pontiac Firebird", "Fiat X1-9", "Porsche 914-2", 
#> "Lotus Europa", "Ford Pantera L", "Ferrari Dino", "Maserati Bora", 
#> "Volvo 142E"), class = "data.frame")` must be length 32 (the number of rows) or one, not 11

#2

Hi @brad.cannell,

You’re almost there, just need to add an x to get it to work:

purrr::map_df(vars, ~{
  mtcars %>%
    group_by(!! .x) %>%
    summarise(mean(mpg))
})

#3

Hi @edgararuiz,

Of course it’s something that simple! I appreciate your help!

Brad


#4

HI @brad.cannell,

If your question’s been answered/has a solution (sounds like Edgar covered this one), would you mind marking the solution post? That way, it’s easier for someone in the future to come along and see what worked for you!

If you’re the OP (as you were in this case), there should be a little box at the bottom of replies that you can click on to select the answer as your “solution” (example from one of my questions, below)

Thanks!

Mara


Joining columns of two data frames column-wise
RStudio server and Shiny server
#5

Hi @mara,

Sorry! I thought I clicked it earlier. Thanks for the reminder!

Brad


#6

No problem at all. A lot of people don’t know that the option is there/how to do it. So, definitely intended as a friendly reminder! :+1: