【发布时间】:2021-09-28 06:25:11
【问题描述】:
我正在尝试使用rlang 编写一个函数,以便我可以根据提供的表达式对数据进行子集化。虽然实际的功能很复杂,但这里有一个最小版本来说明问题。
所需函数的最小版本
library(rlang)
# define a function
foo <- function(data, expr = NULL) {
if (!quo_is_null(enquo(expr))) {
dplyr::filter(data, !!enexpr(expr))
} else {
data
}
}
# does the function work? yes
head(foo(mtcars, NULL)) # with NULL
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
#> Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
#> Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
#> Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
#> Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
#> Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
head(foo(mtcars, mpg > 20)) # with expression
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
#> Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
#> Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#> Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
#> Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
#> Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
purrr::pmap 的问题
当与purrr::pmap() 一起使用时,当expr 为NULL 时,它按预期工作,但不是其他情况。除了list,我还尝试使用alist 来提供输入。
library(purrr)
# works when expression is `NULL`
pmap(
.l = list(data = list(head(mtcars)), expr = list(NULL)),
.f = foo
)
#> [[1]]
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
#> Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
#> Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
#> Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
#> Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
#> Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
# but not otherwise
pmap(
.l = list(data = list(head(mtcars)), expr = list("mpg > 20")),
.f = foo
)
#> Error: Problem with `filter()` input `..1`.
#> ℹ Input `..1` is `"mpg > 20"`.
#> x Input `..1` must be a logical vector, not a character.
由reprex package (v2.0.0) 于 2021-07-20 创建
【问题讨论】:
-
你可以在
pmap中使用expr = list(quote(mpg > 20)))来代替字符串吗