this post
,我提出了一种完全通用的机制,通过这种机制,一个数据帧可以被另一个数据帧中存储的条件过滤。警察把我叫出来了(该死!)并要求我实施。
功能
在筛选器数据帧中。这是可能的:
this post
展示如何。
library(tidyverse)
longFilterTable <- tribble(
~var, ~value,
"gear", list(3),
) %>%
mutate(
func=pmap(
list(value),
~function(x) x == ..1[[1]]
)
)
longFilterTable
# A tibble: 1 x 3
var value func
<chr> <list> <list>
1 gear <list [1]> <fn>
这是一种非常复杂的说法“只选择那些行(共行)”
mtcars
)为了什么
gear
是
3
. 这样做有效:
mtcars %>% filter(longFilterTable$func[[1]](gear)) %>% head(3)
mpg cyl disp hp drat wt qsec vs am gear carb
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
<11 rows deleted for brevity>
现在假设我想在标准上有更大的灵活性。例如,我可能希望选择一个值范围或一个固定值。这似乎是对上述过滤器数据集的合理扩展:
longFilterTable <- tribble(
~var, ~value, ~condition,
"gear", list(3), "equal",
"wt", list(3,4, 3.9), "range",
) %>%
mutate(
func=pmap(
list(value, condition),
~function(x) {
case_when(
condition == "equal" ~ x == ..1[[1]],
condition == "range" ~ x >= ..1[[1]][1] & x <= ..1[[1]][2],
TRUE ~ x
)
}
)
)
longFilterTable
# A tibble: 2 x 4
var value condition func
<chr> <list> <chr> <list>
1 gear <list [1]> equal <fn>
2 wt <list [3]> range <fn>
但现在当我尝试应用过滤器时,我得到:
mtcars %>% filter(longFilterTable$func[[1]](gear))
Show Traceback
Rerun with Debug
Error: Problem with `filter()` input `..1`.
x Obsolete data mask.
x Too late to resolve `condition` after the end of `dplyr::mutate()`.
â¹ Did you save an object that uses `condition` lazily in a column in the `dplyr::mutate()` expression ?
â¹ Input `..1` is `longFilterTable$func[[1]](gear)`.
我玩过各种各样的
deparse()
substitute()
expression()
,
force()
和
eval()
,但无济于事。有人能找到解决办法吗?