【问题标题】:Pass a list of vectors of arguments as quosures to a function with purrr and rlang将参数向量列表作为 quosures 传递给具有 purrr 和 rlang 的函数
【发布时间】:2020-09-02 22:28:16
【问题描述】:

对不起,标题中的许多介词。与this question, 类似,我有一个想要传递给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 年 9 月 2 日创建

使用 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 年 9 月 2 日创建

【问题讨论】:

  • 也许你需要count(mtcars, !!! q_list(cyl, gear), sort = TRUE)

标签: r dplyr purrr rlang


【解决方案1】:

让这件事变得困难的是在这里使用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 = TRUE 被评估为改变另一列,而不是作为计数的排序参数。
  • @DavidRanzolin 我确实错过了。我对此有点惊讶。我已经更新为使用解决方法。我会继续寻找原因。
  • 是的,我认为它是相关的,但我很惊讶 select(mtcars, c(cyl, carb)) 工作正常,但 count(mtcars, c(cyl, carb)) 失败。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-03
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 2012-03-07
    相关资源
    最近更新 更多