将引用列表转换为 dplyr::filter 的引用表达式列表
Converting a quoted list into a list of quoted expressions for dplyr::filter
我正在编写一个函数,它在执行其他操作之前组合了一个 dplyr::filter
步骤(我想对其进行参数化)。我想为可以覆盖的过滤条件提供一个默认参数。这排除了通过 ...
传递过滤参数的可能性,一次尝试如下:
library(rlang)
library(dplyr)
filter_and_stuff1 = function(tbl, filter_args = list(mpg > 33, gear == 4), arg3, arg4){
as_expr = enexpr(filter_args)
sub_tbl = filter(tbl, !!!as_expr)
# do some other things with sub_tbl, arg3 and arg4
sub_tbl
}
但是
filter_and_stuff1(mtcars)
Error: Argument 2 filter condition does not evaluate to a logical vector
看来逗号分隔有问题。查看 dplyr 的代码,它是通过调用内部函数 quo_reduce
来处理的,它似乎将逗号分隔值与 &
拼接在一起。我不明白如何在不使用 ...
的情况下执行此操作
TLDR:如何以编程方式将一组参数传递给包含默认表达式的 dplyr::filter?
如果我放弃 filter
的多个参数可以是 comma-separated 的要求,这有效:
filter_and_stuff2 = function(tbl, filter_args = mpg > 33 & gear == 4, arg3, arg4){
filter(tbl, !!enexpr(filter_args))
}
> filter_and_stuff2(mtcars)
mpg cyl disp hp drat wt qsec vs am gear carb gear4
1 33.9 4 71.1 65 4.22 1.835 19.9 1 1 4 1 TRUE
问题是,根据您的使用方式,enexpr
也会捕获对 list
的调用,
而使用省略号已经将每个表达式分隔为列表的不同元素:
library(rlang)
foo <- function(x) {
enexpr(x)
}
foo(list(a, b, c))
# list(a, b, c)
bar <- function(...) {
enexprs(...)
}
bar(a, b, c)
# [[1]]
# a
#
# [[2]]
# b
#
# [[3]]
# c
要执行您想要的操作,您可以使用 call_args
从提供给 list
的内容中提取每个表达式:
baz <- function(x) {
as_expr <- enexpr(x)
# expr just to show
expr(filter(!!!call_args(as_expr)))
}
baz(list(a == 1, b < 2))
# filter(a == 1, b < 2)
我正在编写一个函数,它在执行其他操作之前组合了一个 dplyr::filter
步骤(我想对其进行参数化)。我想为可以覆盖的过滤条件提供一个默认参数。这排除了通过 ...
传递过滤参数的可能性,一次尝试如下:
library(rlang)
library(dplyr)
filter_and_stuff1 = function(tbl, filter_args = list(mpg > 33, gear == 4), arg3, arg4){
as_expr = enexpr(filter_args)
sub_tbl = filter(tbl, !!!as_expr)
# do some other things with sub_tbl, arg3 and arg4
sub_tbl
}
但是
filter_and_stuff1(mtcars)
Error: Argument 2 filter condition does not evaluate to a logical vector
看来逗号分隔有问题。查看 dplyr 的代码,它是通过调用内部函数 quo_reduce
来处理的,它似乎将逗号分隔值与 &
拼接在一起。我不明白如何在不使用 ...
TLDR:如何以编程方式将一组参数传递给包含默认表达式的 dplyr::filter?
如果我放弃 filter
的多个参数可以是 comma-separated 的要求,这有效:
filter_and_stuff2 = function(tbl, filter_args = mpg > 33 & gear == 4, arg3, arg4){
filter(tbl, !!enexpr(filter_args))
}
> filter_and_stuff2(mtcars)
mpg cyl disp hp drat wt qsec vs am gear carb gear4
1 33.9 4 71.1 65 4.22 1.835 19.9 1 1 4 1 TRUE
问题是,根据您的使用方式,enexpr
也会捕获对 list
的调用,
而使用省略号已经将每个表达式分隔为列表的不同元素:
library(rlang)
foo <- function(x) {
enexpr(x)
}
foo(list(a, b, c))
# list(a, b, c)
bar <- function(...) {
enexprs(...)
}
bar(a, b, c)
# [[1]]
# a
#
# [[2]]
# b
#
# [[3]]
# c
要执行您想要的操作,您可以使用 call_args
从提供给 list
的内容中提取每个表达式:
baz <- function(x) {
as_expr <- enexpr(x)
# expr just to show
expr(filter(!!!call_args(as_expr)))
}
baz(list(a == 1, b < 2))
# filter(a == 1, b < 2)