Home > OS >  Flattening a dynamic list in R
Flattening a dynamic list in R

Time:12-03

I have two lists as follows -

XY01 = list(
  "A" = LETTERS[1:5],
  "B" = LETTERS[6:10],
  "C" = list(
    "ZZ1" = LETTERS[1],
    "ZZ2" = LETTERS[2],
    "ZZ3" = LETTERS[3]
  )
)

XY02 = list(
  "A" = LETTERS[1:5],
  "B" = LETTERS[6:10],
  "C" = list(
    "Q1" = list(
      "ZZ1" = LETTERS[1],
      "ZZ2" = LETTERS[2],
      "ZZ3" = LETTERS[3]
    ),
    "Q2" = list(
      "ZZ1" = LETTERS[4],
      "ZZ2" = LETTERS[5],
      "ZZ3" = LETTERS[6]
    )
  )
)

I want the flatten both of these lists using the same code as the remote server can send any of these lists randomly - Desired output after flattening list XY01, which I got after running the following code -

library(data.table)
rbindlist(list(XY02$C), fill = T)
   ZZ1 ZZ2 ZZ3
1:   A   B   C

I am not sure how to get the desired output for XY02 (given below) using the same code.

Desired output for list XY02
   ZZ1 ZZ2 ZZ3
1:   A   B   C
2:   D   E   F

Can someone suggest a solution to get the desired outputs for lists XY01 and XY02 using the same piece of code?

CodePudding user response:

bind_rows would do this with the same code

library(dplyr)
bind_rows(XY01$C)
# A tibble: 1 × 3
  ZZ1   ZZ2   ZZ3  
  <chr> <chr> <chr>
1 A     B     C    
bind_rows(XY02$C)
# A tibble: 2 × 3
  ZZ1   ZZ2   ZZ3  
  <chr> <chr> <chr>
1 A     B     C    
2 D     E     F    

If we need to use rbindlist, don't wrap it in a list again for 'XY02'

library(data.table)
rbindlist(XY02$C)
   ZZ1 ZZ2 ZZ3
1:   A   B   C
2:   D   E   F

whereas for the first case, wrap it in a list

rbindlist(list(XY01$C))
   ZZ1 ZZ2 ZZ3
1:   A   B   C

If we want to check whether it is a list, create a function with if/else

f1 <- function(x) {
     if(!any(sapply(x, is.list))) {
           x <- list(x)
       }
      rbindlist(x)
}

-testing

> f1(XY01$C)
   ZZ1 ZZ2 ZZ3
1:   A   B   C
> f1(XY02$C)
   ZZ1 ZZ2 ZZ3
1:   A   B   C
2:   D   E   F
  • Related