R: Map a function over lower levels of a nested list

at_depth {purrr} | R Documentation

## Map a function over lower levels of a nested list

### Description

`at_depth()` maps a function on lower levels of nested lists. In essence, `at_depth()` is a recursive map.

### Usage

    at_depth(.x, .depth, .f, ...)

### Arguments

`.x` | A deep list
`.depth` | Level of `.x` to map on.
`.f` | A function, formula, or atomic vector. If a function, it is used as is. If a formula, e.g. `~ .x + 2`, it is converted to a function with two arguments, `.x` or `.` and `.y`. This allows you to create very compact anonymous functions with up to two inputs. If character or integer vector, e.g. `"y"`, it is converted to an extractor function, `function(x) x[["y"]]`. To index deeply into a nested list, use multiple values; `c("x", "y")` is equivalent to `z[["x"]][["y"]]`. You can also set `.null` to set a default to use instead of `NULL` for absent components.
`...` | Additional arguments passed on to `.f`.

### Details

- `x %>% at_depth(0, fun)` is equivalent to `fun(x)`.

- `x %>% at_depth(1, fun)` is equivalent to `map(x, fun)`.

- `x %>% at_depth(2, fun)` is equivalent to `map(x, . %>% map(fun))`.

### Examples

    l1 <- list(
      obj1 = list(
        prop1 = list(param1 = 1:2, param2 = 3:4),
        prop2 = list(param1 = 5:6, param2 = 7:8)
      ),
      obj2 = list(
        prop1 = list(param1 = 9:10, param2 = 11:12),
        prop2 = list(param1 = 13:14, param2 = 15:16)
      )
    )

    # In the above list, "obj" is level 1, "prop" is level 2 and "param"
    # is level 3. To apply sum() on all params, we map it at depth 3:
    l1 %>% at_depth(3, sum)

    # map() lets us pluck the elements prop1/param2 in obj1 and obj2:
    l1 %>% map(c("prop1", "param2")) %>% str()

    # But what if we want to pluck all param2 elements? Then we need to
    # act at a lower level:
    l1 %>% at_depth(2, "param2") %>% str()

    # at_depth can be used in a complementary way with other purrr
    # functions to make them operate at a lower level
    l2 <- list(
      obj1 = list(
        prop1 = list(c(1, 2), c(3, 4), c(5, 6)),
        prop2 = list(c("a", "b"), c("c", "d"), c("e", "f"))
      ),
      obj2 = list(
        prop1 = list(c(10, 20), c(30, 40), c(50, 60)),
        prop2 = list(c("A", "B"), c("C", "D"), c("E", "F"))
      )
    )

    # Here we ask pmap() to map paste() simultaneously over all
    # elements of the objects at the second level. paste() is thus
    # effectively mapped at level 3.
    l2 %>% at_depth(2, pmap, paste, sep = " / ")

[Package purrr version 0.2.2 Index]