Maybe I'm missing something obvious but trying to flatten a list of named lists of named lists in R (may even be more nested) into eventually one flat list. purrr
and rlist
seem to have tools for that. How can I achieve that names of sublists become name precrypts of flattened result list, e.g. list1.blist.a
in purrr
? My actual list is more deeply nested with varying number of levels and repeating names on different levels. In the end I perform purrr::map_df(final_list, bind_rows)
and this seems to drop all duplicate names (and even if it didn't I don't know from which branch the original duplicate name comes from). I can do it with rlist
but I had hoped for a tidyverse
solution (nothing against fantastic rlist
but many already have tidyverse
installed).
EDIT:
Also note that rlist::list.flatten()
will always remove all levels but the top while purrr::flatten()
drops levels one at a time which may sometimes be what you need. You could achieve the same by nesting purrr::map(.x, .f = rlist::list.flatten) as often as you require but it's cumbersome and not beautiful/readable.
alist <- list(list1 = list(a = 1, b = 2, blist = list(a = 3, b = 4)),
list2 = list(a = 1, b = 2, blist = list(a = 3, b = 4)))
str(alist)
List of 2
$ list1:List of 3
..$ a : num 1
..$ b : num 2
..$ blist:List of 2
.. ..$ a: num 3
.. ..$ b: num 4
$ list2:List of 3
..$ a : num 1
..$ b : num 2
..$ blist:List of 2
.. ..$ a: num 3
.. ..$ b: num 4
alist_flat <- purrr::map(alist, purrr::flatten)
str(alist_flat)
List of 2
$ list1:List of 4
..$ a: num 1
..$ b: num 2
..$ a: num 3
..$ b: num 4
$ list2:List of 4
..$ a: num 1
..$ b: num 2
..$ a: num 3
..$ b: num 4
alist_flattest <- purrr::flatten(alist_flat)
str(alist_flattest)
List of 8
$ a: num 1
$ b: num 2
$ a: num 3
$ b: num 4
$ a: num 1
$ b: num 2
$ a: num 3
$ b: num 4
# works with rlist
alist_flat_names <- map(alist, rlist::list.flatten, use.names = TRUE)
str(alist_flat_names)
List of 2
$ list1:List of 4
..$ a : num 1
..$ b : num 2
..$ blist.a: num 3
..$ blist.b: num 4
$ list2:List of 4
..$ a : num 1
..$ b : num 2
..$ blist.a: num 3
..$ blist.b: num 4
alist_flattest_names <- rlist::list.flatten(alist_flat_names, use.names = TRUE)
str(alist_flattest_names)
List of 8
$ list1.a : num 1
$ list1.b : num 2
$ list1.blist.a: num 3
$ list1.blist.b: num 4
$ list2.a : num 1
$ list2.b : num 2
$ list2.blist.a: num 3
$ list2.blist.b: num 4