I often have nested lists of objects which come from nested lapply
statements, so that the objects are in the last level. When I want to "flatten" these lists, I use unlist
; however, sometimes I cannot use unlist(recursive = T)
because it will also flatten the last object's structure.
Is there any way to control the levels in the list up to which I can apply the unlist recursion? Or is there any other R function that does this?
For example, say I have a list of plots and I want to have them in the same list level to then align all the plots together in a panel.
# Example list
library(ggplot2)
l0 <- list(
l1 = list(
l2 = list(
l3.1 = ggplot(data = data.frame()) + ggtitle("p1"),
l3.2 = ggplot(data = data.frame()) + ggtitle("p2")
)
)
)
# What I can do with unlist()
l0.u <- unlist(l0, recursive = F)
l0.u.r <- unlist(l0, recursive = T)
# The desired output
l0.desired <- unlist(unlist(l0, recursive = F),recursive = F)
Here are several other solutions using rrapply()
(in package rrapply
), which has a dedicated option how = "flatten"
to flatten a nested list based on some condition
function:
## by class (not a pure list)
rrapply::rrapply(
l0,
condition = \(x) !inherits(x, "list"),
classes = c("list", "ANY"),
how = "flatten"
)
## by class (ggplot object)
rrapply::rrapply(
l0,
condition = ggplot2::is.ggplot,
classes = c("list", "ANY"),
how = "flatten"
)
## by name
rrapply::rrapply(
l0,
condition = \(x, .xname) grepl("l3", .xname),
classes = c("list", "ANY"),
how = "flatten"
)
## by level of nesting
rrapply::rrapply(
l0,
condition = \(x, .xpos) length(.xpos) == 3,
classes = c("list", "ANY"),
how = "flatten"
)