Home > database >  Row bind all tibbles present in the nested list
Row bind all tibbles present in the nested list

Time:10-30

How to row bind all tibbles present in the nested list. Below is an example of four levels

combine all nested list elements to create a single tibble which has five columns -

  • first level list elements
  • second level list elements
  • third level list elements
  • fourth level list elements
  • p
library(dplyr)



tbl <- list()

a1 = runif(2)
a2 = runif(2)
a3 = runif(2)
a4 = runif(2)
a5 = runif(2)
a6 = runif(2)
a7 = runif(2)
a8 = runif(2)

tbl[["A"]][["m"]] [["a"]][["x"]] <- tibble(p = a1)
tbl[["A"]][["m"]] [["a"]][["y"]] <- tibble(p = a2)

tbl[["A"]][["m"]] [["b"]][["x"]] <- tibble(p = a3)
tbl[["A"]][["m"]] [["b"]][["y"]] <- tibble(p = a4)

tbl[["A"]][["n"]] [["a"]][["x"]] <- tibble(p = a5)
tbl[["A"]][["n"]] [["a"]][["y"]] <- tibble(p = a6)

tbl[["B"]][["n"]] [["b"]][["x"]] <- tibble(p = a7)
tbl[["A"]][["n"]] [["b"]][["y"]] <- tibble(p = a8)

tbl[["B"]][["m"]] [["a"]][["x"]] <- tibble(p = a1)
tbl[["B"]][["m"]] [["a"]][["y"]] <- tibble(p = a2)

tbl[["B"]][["m"]] [["b"]][["x"]] <- tibble(p = a3)
tbl[["B"]][["m"]] [["b"]][["y"]] <- tibble(p = a4)

tbl[["B"]][["n"]] [["a"]][["x"]] <- tibble(p = a5)
tbl[["B"]][["n"]] [["a"]][["y"]] <- tibble(p = a6)

tbl[["B"]][["n"]] [["b"]][["x"]] <- tibble(p = a7)
tbl[["B"]][["n"]] [["b"]][["y"]] <- tibble(p = a8)




# p

# expected results

tbl_expected <- tibble(first_element = c(rep("A", 16), rep("B", 16)),
                       
                       second_element = c(rep("m", 8), rep("n", 8), rep("m", 8), rep("n", 8)),
                       
                       third_element = c(rep("a", 4), rep("b", 4), rep("a", 4), rep("b", 4),
                                          rep("a", 4), rep("b", 4), rep("a", 4), rep("b", 4)),
                       
                       forth_element = c(rep("x", 2), rep("y", 2), rep("x", 2), rep("y", 2),
                                         rep("x", 2), rep("y", 2), rep("x", 2), rep("y", 2),
                                         rep("x", 2), rep("y", 2), rep("x", 2), rep("y", 2),
                                         rep("x", 2), rep("y", 2), rep("x", 2), rep("y", 2)),
                       
                     p = c(a1, a2, a3, a4, a5, a6, a7, a8, a1, a2, a3, a4, a5, a6, a7, a8))

CodePudding user response:

We could use map with bind_rows while specifying the .id to create the inner and outer names of the nested list

library(purrr)
library(dplyr)
map_dfr(tbl, ~ bind_rows(.x, .id = 'second_element'),
     .id = 'first_element')

-output

# A tibble: 8 × 3
  first_element second_element      p
  <chr>         <chr>           <dbl>
1 a             x              0.307 
2 a             x              0.524 
3 a             y              0.827 
4 a             y              0.437 
5 b             x              0.236 
6 b             x              0.0944
7 b             y              0.590 
8 b             y              0.787 

With new dataset with more nesting, we may use a recursive function rrapply

library(rrapply)
library(tidyr)
rrapply(tbl, how = 'melt') %>% 
   unnest(value) %>%  
   select(-L5) %>% 
   set_names(c('first_element', 'second_element',
      'third_element', 'fourth_element',  'p')) 

-output

# A tibble: 30 × 5
   first_element second_element third_element fourth_element       p
   <chr>         <chr>          <chr>         <chr>            <dbl>
 1 A             m              a             x              0.409  
 2 A             m              a             x              0.782  
 3 A             m              a             y              0.832  
 4 A             m              a             y              0.769  
 5 A             m              b             x              0.365  
 6 A             m              b             x              0.401  
 7 A             m              b             y              0.00445
 8 A             m              b             y              0.667  
 9 A             n              a             x              0.00853
10 A             n              a             x              0.0553 
# … with 20 more rows
  • Related