Search code examples
rnested-liststibble

Building a tibble from a multi-level nested list?


I have a deeply nested list that I want to transform into a single tibble. At the top level there is some number of secondary lists. Each of these is the same length. Inside each of these is a tertiary list. Each of these contains a single value and an identifier.

What I want to do is make a tibble where the columns are named by the tertiary list identifiers, and the single values from each tertiary list are populated into that column as observations.

I have tried a lot of tweaks on something similar to this, but I'm just not that adept with these functions yet, and I'm not sure how to get this to work.

  # Convert to tibble
  temp <- map_dfr(lstTemp, ~tibble::tibble(!!pluck(., "identifiers") := pluck(., "values")))

Here's some code to generate a list structure like what I have.

set.seed(123)  # Setting seed for reproducibility

# Create a nested list structure
nested_list <- replicate(5, {
  lapply(1:14, function(counter) {
    list(
      identifiers = letters[counter],
      values = runif(1, 1, 10)
    )
  })
}, simplify = FALSE)

Solution

  • You could accomplish the same using the following:

    library(jsonlite)   
    library(tidyverse)
    
     map_df(fromJSON(toJSON(nested_list)), deframe)
    
    # A tibble: 5 × 14
          a     b     c     d     e     f     g     h     i     j     k     l     m     n
      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    1  3.59  8.09  4.68  8.95  9.46  1.41  5.75  9.03  5.96  5.11  9.61  5.08  7.10  6.15
    2  1.93  9.10  3.21  1.38  3.95  9.59  9.01  7.24  6.76  9.95  6.90  7.38  5.90  6.35
    3  3.60  2.32  9.67  9.12  7.22  8.16  1.22  5.30  7.83  2.95  3.86  3.08  2.29  4.73
    4  4.72  4.32  2.37  2.25  3.10  5.19  3.39  8.72  1.41  4.98  8.19  2.10  6.05  2.86
    5  2.15  7.78  9.06  4.37  6.99  1.85  4.46  3.47  8.33  5.04  8.29  8.31  8.15  4.96
    

    map(nested_list, transpose) %>%
       array(length(.))%>%
       array2DF() %>%
       exec(pmap_df, ., ~set_names(unlist(..3), ..2))
    
    # A tibble: 5 × 14
          a     b     c     d     e     f     g     h     i     j     k     l     m     n
      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    1  3.59  8.09  4.68  8.95  9.46  1.41  5.75  9.03  5.96  5.11  9.61  5.08  7.10  6.15
    2  1.93  9.10  3.21  1.38  3.95  9.59  9.01  7.24  6.76  9.95  6.90  7.38  5.90  6.35
    3  3.60  2.32  9.67  9.12  7.22  8.16  1.22  5.30  7.83  2.95  3.86  3.08  2.29  4.73
    4  4.72  4.32  2.37  2.25  3.10  5.19  3.39  8.72  1.41  4.98  8.19  2.10  6.05  2.86
    5  2.15  7.78  9.06  4.37  6.99  1.85  4.46  3.47  8.33  5.04  8.29  8.31  8.15  4.96