Что-то вроде expand.grid в списке списков - программирование
Подтвердить что ты не робот

Что-то вроде expand.grid в списке списков

У меня есть три текстовых документа, которые хранятся в виде списка списков, называемых "dlist":

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

В моей голове я считаю полезным отображать dlist следующим образом:

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

Как это можно манипулировать, как внизу? Идея состоит в том, чтобы нарисовать диаграмму, поэтому что-то, что может быть расплавлено для ggplot2, было бы хорошо.

  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

Эта строка для каждого слова, предоставляющая как слово, так и его родительский документ.

Я пробовал:

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

Справедливости ради следует сказать, что меня озадачивают различные функции apply и plyr и не знаю, с чего начать. Я никогда не видел результата, как в попытке "sapply" выше, и не понимаю его.

4b9b3361

Ответ 1

Если вы преобразуете свой dlist в именованный список (на мой взгляд, более подходящая структура), вы можете использовать stack() для получения двух данных data.frame.

(вызовы rev() и setNames() во второй строке являются лишь одним из многих способов настройки упорядочения столбцов и имен в соответствии с желаемым результатом, указанным в вашем вопросе.)

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

Ответ 2

Другое решение, возможно, более обобщаемое:

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

Ответ 3

Ответ Джоша намного слаще, но я думал, что брошу свою шляпу в кольцо.

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

При этом список списков является немного неудобным методом хранения. С перечнем векторов (особенно названных списков векторов) было бы легче справиться.