2015-10-18 20 views
7

Mam następujący wykaz list:Extract wszystkie wartości z listy list z nazwą samego wektora

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

Teraz to, co chcę jest wyodrębnienie A i wartości B z listy i zapisać je albo jako data.frame z odpowiednimi nazwami lista jak kolumna ID takich jak:

[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 

lub jako zmienne, tak że a zawiera wszystkim wartości b zawiera wszystkie wartości b i ID zawiera odpowiadającą jej listę identyfikatorów:

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

Próbowałem drugie podejście z pętli for, ale nie udało się zarchiwizować pożądanego wyniku. Ale nawet gdybym mógł sobie z tym poradzić, nie wiem, jak rozwiązać problem z identyfikatorem. Byłoby świetnie, gdyby rozwiązanie mogło być ogólne, ponieważ mam wiele takich list o różnych długościach.

Odpowiedz

3

w bazie R, można pętli nazwiskami mylist, dla każdej nazwy tworząc ramkę danych z tą nazwą jako zmienną ID i wszystkich zmiennych z odpowiedniego elementu mylist. Następnie można połączyć wszystkie wygenerowane dane ramek wraz z do.call i 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 
3

Chciałbym tylko rbind listach i dodać nazwy wierszy jak ID. W ten sposób nie musisz w ogóle martwić się o nazwy kolumn. Albo można po prostu pozostawić row.names jako ID i tylko rozliczenia z 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 

Alternatywnie można też zrobić

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

To jest trochę ekstra. Myślę, że pakiet purrr oferuje w tym przypadku coś całkiem dobrego. Poniższy tekst zwraca listę podobną do tej, którą napisał David Arenburg. Różnica polega na tym, że część ID pozostaje jako imiona w każdym wektorze.

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 
Powiązane problemy