简体   繁体   中英

Rbind on dataframes in nested list/tibbles

I have nested tibbles, within a list, within a list, here's the structure:

I basically need to rbind the dataframes that are inside everything. The result would be 6 dataframes in a list, one for each season(winter/summer) and species combination.

> glimpse(list_graphs)

List of 2
 $ winter:List of 3
  ..$ species1: tibble [161 x 1] (S3: tbl_df/tbl/data.frame)
  ..$ species2: tibble [38 x 1] (S3: tbl_df/tbl/data.frame)
  ..$ species3: tibble [72 x 1] (S3: tbl_df/tbl/data.frame)
 $ summer:List of 3
  ..$ species1: tibble [33 x 1] (S3: tbl_df/tbl/data.frame)
  ..$ species2: tibble [2 x 1] (S3: tbl_df/tbl/data.frame)
  ..$ species3: tibble [52 x 1] (S3: tbl_df/tbl/data.frame)

I've tried:

map(list_graphs, function(x) {
  map(x, function(x){
    map(x,~do.call(rbind,x))
    }
  )
})

However, this results in the following which is incorrect:

List of 2
 $ winter:List of 3
  ..$ species1:List of 1
  .. ..$ graph_layer:List of 161
  .. .. ..- attr(*, "dim")= int [1:2] 1 161
  .. .. ..- attr(*, "dimnames")=List of 2
  ..$ species2:List of 1
  .. ..$ graph_layer:List of 38
  .. .. ..- attr(*, "dim")= int [1:2] 1 38
  .. .. ..- attr(*, "dimnames")=List of 2
  ..$ species3:List of 1
  .. ..$ graph_layer:List of 72
  .. .. ..- attr(*, "dim")= int [1:2] 1 72
  .. .. ..- attr(*, "dimnames")=List of 2
 $ summer:List of 3
  ..$ species1:List of 1
  .. ..$ graph_layer:List of 33
  .. .. ..- attr(*, "dim")= int [1:2] 1 33
  .. .. ..- attr(*, "dimnames")=List of 2
  ..$ species2:List of 1
  .. ..$ graph_layer:List of 2
  .. .. ..- attr(*, "dim")= int [1:2] 1 2
  .. .. ..- attr(*, "dimnames")=List of 2
  ..$ species3:List of 1
  .. ..$ graph_layer:List of 52
  .. .. ..- attr(*, "dim")= int [1:2] 1 52
  .. .. ..- attr(*, "dimnames")=List of 2

I'm sure it's a relatively easy fix, but I just can't work it out. I'm hoping someone can suggest solution based on structure I have above, if not I'll try and get a working regex dataframe.

Thank you

You could use map_dfr + bind_rows :

library(tidyverse)

map_dfr(list_graphs, ~ bind_rows(.x, .id = "species"), .id = "season")

# # A tibble: 6 × 3
#   season species      x
#   <chr>  <chr>    <dbl>
# 1 winter species1     1
# 2 winter species2     2
# 3 winter species3     3
# 4 summer species1     4
# 5 summer species2     5
# 6 summer species3     6

Data
list_graphs <- list(winter = list(species1 = tibble(x = 1), species2 = tibble(x = 2), species3 = tibble(x = 3)),
                    summer = list(species1 = tibble(x = 4), species2 = tibble(x = 5), species3 = tibble(x = 6)))

glimpse(list_graphs)

# List of 2
#  $ winter:List of 3
#   ..$ species1: tibble [1 × 1] (S3: tbl_df/tbl/data.frame)
#   ..$ species2: tibble [1 × 1] (S3: tbl_df/tbl/data.frame)
#   ..$ species3: tibble [1 × 1] (S3: tbl_df/tbl/data.frame)
#  $ summer:List of 3
#   ..$ species1: tibble [1 × 1] (S3: tbl_df/tbl/data.frame)
#   ..$ species2: tibble [1 × 1] (S3: tbl_df/tbl/data.frame)
#   ..$ species3: tibble [1 × 1] (S3: tbl_df/tbl/data.frame)

Since you don't provide a reproducible example, here's how I understand what you are dealing with:

You have (something like)

l <- list(
      winter = list(
        species1 = list(tibble(x = 1), tibble(x = 2), tibble(x = 3)), 
        species2 = list(tibble(x = 4), tibble(x = 5), tibble(x = 6)), 
        species3 = list(tibble(x = 7), tibble(x = 8), tibble(x = 9)) 
        ),
     summer = list(
       species1 = list(tibble(x = 10), tibble(x = 11), tibble(x = 12)), 
       species2 = list(tibble(x = 13), tibble(x = 14), tibble(x = 15)), 
       species3 = list(tibble(x = 16), tibble(x = 17), tibble(x = 18)) 
     )
    )

Here's an approach that preserves names and returns a list of (row-bound) tibbles:

map(names(l), function(name) set_names( 
                              map(l[[name]], ~ map_dfr(.x, ~ .x)), 
                              paste0, name
                             )
  ) %>% 
   flatten()

Outcome (of str() for brevity)

List of 6
 $ species1winter: tibble [3 × 1] (S3: tbl_df/tbl/data.frame)
  ..$ x: num [1:3] 1 2 3
 $ species2winter: tibble [3 × 1] (S3: tbl_df/tbl/data.frame)
  ..$ x: num [1:3] 4 5 6
 $ species3winter: tibble [3 × 1] (S3: tbl_df/tbl/data.frame)
  ..$ x: num [1:3] 7 8 9
 $ species1summer: tibble [3 × 1] (S3: tbl_df/tbl/data.frame)
  ..$ x: num [1:3] 10 11 12
 $ species2summer: tibble [3 × 1] (S3: tbl_df/tbl/data.frame)
  ..$ x: num [1:3] 13 14 15
 $ species3summer: tibble [3 × 1] (S3: tbl_df/tbl/data.frame)
  ..$ x: num [1:3] 16 17 18

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM