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