将参数向量列表作为 quosures 传递给具有 purrr 和 rlang 的函数
Pass a list of vectors of arguments as quosures to a function with purrr and rlang
抱歉,标题中有很多介词。类似于 我有一个 quosures/arguments 的列表 我想传递给像 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
由 reprex package (v0.3.0.9001)
创建于 2020-09-02
使用 purrr 和 rlang,我如何将此列表的每个 quosure 传递给 count(mtcars, ...)
并执行
所以最终结果是相同的:
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
由 reprex package (v0.3.0.9001)
创建于 2020-09-02
难点在于此处使用了 c()
。我们确实需要某种 rlang
对象来保存您的参数。这是生成列表的更改函数
q_list <- function(...) {
q <- enexprs(...)
transenv <- new_environment(list(c=exprs))
purrr::map(q, function(x) {
eval_tidy(x, env = transenv)
})
}
这会获取您的表达式并评估它们将 c()
视为 enexprs()
。然后你可以将这些值注入你的函数调用
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))))
如果您只是在列表中创建表达式而不使用 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))))
sort
可以在外面
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
抱歉,标题中有很多介词。类似于 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
由 reprex package (v0.3.0.9001)
创建于 2020-09-02使用 purrr 和 rlang,我如何将此列表的每个 quosure 传递给 count(mtcars, ...)
所以最终结果是相同的:
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
由 reprex package (v0.3.0.9001)
创建于 2020-09-02难点在于此处使用了 c()
。我们确实需要某种 rlang
对象来保存您的参数。这是生成列表的更改函数
q_list <- function(...) {
q <- enexprs(...)
transenv <- new_environment(list(c=exprs))
purrr::map(q, function(x) {
eval_tidy(x, env = transenv)
})
}
这会获取您的表达式并评估它们将 c()
视为 enexprs()
。然后你可以将这些值注入你的函数调用
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))))
如果您只是在列表中创建表达式而不使用 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))))
sort
可以在外面
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