2013-05-01 13 views
14

mam trzy dokumenty tekstowe zapisane jako lista list o nazwie „dlist”:Coś expand.grid na liście list

dlist <- structure(list(name = c("a", "b", "c"), text = list(c("the", "quick", "brown"), c("fox", "jumps", "over", "the"), c("lazy", "dog"))), .Names = c("name", "text")) 

W głowie mi znaleźć przydatne wyobrazić dlist tak:

name text 
1 a  c("the", "quick", "brown") 
2 b  c("fox", "jumps", "over", "the") 
3 c  c("lazy", "dog") 

Jak można manipulować, jak poniżej? Chodzi o to, aby go wykreślić, więc coś, co można stopić dla ggplot2, byłoby dobre.

name text 
1 a the 
2 a quick 
3 a brown 
4 b fox 
5 b jumps 
6 b over 
7 b the 
8 c lazy 
9 c dog 

To jeden wiersz na słowo, dając jednocześnie wyraz i jego dokumentu nadrzędnego.

Próbowałem:

> expand.grid(dlist) 
    name     text 
1 a  the, quick, brown 
2 b  the, quick, brown 
3 c  the, quick, brown 
4 a fox, jumps, over, the 
5 b fox, jumps, over, the 
6 c fox, jumps, over, the 
7 a    lazy, dog 
8 b    lazy, dog 
9 c    lazy, dog 

> sapply(seq(1,3), function(x) (expand.grid(dlist$name[[x]], dlist$text[[x]]))) 
    [,1]  [,2]  [,3]  
Var1 factor,3 factor,4 factor,2 
Var2 factor,3 factor,4 factor,2 

unlist(dlist) 
    name1 name2 name3 text1 text2 text3 text4 
    "a"  "b"  "c" "the" "quick" "brown" "fox" 
    text5 text6 text7 text8 text9 
"jumps" "over" "the" "lazy" "dog" 

> sapply(seq(1,3), function(x) (cbind(dlist$name[[x]], dlist$text[[x]]))) 
[[1]] 
    [,1] [,2] 
[1,] "a" "the" 
[2,] "a" "quick" 
[3,] "a" "brown" 

[[2]] 
    [,1] [,2] 
[1,] "b" "fox" 
[2,] "b" "jumps" 
[3,] "b" "over" 
[4,] "b" "the" 

[[3]] 
    [,1] [,2] 
[1,] "c" "lazy" 
[2,] "c" "dog" 

Można śmiało powiedzieć, że jestem befuddled przez różne zastosowania i plyr funkcje i tak naprawdę nie wiem od czego zacząć. Nigdy nie widziałem wyniku takiego jak w "sapply" powyżej i nie rozumiem tego.

+1

można sformatować go bardziej do tego, co masz w głowie, jak to: 'dlist <-list (a = c ("the"," szybki "," brązowy "), ...)'. Może to również ułatwić odpowiedź na to pytanie. – Frank

+0

Dzięki Frank, a funkcja setNames Josh pokazała mi, jak to zrobić. – nacnudus

Odpowiedz

11

Po przekonwertowaniu numeru dlist na listę nazwaną (lepiej według mnie lepszą strukturą) można użyć stack(), aby uzyskać żądaną kolumnę data.frame.

(The rev() i setNames() wzywa w drugiej linii, to tylko jeden z wielu sposobów, aby zmienić kolejność kolumn i nazwy, aby dopasować pożądany wynik pokazany w swoim pytaniu.)

x <- setNames(dlist$text, dlist$name) 
setNames(rev(stack(x)), c("name", "text")) 
# name text 
# 1 a the 
# 2 a quick 
# 3 a brown 
# 4 b fox 
# 5 b jumps 
# 6 b over 
# 7 b the 
# 8 c lazy 
# 9 c dog 
+1

+1 Mam * nie * pomysł, jak to działa. Teraz mogę się dowiedzieć i mi się to podoba. –

+0

Dzięki za trzy nowe funkcje, szczególnie dla setNames, co oznacza, że ​​mogę śledzić komentarz Franka po fakcie, zamiast iść od razu do początku. – nacnudus

+0

@ SimonO101 - Oh dobrze. Właściwie wstrzymywałem się na tym, początkowo, ponieważ zawiera tyle kroków w kilku linijkach. Opierając się na twoich komentarzach i nacnudusie, cieszę się, że to zrobiłem. (FWIW, prawdopodobnie * naprawdę * użyłbym 'with (dlist, setNames (text, name)), sam.) –

0

odpowiedź Josha jest znacznie słodsze ale myślałem, że rzucę kapelusz na ringu.

dlist <- structure(list(name = c("a", "b", "c"), 
    text = list(c("the", "quick", "brown"), 
    c("fox", "jumps", "over", "the"), c("lazy", "dog"))), 
    .Names = c("name", "text")) 

lens <- sapply(unlist(dlist[-1], recursive = FALSE), length) 

data.frame(name = rep(dlist[[1]], lens), text = unlist(dlist[-1]), row.names = NULL) 

## name text 
## 1 a the 
## 2 a quick 
## 3 a brown 
## 4 b fox 
## 5 b jumps 
## 6 b over 
## 7 b the 
## 8 c lazy 
## 9 c dog 

W związku z tym lista list jest nieco niezręczna metoda przechowywania. Lista wektorów (szczególnie nazwanych list wektorów) byłaby łatwiejsza do opanowania.

1

Innym rozwiązaniem, może bardziej uogólnić:

do.call(rbind, do.call(mapply, c(dlist, FUN = data.frame, SIMPLIFY = FALSE))) 

#  name text 
# a.1 a the 
# a.2 a quick 
# a.3 a brown 
# b.1 b fox 
# b.2 b jumps 
# b.3 b over 
# b.4 b the 
# c.1 c lazy 
# c.2 c dog 
+0

To jest lepsze niż sugestia Simona O'Hanlona, ​​ponieważ pozwala na ramki danych z wieloma kolumnami (np. nazwa "w przykładzie), który ma zostać rozszerzony do wierszy na podstawie kolumny listy !!! – datamole