你可以试试
rowMeans
+
mapply
如下图所示
starwars %>%
filter(
rowMeans(mapply(`%in%`, select(., names(filter_list)), filter_list)) == 1
)
或
Reduce
+
Map
starwars %>%
filter(Reduce(`&`, Map(`%in%`, select(., names(filter_list)), filter_list)))
或者只是一个基本的R组合
subset
+
减少
+
地图
subset(starwars, Reduce(`&`, Map(`%in%`, starwars[names(filter_list)], filter_list)))
这给了
# A tibble: 8 Ã 14
name height mass hair_color skin_color eye_color birth_year sex gender
<chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
1 Leia Org⦠150 49 brown light brown 19 fema⦠feminâ¦
2 Beru Whi⦠165 75 brown light blue 47 fema⦠feminâ¦
3 Padmé Am⦠185 45 brown light brown 46 fema⦠feminâ¦
4 Cordé 157 NA brown light brown NA NA NA
5 Dormé 165 NA brown light brown NA fema⦠feminâ¦
6 Raymus A⦠188 79 brown light brown NA male mascuâ¦
7 Rey NA NA brown light hazel NA fema⦠feminâ¦
8 Poe Dame⦠NA NA brown light brown NA male mascuâ¦
# â¹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
# vehicles <list>, starships <list>
基准
如果标题中的“效率”指的是速度,你可以在这里查看基准测试
axeman <- \() {
starwars |>
reduce2(
.x = filter_list, .y = names(filter_list), .init = _,
.f = \(df, x, y) filter(df, .data[[y]] %in% x)
)
}
i_o <- \() {
names(filter_list) |>
Map(f = \(varname) starwars |> filter(.data[[varname]] %in% filter_list[[varname]])) |>
Reduce(f = \(stack, piece) inner_join(stack, piece))
}
tic1 <- \() {
starwars %>%
filter(
rowMeans(mapply(`%in%`, select(., names(filter_list)), filter_list)) == 1
)
}
tic2 <- \() {
starwars %>%
filter(Reduce(`&`, Map(`%in%`, select(., names(filter_list)), filter_list)))
}
tic3 <- \() {
subset(starwars, Reduce(`&`, Map(`%in%`, starwars[names(filter_list)], filter_list)))
}
microbenchmark(
axeman(),
i_o(),
tic1(),
tic2(),
tic3(),
unit = "relative",
check = "equal"
)
其中显示
Unit: relative
expr min lq mean median uq max neval
axeman() 11.98158 9.977999 9.679677 10.74786 9.652521 4.009427 100
i_o() 172.43091 130.316298 96.607907 121.01399 96.094325 15.142344 100
tic1() 12.45654 11.237299 11.433905 12.15965 12.796552 2.417425 100
tic2() 12.14343 10.864622 10.723350 11.55505 11.580282 4.656169 100
tic3() 1.00000 1.000000 1.000000 1.00000 1.000000 1.000000 100