Trying to exclude
- multiple columns in a call to
tidyr::gather()
- which are served as inputs to my function via a character vector argument (output of
shiny::selectInput
) instead of via...
- in a programmatic way
How would I do that with tidy eval functionality?
Since I pass multiple column names via a single function argument, I thought I needed to use !!!
(unquote-splicing) instead of !!
as layed out in Programming with dplyr. But that doesn't seem to play nicely with tidyselect::vars_select()
and it seems that the -
is causing the trouble.
This is the basic thing I'd like to do:
library(magrittr)
gather_data_1 <- function(dat, ...) {
dat %>% tidyr::gather("key", "value", ...)
}
mtcars %>% gather_data_1(-mpg, -cyl) %>% head()
#> mpg cyl key value
#> 1 21.0 6 disp 160
#> 2 21.0 6 disp 160
#> 3 22.8 4 disp 108
#> 4 21.4 6 disp 258
#> 5 18.7 8 disp 360
#> 6 18.1 6 disp 225
But I would like to pass the column names via a single argument (as in the shiny app it will be served via input$<select_input_id>
as well):
gather_data_2 <- function(dat, exclude) {
exclude <- rlang::syms(exclude)
dat %>% tidyr::gather("key", "value", -!!!exclude)
}
mtcars %>% gather_data_2(exclude = c("mpg", "cyl"))
#> Error: Can't use `!!!` at top level
Then I tried to see if -
is the problem:
gather_data_3 <- function(dat, exclude) {
exclude <- rlang::syms(exclude)
dat %>% tidyr::gather("key", "value", !!!exclude)
}
mtcars %>% gather_data_3(exclude = c("mpg", "cyl")) %>% head()
#> disp hp drat wt qsec vs am gear carb key value
#> 1 160 110 3.90 2.620 16.46 0 1 4 4 mpg 21.0
#> 2 160 110 3.90 2.875 17.02 0 1 4 4 mpg 21.0
#> 3 108 93 3.85 2.320 18.61 1 1 4 1 mpg 22.8
#> 4 258 110 3.08 3.215 19.44 1 0 3 1 mpg 21.4
#> 5 360 175 3.15 3.440 17.02 0 0 3 2 mpg 18.7
#> 6 225 105 2.76 3.460 20.22 1 0 3 1 mpg 18.1
That seems to work.
Then I tried to get the -
into the actual symbol names, but that doesn't work (at least the way I tried it ;-)):
gather_data_4 <- function(dat, exclude) {
exclude <- rlang::syms(sprintf("-%s", exclude))
dat %>% tidyr::gather("key", "value", !!!exclude)
}
mtcars %>% gather_data_4(exclude = c("mpg", "cyl"))
#> Error in .f(.x[[i]], ...): object '-mpg' not found
[1]: https://dplyr.tidyverse.org/articles/programming.html#unquote-splicing
EDIT
With the help from Lionel I was able to piece it together:
gather_data_6 <- function(dat, exclude) {
dat %>% tidyr::gather("key", "value", -c(rlang::UQS(exclude)))
}
mtcars %>% gather_data_6(exclude = c("mpg", "cyl")) %>% head()
#> mpg cyl key value
#> 1 21.0 6 disp 160
#> 2 21.0 6 disp 160
#> 3 22.8 4 disp 108
#> 4 21.4 6 disp 258
#> 5 18.7 8 disp 360
#> 6 18.1 6 disp 225
Even simplified:
gather_data_7 <- function(dat, exclude) {
dat %>% tidyr::gather("key", "value", -c(!!!exclude))
}
mtcars %>% gather_data_7(exclude = c("mpg", "cyl")) %>% head()
#> mpg cyl key value
#> 1 21.0 6 disp 160
#> 2 21.0 6 disp 160
#> 3 22.8 4 disp 108
#> 4 21.4 6 disp 258
#> 5 18.7 8 disp 360
#> 6 18.1 6 disp 225
Created on 2018-04-26 by the reprex package (v0.2.0).