Search code examples
rlazy-evaluationevaluationrlangtidyeval

Converting a vector of symbols to input for `...`


I have an R function where I want to turn a vector of symbols (c(a, b)) into input for ... (e.g. a, b).

# create data
set.seed(1)
data <- dplyr::tibble(a = sample(1:5, size = 10, replace = TRUE),
                      b = sample(1:5, size = 10, replace = TRUE))

The function should look like the following:

f <- function(category) {
  # trying to work out
}
f(category = c(a,b))

and give the result:

data |>
  tidyr::expand(tidyr::nesting(a, b))

The difficulty is that my function supplies the inputs as a vector of symbols whereas rlang::nesting takes input as ....

How can I convert from one format to the other? Or should I use another function than rlang::nesting?


Solution

  • Interfaces where you supply a set of variables through c() should be based on tidyselect. The easiest way is to use select().

    First take a selection then splice in the data:

    f <- function(data, category) {
      sel <- dplyr::select(data, {{ category }})
      tidyr::expand(data, tidyr::nesting(!!!sel))
    }
    
    f(data, category = c(a, b))
    #> # A tibble: 8 × 2
    #>       a     b
    #>   <int> <int>
    #> 1     1     2
    #> 2     1     5
    #> 3     2     2
    #> 4     2     5
    #> 5     3     1
    #> 6     3     5
    #> 7     4     5
    

    Because you're interfacing through select() you gain all tidyselect features:

    f(data, category = starts_with(c("a", "b")))