2013-05-01 31 views
14

tôi có ba tài liệu văn bản được lưu trữ như một danh sách liệt kê được gọi là "dlist":Something như expand.grid trên một danh sách liệt kê

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

Trong đầu tôi, tôi thấy nó hữu ích để hình dung dlist như thế này:

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

Làm cách nào để thao tác như sau? Ý tưởng là để vẽ đồ thị nó, vì vậy một cái gì đó có thể được tan chảy cho ggplot2 sẽ là tốt.

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 

Đó là một hàng trên mỗi từ, cung cấp cả từ và tài liệu gốc của từ đó.

Tôi đã thử:

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

Đó là công bằng để nói rằng tôi đang befuddled bởi khác nhau áp dụng và plyr chức năng và thực sự không biết bắt đầu từ đâu. Tôi chưa bao giờ thấy một kết quả như trong nỗ lực "dễ thương" ở trên, và không hiểu nó.

+1

Bạn có thể định dạng nó chặt chẽ hơn với những gì bạn có trong đầu của bạn, như thế này: 'dlist <-list (a = c ("the"," nhanh "," nâu "), ...)'. Làm như vậy cũng có thể đơn giản hóa câu trả lời cho câu hỏi này. – Frank

+0

Cảm ơn Frank và hàm setNames của Josh đã chỉ cho tôi cách thực hiện. – nacnudus

Trả lời

11

Nếu bạn chuyển đổi dlist thành danh sách được đặt tên (cấu trúc phù hợp hơn theo ý kiến ​​của tôi), bạn có thể sử dụng stack() để lấy dữ liệu hai cột.bạn muốn.

(The rev()setNames() cuộc gọi trong dòng thứ hai chỉ là một trong nhiều cách để điều chỉnh thứ tự cột và tên để phù hợp với đầu ra mong muốn thể hiện trong câu hỏi của bạn.)

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 Tôi có * không * ý tưởng về cách thức hoạt động của tính năng này. Bây giờ tôi có thể tìm ra và tôi thích điều đó. –

+0

Cảm ơn ba chức năng mới tuyệt vời, đặc biệt là đối với setNames có nghĩa là tôi có thể theo dõi nhận xét của Frank sau khi thực tế, thay vì quay lại ngay từ đầu. – nacnudus

+0

@ SimonO101 - Ồ tốt. Tôi đã thực sự giữ lại đăng bài này lúc đầu, bởi vì nó gói rất nhiều bước trong một vài dòng. Dựa trên ý kiến ​​của bạn và nacnudus ', mặc dù, tôi vui vì tôi đã làm. (FWIW, tôi có thể * thực sự * sử dụng 'với (dlist, setNames (văn bản, tên))', bản thân mình.) –

0

câu trả lời của Josh là ngọt ngào hơn nhiều nhưng tôi nghĩ tôi sẽ ném chiếc mũ vào chiếc nhẫn.

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 

Điều đó được cho biết danh sách danh sách là một phương pháp lưu trữ khó xử. Một danh sách các vectơ (đặc biệt là danh sách các vectơ) sẽ dễ giải quyết hơn.

1

Một giải pháp, có thể khái quát hơn:

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

Điều này tốt hơn đề xuất của Simon O'Hanlon vì nó cho phép các khung dữ liệu có nhiều cột (như " tên "trong ví dụ) để được mở rộng thành các hàng dựa trên cột danh sách !!! – datamole

Các vấn đề liên quan