purrr::keep() / purrr::discard() / purrr::compact()
keep(.x, .p, ...)
discard(.x, .p, ...)
compact(.x, ...) Returns:
list or atomic · Updated March 13, 2026 · Tidyverse purrr functional-programming filtering lists
These purrr functions filter elements in a list or vector based on a predicate function. keep() retains elements where the predicate returns TRUE, discard() does the opposite, and compact() removes NULL, empty strings, and zero-length elements.
Syntax
keep(.x, .p, ...)
discard(.x, .p, ...)
compact(.x, ...)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
.x | list or atomic | — | A vector or list to filter |
.p | function | — | A predicate function that returns TRUE/FALSE |
... | additional arguments | — | Additional arguments passed to .p |
For compact(), .x is the only required parameter.
Examples
Basic usage with keep()
library(purrr)
# Keep even numbers
x <- list(1, 2, 3, 4, 5, 6)
keep(x, ~ .x %% 2 == 0)
# [[1]]
# [1] 2
# [[2]]
# [1] 4
# [[3]]
# [1] 6
Using discard() to remove elements
# Remove NULL and NA values
y <- list(1, NULL, 3, NA, 5)
discard(y, is.null)
# [[1]]
# [1] 1
# [[2]]
# [1] 3
# [[3]]
# [1] NA
# [[4]]
# [1] 5
# Discard empty strings
z <- list("apple", "", "banana", "cherry", "")
discard(z, ~ .x == "")
# [[1]]
# [1] "apple"
# [[2]]
# [1] "banana"
# [[3]]
# [1] "cherry"
Using compact() for quick cleanup
# Remove NULL and empty elements
data <- list(name = "Alice", email = NULL, age = 30, notes = "")
compact(data)
# $name
# [1] "Alice"
# $age
# [1] 30
# Compact works with all empty types
mixed <- list(1, NULL, "", character(0), NA, "hello")
compact(mixed)
# [[1]]
# [1] 1
# [[2]]
# [1] "hello"
Common Patterns
Conditional element removal
# Remove elements based on type
mixed_types <- list(1, "a", 2, "b", NULL, 3)
discard(mixed_types, is.null)
# [[1]]
# [1] 1
# [[2]]
# [1] "a"
# ...
# Keep only numeric values
keep(mixed_types, is.numeric)
# [[1]]
# [1] 1
# [[2]]
# [1] 2
# [[3]]
# [1] 3
Data cleaning pipelines
library(dplyr)
# Clean up a data frame with some missing values
df <- data.frame(
name = c("Alice", NA, "Bob", "Charlie"),
value = c(10, 20, NA, 40)
)
# Compact rows (remove rows with any NA)
df %>% pmap(~ c(...)) %>% compact() %>% matrix(ncol = 2, byrow = TRUE) %>% as.data.frame()