Skip to content

Instantly share code, notes, and snippets.

@jmbarbone
Last active June 21, 2022 15:51
Show Gist options
  • Save jmbarbone/6e788df5728cf59af1db3cd6124bf986 to your computer and use it in GitHub Desktop.
Save jmbarbone/6e788df5728cf59af1db3cd6124bf986 to your computer and use it in GitHub Desktop.
filtering
# vector filtering --------------------------------------------------------
# Modeled from `base::Filter()` but less generalized (therefore more efficient).
# These functions also use a vector as the first argument rather than the
# filtering function.
base::Filter
#> function (f, x)
#> {
#> f <- match.fun(f)
#> ind <- as.logical(unlist(lapply(x, f)))
#> x[which(ind)]
#> }
#> <bytecode: 0x000002053df873b8>
#> <environment: namespace:base>
filter_vec <- function(x, FUN, ...) {
FUN <- match.fun(FUN)
x[which(FUN(x, ...))]
}
filter_apply <- function(x, FUN, ...) {
FUN <- match.fun(FUN)
x[which(vapply(x, FUN, NA, ...))]
}
is_even <- function(x) x %% 2 == 0
# Examples ----------------------------------------------------------------
x <- sample(1:10, 30, TRUE)
filter_vec(x, is_even)
#> [1] 8 10 8 8 8 10 6 10 8 2 4 8 8 6 6 6
filter_vec(x, Negate(is_even))
#> [1] 1 1 1 3 5 1 1 5 7 9 5 1 1 7
# Benchmarks --------------------------------------------------------------
x <- round(runif(1e5) * 100)
bench::mark(
Filter = Filter(is_even, x),
filter_vec = filter_vec(x, is_even),
filter_apply = filter_apply(x, is_even)
)
#> Warning: Some expressions had a GC in every iteration; so filtering is disabled.
#> # A tibble: 3 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 Filter 75.51ms 79.23ms 12.5 2.1MB 25.0
#> 2 filter_vec 2.33ms 2.82ms 311. 2.1MB 13.8
#> 3 filter_apply 73.41ms 74.39ms 13.2 1.34MB 26.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment