Home > Mobile >  How to combine lists that include tibbles?
How to combine lists that include tibbles?

Time:01-07

Here are lists that include tibbels:

test=list()
l <- list(list(var = "bb",b =  2, c = 3, d = 5), list(var = "a", b = 3, c  = 2,  d = 4))

l2 <- map(l,~data.frame(.))
l3 <-map_dfr(l2,~mutate_all(.,as.character))  
l4<-as_tibble(l3)
test[[1]]=l4
names(test)[1]="par"
test[[2]]=l4
names(test)[2]="mas"

myli=list()
myli[[1]]=l4
names(myli)[1]="par"
myli[[2]]=l4
names(myli)[2]="mas"

I would like to extract the name, var, and d and combine:

The output that I need would be like this:

  var        value    list     name 
  bb         5         test    par
  a          4         test    par
  bb         5         test    mas 
  a          4         test    mas
  bb         5         myli    par
  a          4         myli    par
  bb         5         myli    mas 
  a          4         myli    mas

CodePudding user response:

You can use purrr and a few of the map functions.

library(purrr)
library(tibble)
library(dplyr)

lst(test, myli) %>% 
  map_dfr(~ imap_dfr(.x, ~ add_column(.x, par = .y)), .id = "list") %>% 
  select(var, value = d, list, par)

This is combining your two (could be more) lists into a named list. Then iterate over each list. For each of these primary lists, iterate through their sub-lists (par and mas) adding the element name in as a column, and stacking the results. This gives you one final stacked list that you can select your desired variables off of.

# A tibble: 8 x 4
  var   value list  par  
  <chr> <chr> <chr> <chr>
1 bb    5     test  par  
2 a     4     test  par  
3 bb    5     test  mas  
4 a     4     test  mas  
5 bb    5     myli  par  
6 a     4     myli  par  
7 bb    5     myli  mas  
8 a     4     myli  mas 

EDIT

Inspired by another solution, I probably would favor this instead of my original.

lst(test, myli) %>% 
  map_dfr(~ bind_rows(.x, .id = "par"), .id = "list") %>% 
  select(var, value = d, list, par)

CodePudding user response:

Using dplyr::bind_rows you could do:

library(purrr)
library(dplyr)

map(list(test = test, myli = myli), bind_rows, .id = "name") %>% 
  bind_rows(.id = "list") %>% 
  select(var, value = d, list, name)
#> # A tibble: 8 × 4
#>   var   value list  name 
#>   <chr> <chr> <chr> <chr>
#> 1 bb    5     test  par  
#> 2 a     4     test  par  
#> 3 bb    5     test  mas  
#> 4 a     4     test  mas  
#> 5 bb    5     myli  par  
#> 6 a     4     myli  par  
#> 7 bb    5     myli  mas  
#> 8 a     4     myli  mas

CodePudding user response:

Yet another solution using tidyr::pivot_longer.

lst(myli, test) %>% 
  map_dfr(~ imap_dfr(.x, ~ .x %>% 
                       select(var,d) %>% 
                       pivot_longer(cols = var), .id = "name"), .id = "list")

# A tibble: 8 x 4
  var   list  name  value
  <chr> <chr> <chr> <chr>
1 bb    myli  par   5    
2 a     myli  par   4    
3 bb    myli  mas   5    
4 a     myli  mas   4    
5 bb    test  par   5    
6 a     test  par   4    
7 bb    test  mas   5    
8 a     test  mas   4   
  •  Tags:  
  • Related