R: Recursively Apply a Function to a List

rapply {base} | R Documentation

## Recursively Apply a Function to a List

### Description

`rapply` is a recursive version of `lapply` with flexibility in how the result is structured (`how = ".."`).

### Usage

    rapply(object, f, classes = "ANY", deflt = NULL,
           how = c("unlist", "replace", "list"), ...)

### Arguments

`object` | a `list` or `expression`, i.e., “list-like”.
`f` | a `function` of one “principal” argument, passing further arguments via `...`.
`classes` | character vector of `class` names, or `"ANY"` to match any class.
`deflt` | The default result (not used if `how = "replace"`).
`how` | character string partially matching the three possibilities given: see ‘Details’.
`...` | additional arguments passed to the call to `f`.

### Details

This function has two basic modes. If `how = "replace"`, each element of `object` which is not itself list-like and has a class included in `classes` is replaced by the result of applying `f` to the element.

Otherwise, with mode `how = "list"` or `how = "unlist"`, conceptually `object` is copied, all non-list elements which have a class included in `classes` are replaced by the result of applying `f` to the element and all others are replaced by `deflt`. Finally, if `how = "unlist"`, `unlist(recursive = TRUE)` is called on the result.

The semantics differ in detail from `lapply`: in particular the arguments are evaluated before calling the C code.

In R 3.5.x and earlier, `object` was required to be a list, which was not the case for its list-like components.

### Value

If `how = "unlist"`, a vector, otherwise “list-like” of similar structure as `object`.

### References

Chambers, J. A. (1998) Programming with Data. Springer.
(`rapply` is only described briefly there.)

### See Also

`lapply`, `dendrapply`.

### Examples

    X <- list(list(a = pi, b = list(c = 1L)), d = "a test")
    # the "identity operation":
    rapply(X, function(x) x, how = "replace") -> X.; stopifnot(identical(X, X.))
    rapply(X, sqrt, classes = "numeric", how = "replace")
    rapply(X, deparse, control = "all") # passing extras. argument of deparse()
    rapply(X, nchar, classes = "character", deflt = NA_integer_, how = "list")
    rapply(X, nchar, classes = "character", deflt = NA_integer_, how = "unlist")
    rapply(X, nchar, classes = "character",                      how = "unlist")
    rapply(X, log, classes = "numeric", how = "replace", base = 2)

    ## with expression() / list():
    E  <- expression(list(a = pi, b = expression(c = C1 * C2)), d = "a test")
    LE <- list(expression(a = pi, b = expression(c = C1 * C2)), d = "a test")
    rapply(E, nchar, how="replace") # "expression(c = C1 * C2)" are 23 chars
    rapply(E, nchar, classes = "character", deflt = NA_integer_, how = "unlist")
    rapply(LE, as.character) # a "pi" | b1 "expression" | b2 "C1 * C2" ..
    rapply(LE, nchar)        # (see above)
    stopifnot(exprs = {
      identical(E , rapply(E , identity, how = "replace"))
      identical(LE, rapply(LE, identity, how = "replace"))
    })

[Package base version 4.0.5 Index]