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 what I want is to extract all the a and b values from the lists and save them either as a data.frame with the corresponding list names as a ID column like:
    [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 a values, b contains all b values, and ID contains the corresponding list IDs:
[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 couldn't mange to archive the desired result. But even if I could manage that I don't know how I would solve the ID thing. It would be great if the solution could be a general one, because I have many such lists of different lengths.
In base R, you could loop through the names of mylist, for each name generating a data frame with that name as the ID variable and all variables from the relevant element of mylist. Then you could combine all the generated data frames together with do.call and rbind:
do.call(rbind, lapply(names(mylist), function(x) data.frame(c(ID=x, mylist[[x]]))))
#        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
                        I would just rbind the lists and add the row names as ID. This way you don't need to worry about the column names at all. Or you can just leave the row.names as the ID and just settle with do.call(rbind.data.frame, mylist)
res <- do.call(rbind.data.frame, mylist)
res$ID <- sub("\\..*", "", row.names(res))
row.names(res) <- NULL
res
#     a  b     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
Alternately you could 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
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With