Skip to content

lmap(), lmap_at() and lmap_if() are similar to map(), map_at() and map_if(), except instead of mapping over .x[[i]], they instead map over .x[i].

This has several advantages:

  • It makes it possible to work with functions that exclusively take a list.

  • It allows .f to access the attributes of the encapsulating list, like names().

  • It allows .f to return a larger or small list than it receives changing the size of the output.

Usage

lmap(.x, .f, ..., .progress = FALSE)

lmap_if(.x, .p, .f, ..., .else = NULL, .progress = FALSE)

lmap_at(.x, .at, .f, ..., .progress = FALSE)

Arguments

.x

A list or data frame.

.f

A function that takes a length-1 list and returns a list (of any length.)

...

Additional arguments passed on to the mapped function.

We now generally recommend against using ... to pass additional (constant) arguments to .f. Instead use a shorthand anonymous function:

# Instead of
x |> map(f, 1, 2, collapse = ",")
# do:
x |> map(\(x) f(x, 1, 2, collapse = ","))

This makes it easier to understand which arguments belong to which function and will tend to yield better error messages.

.progress

Whether to show a progress bar. Use TRUE to turn on a basic progress bar, use a string to give it a name, or see progress_bars for more details.

.p

A predicate function specified in one of the following ways:

  • A named function, e.g. is.character.

  • An anonymous function, e.g. \(x) all(x < 0) or function(x) all(x < 0).

  • A logical vector of the same length as .x.

  • A string, if the elements of .x are themselves lists of objects, giving the name of a logical element in the inner lists.

Only those elements where .p evaluates to TRUE will be modified.

Wrap a function with in_parallel() to declare that it should be performed in parallel. See in_parallel() for more details. Use of ... is not permitted in this context.

.else

A function applied to elements of .x for which .p returns FALSE.

.at

A logical, integer, or character vector giving the elements to select. Alternatively, a function that takes a vector of names, and returns a logical, integer, or character vector of elements to select.

Value

A list or data frame, matching .x. There are no guarantees about the length.

See also

Examples

set.seed(1014)

# Let's write a function that returns a larger list or an empty list
# depending on some condition. It also uses the input name to name the
# output
maybe_rep <- function(x) {
  n <- rpois(1, 2)
  set_names(rep_len(x, n), paste0(names(x), seq_len(n)))
}

# The output size varies each time we map f()
x <- list(a = 1:4, b = letters[5:7], c = 8:9, d = letters[10])
x |> lmap(maybe_rep) |> str()
#> List of 6
#>  $ b1: chr [1:3] "e" "f" "g"
#>  $ b2: chr [1:3] "e" "f" "g"
#>  $ b3: chr [1:3] "e" "f" "g"
#>  $ c1: int [1:2] 8 9
#>  $ c2: int [1:2] 8 9
#>  $ d1: chr "j"

# We can apply f() on a selected subset of x
x |> lmap_at(c("a", "d"), maybe_rep) |> str()
#> List of 4
#>  $ b : chr [1:3] "e" "f" "g"
#>  $ c : int [1:2] 8 9
#>  $ d1: chr "j"
#>  $ d2: chr "j"

# Or only where a condition is satisfied
x |> lmap_if(is.character, maybe_rep) |> str()
#> List of 5
#>  $ a : int [1:4] 1 2 3 4
#>  $ b1: chr [1:3] "e" "f" "g"
#>  $ b2: chr [1:3] "e" "f" "g"
#>  $ c : int [1:2] 8 9
#>  $ d1: chr "j"