Reputation: 273
I am trying to flatten a list that has 3 levels into a list that has 2 levels.... In other words, I have a nested list as such :
ls <- list(
a = list(
a1 = list(
a11 = list(data),
a2 = list(
a21 = list(data2)),
b = list(
b1 = list(
b11 = list(data3),
b2 = list(
b21 = list(data4)))
I would like to flatten this so that it looks like this:
flat_ls <- list(
a_a1 = list(
a11 = list(data),
a_a2 = list(
a21 = list(data2)),
b_b1 = list(
b11 = list(data3),
b_b2 = list(
b21 = list(data4)))
I know there function flatten()
or lapply(rapply(y, enquote, how="unlist"), eval)
can make a multilevel list into a flat list. However, I want to keep the last layer of the list, without flattening that. How can I accomplish this?
Upvotes: 0
Views: 997
Reputation: 17079
purrr::flatten()
actually does exactly what you're looking for. per (purrr) the documentation, flatten()
and friends "only ever remove a single layer of hierarchy."
library(purrr)
# placeholder values for `data` etc
data <- as.symbol("data")
data2 <- as.symbol("data2")
data3 <- as.symbol("data3")
data4 <- as.symbol("data4")
# added a few missing parens; raised error in original
ls <- list(
a = list(
a1 = list(
a11 = list(data)
),
a2 = list(
a21 = list(data2)
)
),
b = list(
b1 = list(
b11 = list(data3)
),
b2 = list(
b21 = list(data4)
)
)
)
# (added step in response to comment):
# combine top two levels of names
ls_renamed <- imap(ls, ~ set_names(.x, paste(.y, names(.x), sep = "_")))
# flatten top level
flat_ls <- flatten(ls_renamed)
dput(flat_ls)
# list(
# a_a1 = list(
# a11 = list(data)
# ),
# a_a2 = list(
# a21 = list(data2)
# ),
# b_b1 = list(
# b11 = list(data3)
# ),
# b_b2 = list(
# b21 = list(data4)
# )
# )
Upvotes: 2