purrr::keep
keep(), discard(), and compact() are predicate functionals in purrr. They filter a list or vector based on a condition you provide.
keep() — Retain Matching Elements
keep() calls your predicate function on each element and keeps only the ones where the predicate returns TRUE:
library(purrr)
x <- list(a = 1:3, b = "hello", c = 4:6, d = "world")
keep(x, is.numeric)
#> $a
#> [1] 1 2 3
#>
#> $c
#> [1] 4 5 6
discard() — Drop Matching Elements
discard() is the inverse — it keeps elements where the predicate returns FALSE:
discard(x, is.numeric)
#> $b
#> [1] "hello"
#>
#> $d
#> [1] "world"
compact() — Remove Empty Elements
compact() removes elements that are NULL or have length zero:
y <- list(a = "foo", b = NULL, c = integer(0), d = NA, e = list())
compact(y)
#> $a
#> [1] "foo"
#>
#> $d
#> [1] NA
compact() with a predicate keeps only elements where the predicate returns TRUE for a non-empty, non-NULL value.
Predicate Syntax
The .p argument accepts several forms:
Named function:
keep(x, is.character)
Anonymous function (lambda):
keep(x, \(elem) length(elem) > 1)
String shorthand for lists — selects elements where the named sub-element is truthy:
z <- list(
list(name = "alice", active = TRUE),
list(name = "bob", active = FALSE),
list(name = "carol", active = TRUE)
)
keep(z, "active")
#> [[1]]
#> $name
#> [1] "alice"
#>
#> [[2]]
#> $name
#> [1] "carol"
Additional Arguments
Pass extra arguments to your predicate with ...:
nums <- list(a = c(1, 2, 3), b = c(4, 5), c = c(6, 7, 8, 9))
# Keep elements where mean is greater than 4
keep(nums, \(x) mean(x) > 4)
#> $b
#> [1] 4 5
#>
#> $c
#> [1] 6 7 8 9
Pipe-Friendly Chaining
Because the data comes first, these work well in pipes:
library(dplyr)
mtcars %>%
split(.$cyl) %>%
keep(\(df) nrow(df) > 10) %>%
map(summary)
Relationship to Base R
keep() is similar to base::Filter() but with more convenient argument order and stricter predicate checking. In Python, these are like filter() and reject() from itertools.
See Also
- /reference/tidyverse/purrr-map/ — transform each element with
map() - /reference/tidyverse/purrr-reduce/ — reduce a list to a single value
- /guides/purrr-functional-programming/ — functional programming patterns with purrr