How do you break up a nested list into a dataframe where each embedded list becomes a separate column?

Viewed 189

My goal is to take a nested list as such:

list1 <- list(1,2,3,4,5)
list2 <- list(6,7,8,9,10)
list3 <- list(11,12,13,14,15)

nested_list <- list(list1, list2, list3)

and create a dataframe with the number of columns = number of lists embedded in the nested list. In other words, I am trying to get list1, list2, and list3 all placed into separate columns of a data frame.

I have tried using some functions from tidyr such as "unnest_wider" but haven't had much luck. Most functions out there are built to turn each nested list into an observation (row), not columns. I know I could run some sort of loop to do this, but that approach isn't very efficient.

2 Answers

If you look at unclass(df) with any data.frame, you can see that (despite the attributes) a data.frame bascially already has the data structure you have. Knowing this we only have to unlist the lists inside the list.

In a one-liner:

as.data.frame(lapply(nested_list, unlist))
#>   c.1..2..3..4..5. c.6..7..8..9..10. c.11..12..13..14..15.
#> 1                1                 6                    11
#> 2                2                 7                    12
#> 3                3                 8                    13
#> 4                4                 9                    14
#> 5                5                10                    15

Or using tidyverse:

library(tidyverse)
as_tibble(nested_list, .name_repair = "universal") %>% 
  unnest(everything())
#> New names:
#> * `` -> ...1
#> * `` -> ...2
#> * `` -> ...3
#> # A tibble: 5 x 3
#>    ...1  ...2  ...3
#>   <dbl> <dbl> <dbl>
#> 1     1     6    11
#> 2     2     7    12
#> 3     3     8    13
#> 4     4     9    14
#> 5     5    10    15

The reason the column names are a mess is that the list elements have no names. If they had names you would see they become column names in both solutions.

I would go

as.data.frame(do.call(cbind, nested_list))
Related