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, likenames()
.It allows
.f
to return a larger or small list than it receives changing the size of the output.
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:This makes it easier to understand which arguments belong to which function and will tend to yield better error messages.
- .p
A single predicate function, a formula describing such a predicate function, or a logical vector of the same length as
.x
. Alternatively, if the elements of.x
are themselves lists of objects, a string indicating the name of a logical element in the inner lists. Only those elements where.p
evaluates toTRUE
will be modified.- .else
A function applied to elements of
.x
for which.p
returnsFALSE
.- .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.
: if the tidyselect package is installed, you can use
vars()
and tidyselect helpers to select elements.
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"