Что-то вроде 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" выше, и не понимаю его.
Ответы
Ответ 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
При этом список списков является немного неудобным методом хранения. С перечнем векторов (особенно названных списков векторов) было бы легче справиться.