Reputation: 1074
Sorry for the numerous prepositions in the title. Similar to this question, I have a list of quosures/arguments I want to pass to a function like dplyr::count
:
library(rlang)
suppressPackageStartupMessages(library(dplyr))
q_list <- function(...) {
enquos(...)
}
my_q_list <- q_list(
c(cyl, sort = TRUE),
c(cyl, gear, sort = TRUE)
)
my_q_list
#> <list_of<quosure>>
#>
#> [[1]]
#> <quosure>
#> expr: ^c(cyl, sort = TRUE)
#> env: global
#>
#> [[2]]
#> <quosure>
#> expr: ^c(cyl, gear, sort = TRUE)
#> env: global
Created on 2020-09-02 by the reprex package (v0.3.0.9001)
Using purrr and rlang, how do I pass and execute each quosure of this list to count(mtcars, ...)
So the end result is identical to:
suppressPackageStartupMessages(library(dplyr))
count(mtcars, cyl, sort = TRUE)
#> cyl n
#> 1 8 14
#> 2 4 11
#> 3 6 7
count(mtcars, cyl, gear, sort = TRUE)
#> cyl gear n
#> 1 8 3 12
#> 2 4 4 8
#> 3 6 4 4
#> 4 4 5 2
#> 5 6 3 2
#> 6 8 5 2
#> 7 4 3 1
#> 8 6 5 1
Created on 2020-09-02 by the reprex package (v0.3.0.9001)
Upvotes: 0
Views: 305
Reputation: 206167
The thing that makes this difficult is the use of c()
here. We really need some sort of rlang
object to hold your parameters. Here's an altered function to generate your list
q_list <- function(...) {
q <- enexprs(...)
transenv <- new_environment(list(c=exprs))
purrr::map(q, function(x) {
eval_tidy(x, env = transenv)
})
}
This takes your expressions and evaulates them treating c()
like enexprs()
. Then you can inject those values into your function call
my_q_list <- q_list(
c(cyl, sort = TRUE),
c(cyl, gear, sort = TRUE)
)
purrr::map(my_q_list, ~eval_tidy(quo(count(mtcars, !!!.x))))
This would have been easier if you just make the expressions in a list without using c()
my_q_list <- list(
exprs(cyl, sort = TRUE),
exprs(cyl, gear, sort = TRUE)
)
purrr::map(my_q_list, ~eval_tidy(quo(count(mtcars, !!!.x))))
Upvotes: 2
Reputation: 886928
The sort
can be outside
library(purrr)
list(q_list(cyl), q_list(cyl, gear)) %>%
map(~ count(mtcars, !!! .x, sort = TRUE))
#[[1]]
# cyl n
#1 8 14
#2 4 11
3 6 7
#[[2]]
# cyl gear n
#1 8 3 12
#2 4 4 8
#3 6 4 4
#4 4 5 2
#5 6 3 2
#6 8 5 2
#7 4 3 1
#8 6 5 1
Upvotes: 2