Extract all values ​​from a list of lists with the same vector name

I have the following list of lists:

list_1 <- list(a = 2, b = 3) list_2 <- list(a=c(5,6), b= c(2,3)) list_3 <- list(a=c(10,5,8,1), b=c(9,6,2,9)) list_4 <- list(a=c(2,5,58), b=c(69,6,23)) mylist <- list(list_1, list_2, list_3, list_4) names(mylist)<- c("list_1", "list_2", "list_3", "list_4") 

Now I want to extract all the values ​​of a and b from the lists and save them either as data.frame with the names of the corresponding lists as an ID column, for example:

  [ID] [a] [b] [1] list_1 2 3 [2] list_2 5 2 [3] list_2 6 3 [4] list_3 10 9 [5] list_3 5 6 [6] list_3 8 2 [7] list_3 1 9 [8] list_4 2 69 [9] list_4 5 6 [10] list_4 58 23 

or as variables, such that a contains all the values, b contains all the values ​​of b, and the ID contains the corresponding identifiers of the list:

 [a] 2 5 6 10 5 8 1 2 5 58 [b] 3 2 3 9 6 2 9 69 6 23 [ID] "list_1" "list_2" "list_2" "list_3" "list_3" "list_3" "list_3" "list_4" "list_4" "list_4" 

I tried the second approach with a for loop, but could not archive the desired result. But even if I could handle it, I don’t know how I can solve the problem with the identifier. It would be great if the solution could be general, because I have many such lists of different lengths.

+7
r
source share
3 answers

In the R database, you can scroll the names mylist , for each name generating a data frame with this name as an ID variable and all the variables from the corresponding mylist element. Then you can combine all the created data frames together with do.call and rbind :

 do.call(rbind, lapply(names(mylist), function(x) data.frame(c(ID=x, mylist[[x]])))) # ID ab # 1 list_1 2 3 # 2 list_2 5 2 # 3 list_2 6 3 # 4 list_3 10 9 # 5 list_3 5 6 # 6 list_3 8 2 # 7 list_3 1 9 # 8 list_4 2 69 # 9 list_4 5 6 # 10 list_4 58 23 
+3
source share

I would just rbind listings and add the line names as ID . This way you don’t have to worry about column names at all. Or you can just leave row.names as ID and just set using do.call(rbind.data.frame, mylist)

 res <- do.call(rbind.data.frame, mylist) res$ID <- sub("\\..*", "", row.names(res)) row.names(res) <- NULL res # ab ID # 1 2 3 list_1 # 2 5 2 list_2 # 3 6 3 list_2 # 4 10 9 list_3 # 5 5 6 list_3 # 6 8 2 list_3 # 7 1 9 list_3 # 8 2 69 list_4 # 9 5 6 list_4 # 10 58 23 list_4 

Alternatively you can also do

 res <- do.call(rbind.data.frame, mylist) as.list(cbind(res, ID = row.names(res))) # $a # [1] 2 5 6 10 5 8 1 2 5 58 # # $b # [1] 3 2 3 9 6 2 9 69 6 23 # # $ID # [1] list_1 list_2.2 list_2.3 list_3.4 list_3.5 list_3.6 list_3.7 list_4.8 list_4.9 list_4.10 # Levels: list_1 list_2.2 list_2.3 list_3.4 list_3.5 list_3.6 list_3.7 list_4.10 list_4.8 list_4.9 
+3
source share

This is a little extra. I think the purrr package offers something very good in this case. The following returns a list similar to one by David Arenburg. The difference is that the identification part remains as names in each vector.

 library(purrr) mylist %>% zip_n(.simplify = TRUE) #$a # list_1 list_21 list_22 list_31 list_32 list_33 list_34 list_41 # 2 5 6 10 5 8 1 2 #list_42 list_43 # 5 58 # #$b # list_1 list_21 list_22 list_31 list_32 list_33 list_34 list_41 # 3 2 3 9 6 2 9 69 #list_42 list_43 # 6 23 
+1
source share

All Articles