Skip to contents

Map over leaves with path (names)

Usage

list_imap(.x, .f, ..., .name = c("name", "path"), .progress = FALSE)

Arguments

.x

A nested list to traverse.

Lists are traversed recursively. Non-list objects are treated as leaves. Data frames are not traversed and are treated as leaf values.

.f

A function, formula, or function-like object coercible by rlang::as_function(). Additional arguments supplied through ... are passed on to .f.

...

Additional arguments passed to .f.

.name

A character scalar controlling what identifier is passed to .f.

Must be one of:

  • "name": pass only the current leaf name or positional index;

  • "path": pass the full path (vector of names) from the root to the current leaf.

.progress

Whether to show a progress

Use TRUE to turn on a basic progress, use a string to give it a name, or use a list to customize the progress bar (see ?cli::cli_progress_bar and https://cli.r-lib.org/articles/progress-advanced.html#cli_progress_bar for details).

Value

A list with the same nested structure as .x, where each leaf has been replaced by the result of calling .f on that leaf.

Examples

# \donttest{
x <- list(
  a = 1,
  b = list(
    x = 2,
    y = list(i = 3, j = 4)
  ),
  unnamed = list(5, z = 6)
)

# Pass only the leaf name or positional index
list_imap(x, \(value, name) paste(name, value, sep = " = "))
#> $a
#> [1] "a = 1"
#> 
#> $b
#> $b$x
#> [1] "x = 2"
#> 
#> $b$y
#> $b$y$i
#> [1] "i = 3"
#> 
#> $b$y$j
#> [1] "j = 4"
#> 
#> 
#> 
#> $unnamed
#> $unnamed[[1]]
#> [1] "1 = 5"
#> 
#> $unnamed$z
#> [1] "z = 6"
#> 
#> 

# Pass the full path to each leaf
list_imap(
  x,
  \(value, path) paste(paste(path, collapse = "."), value, sep = " = "),
  .name = "path"
)
#> $a
#> [1] "a = 1"
#> 
#> $b
#> $b$x
#> [1] "b.x = 2"
#> 
#> $b$y
#> $b$y$i
#> [1] "b.y.i = 3"
#> 
#> $b$y$j
#> [1] "b.y.j = 4"
#> 
#> 
#> 
#> $unnamed
#> $unnamed[[1]]
#> [1] "unnamed.1 = 5"
#> 
#> $unnamed$z
#> [1] "unnamed.z = 6"
#> 
#> 

# Additional arguments are forwarded to `.f`
list_imap(
  x,
  \(value, name, prefix) paste0(prefix, name, ": ", value),
  prefix = "leaf_"
)
#> $a
#> [1] "leaf_a: 1"
#> 
#> $b
#> $b$x
#> [1] "leaf_x: 2"
#> 
#> $b$y
#> $b$y$i
#> [1] "leaf_i: 3"
#> 
#> $b$y$j
#> [1] "leaf_j: 4"
#> 
#> 
#> 
#> $unnamed
#> $unnamed[[1]]
#> [1] "leaf_1: 5"
#> 
#> $unnamed$z
#> [1] "leaf_z: 6"
#> 
#> 

# Data frames are treated as leaves
x2 <- list(a = data.frame(x = 1:3), b = list(c = 1))
list_imap(x2, \(value, path) path, .name = "path")
#> $a
#> [1] "a"
#> 
#> $b
#> $b$c
#> [1] "b" "c"
#> 
#> 

# }