2015-10-18 17 views
7

Tôi có danh sách sau đây của danh sách:Giải nén tất cả các giá trị từ danh sách liệt kê với cùng tên vector

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") 

Bây giờ những gì tôi muốn là để trích xuất tất cả các a và giá trị b từ danh sách và lưu chúng hoặc là một data.frame với những cái tên danh sách tương ứng như một cột ID như:

[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 

hoặc là biến, chẳng hạn rằng a chứa tất cả một giá trị, b chứa tất cả các giá trị b, và ID chứa danh sách các ID tương ứng:

[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" 

Tôi đã thử phương pháp thứ hai với vòng lặp for nhưng không thể sửa đổi để lưu trữ kết quả mong muốn. Nhưng ngay cả khi tôi có thể xoay xở điều đó, tôi không biết làm cách nào để giải quyết vấn đề ID. Nó sẽ là tuyệt vời nếu các giải pháp có thể là một chung, bởi vì tôi có nhiều danh sách như vậy có độ dài khác nhau.

Trả lời

3

Trong cơ sở R, bạn có thể lặp qua tên của mylist, cho mỗi tên tạo ra một khung dữ liệu với tên đó là biến ID và tất cả các biến từ các yếu tố liên quan của mylist. Sau đó, bạn có thể kết hợp tất cả các dữ liệu được tạo khung cùng với do.callrbind:

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 
3

tôi sẽ chỉ rbind danh sách và thêm những cái tên hàng như ID. Bằng cách này bạn không cần phải lo lắng về các tên cột ở tất cả. Hoặc bạn chỉ có thể rời khỏi row.names như ID và chỉ giải quyết với 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 

Hoặc bạn cũng có thể làm

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 
1

Đây là một chút thêm. Tôi nghĩ rằng gói purrr cung cấp một cái gì đó khá tốt trong trường hợp này. Sau đây trả về một danh sách tương tự như một của David Arenburg. Sự khác biệt là phần ID giữ nguyên như tên trong mỗi vectơ.

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 
Các vấn đề liên quan