how to create a sequence of name-value pairs that can be used as input, say, to expand_grid()

Suppose I have two vectors:

letters[1:2]
#> [1] "a" "b"
1:2
#> [1] 1 2

that I would like use as input to expand_grid(), which takes a comma-separated sequence of name-value pairs:

library(tidyverse)
expand_grid(let = letters[1:2],  num = 1:2)
#> # A tibble: 4 × 2
#>   let     num
#>   <chr> <int>
#> 1 a         1
#> 2 a         2
#> 3 b         1
#> 4 b         2

Created on 2025-06-04 with reprex v2.1.1

Or takes a comma-separated sequence of names of vectors:

let <- letters[1:2]
num <- 1:2

library(tidyverse)
expand_grid(let, num)
#> # A tibble: 4 × 2
#>   let     num
#>   <chr> <int>
#> 1 a         1
#> 2 a         2
#> 3 b         1
#> 4 b         2

Created on 2025-06-04 with reprex v2.1.1

Now suppose I have a third vector:

lgl <- c(T, F)

How could I create an object that is interpreted by expand_grid() as a sequence of two of the three vectors? For example, suppose I would like to create a similar table by randomly taking two of the three vectors and supplying them as input to expand_grid() without knowing which two vectors were chosen.

[This question is not about expand_grid() specifically, but about tidyverse functions that expect a sequence of name-value pairs or (data-masked) names of vectors. For example, here is the equivalent context for the expand() function:

library(tidyverse)
tibble(let = letters[1:2], num = 1:2) |> 
  expand(let, num)
#> # A tibble: 4 × 2
#>   let     num
#>   <chr> <int>
#> 1 a         1
#> 2 a         2
#> 3 b         1
#> 4 b         2

Created on 2025-06-04 with reprex v2.1.1
]

If I understand your question correctly, you can assemble your vectors in a list and use do.call():

library(tidyverse)

mylist <- list(
  let = letters[1:2],
  LET = LETTERS[1:2],
  num = 1:2
)
lgl <- c(TRUE, FALSE, TRUE)

stopifnot(length(lgl) == length(mylist))

do.call(expand_grid, mylist[lgl])
#> # A tibble: 4 × 2
#>   let     num
#>   <chr> <int>
#> 1 a         1
#> 2 a         2
#> 3 b         1
#> 4 b         2

Thank you, @AlexisW, you did understand me correctly, and your solution helped me find an equivalent tidyverse solution I had been hoping for: Your call to do.call() applies the expand_grid() function to a sequence of name-value pairs that are wrapped in a list; the !!! operator extracts the sequence from the list so that expand_grid() can be applied to it:

library(tidyverse)

my_list <- list('let' = letters[1:2], 'num' = 1:2)
expand_grid(!!!my_list)
#> # A tibble: 4 × 2
#>   let     num
#>   <chr> <int>
#> 1 a         1
#> 2 a         2
#> 3 b         1
#> 4 b         2

Created on 2025-06-04 with reprex v2.1.1

and there's a similar solution for expand() that uses syms():

library(tidyverse)
my_list <- syms(c('let', 'num'))
my_list
#> [[1]]
#> let
#> 
#> [[2]]
#> num

tibble(let = letters[1:2], num = 1:2) |> 
  expand(!!!my_list)
#> # A tibble: 4 × 2
#>   let     num
#>   <chr> <int>
#> 1 a         1
#> 2 a         2
#> 3 b         1
#> 4 b         2

Created on 2025-06-04 with reprex v2.1.1

1 Like