gpt4 book ai didi

r - Tidyeval:如何在没有用户引用的情况下将带有引用元素的列表传递给嵌套函数?

转载 作者:行者123 更新时间:2023-12-04 17:10:08 28 4
gpt4 key购买 nike

假设我有两个函数,我想将 a 嵌套在 b 中:

library(dplyr)
library(rlang)

a <- function(var, values){
filter(iris, {{var}} %in% values)
}

a(Species, "virginica") %>% head()

Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 6.3 3.3 6.0 2.5 virginica
2 5.8 2.7 5.1 1.9 virginica
3 7.1 3.0 5.9 2.1 virginica
4 6.3 2.9 5.6 1.8 virginica
5 6.5 3.0 5.8 2.2 virginica
6 7.6 3.0 6.6 2.1 virginica

b 调用 a,但使用 dot-dot-dot ... 做一些其他事情。它有一个传递给 a 的列表参数:

b <- function(l, ...){
eval_tidy(expr(a(!!! l)))
}

b(l = list(var = quo(Species), values = "virginica")) %>% head() # works if user passes quosure

当某些元素需要引用时,我可以将参数列表传递给 b 以在 a 中进行评估吗?所以对 b 的调用将如下所示:

b(l = list(var = Species, values = "virginica")) # does not work

我已经尝试了以下方法,但似乎我需要再拆分拼接一次或做些什么:

b <- function(l, ...){
l <- enquos(l)
qq_show(a(!!! l))
}

b(l = list(var = Species, values = "virginica"))

# a(^list(var = Species, values = "virginica"))

其他尝试会导致对 Species 的过早评估,从而导致错误:未找到对象“Species”

最佳答案

创建一个辅助函数,为 a() 收集参数。此助手可以使用 enquo() 化解 var,因此用户不必使用 quo()

a <- function(var, values) {
filter(iris, {{ var }} %in% values)
}

a_opts <- function(var, values) {
list(var = enquo(var), values = values)
}

然后 b() 期望用户传递一个可能由 a_opts() 创建的参数列表。但是我们如何将这些参数传递给 a() 呢?我们不能直接使用 !!! 因为拼接仅在 ... 中启用(参见 dynamic dots )而 a() 没有采取 ...

一种解决方案是使用do.call()。 rlang 惯用的另一个解决方案是使用 inject() 显式启用 !!!:

b <- function(l) {
inject(a(!!!l))
}

示例用法:

a_opts(Species, "virginica") %>%
b() %>%
head()

关于r - Tidyeval:如何在没有用户引用的情况下将带有引用元素的列表传递给嵌套函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69636463/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com