0

I want to create a function where the first input of create_df gets turned into the number 1 using tidyeval. Here it should be only the cyl column.

How do I pull the first "input" of ...?

  library(dplyr, quietly = T)

create_df <- function(...){
  
  var <- enquos(...)
  first <- as_label(quos(...))
  
  mtcars %>% 
    group_by(!!!var) %>% 
    summarise(mean = mean(mpg)) %>% 
    mutate(!!first := 1)
}

create_df(cyl, am)
#> `summarise()` regrouping output by 'cyl' (override with `.groups` argument)
#> # A tibble: 6 x 4
#> # Groups:   cyl [3]
#>     cyl    am  mean `<quos>`
#>   <dbl> <dbl> <dbl>    <dbl>
#> 1     4     0  22.9        1
#> 2     4     1  28.1        1
#> 3     6     0  19.1        1
#> 4     6     1  20.6        1
#> 5     8     0  15.0        1
#> 6     8     1  15.4        1

Created on 2020-07-01 by the reprex package (v0.3.0)

John-Henry
  • 1,556
  • 8
  • 20

1 Answers1

3

You can pull the first variable out of the dots by simply taking the first element out of vars (with credit to Lionel Henry for pointing this out).

create_df <- function(...){
  
  var <- enquos(...)
  first <- as_label(var[[1]])
  
  mtcars %>% 
    group_by(!!!var) %>% 
    summarise(mean = mean(mpg)) %>% 
    mutate(!!first := 1)
}

create_df(cyl, am)
#> `summarise()` regrouping output by 'cyl' (override with `.groups` argument)
#> # A tibble: 6 x 3
#> # Groups:   cyl [1]
#>     cyl    am  mean
#>   <dbl> <dbl> <dbl>
#> 1     1     0  22.9
#> 2     1     1  28.1
#> 3     1     0  19.1
#> 4     1     1  20.6
#> 5     1     0  15.0
#> 6     1     1  15.4
Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • 2
    `list2()` doesn't do anything here. And `quos(...)` is exactly the same as `enquos(...)` (the behaviour is the same for dots, it only differs for other arguments). So you can simplify your code with: `first <- as_label(var[[1]])` – Lionel Henry Jul 01 '20 at 16:18
  • 2
    Thank you for pointing this out @LionelHenry - I have updated, with credit to your good self! – Allan Cameron Jul 01 '20 at 16:24