在R中创建“单词”短语云,而不是单个单词

9
我想从短语列表中制作词云,其中许多短语会重复出现,而不是从单个单词制作词云。我的数据类似于这样,数据框中的一列是短语列表。
df$names <- c("John", "John", "Joseph A", "Mary A", "Mary A", "Paul H C", "Paul H C")

我想制作一个词云,在这个词云中,所有这些名称都被视为单独的短语,并显示它们的频率,而不是构成它们的单词。我一直在使用的代码如下所示:
df.corpus <- Corpus(DataframeSource(data.frame(df$names)))
df.corpus <- tm_map(client.corpus, function(x) removeWords(x, stopwords("english")))
#turning that corpus into a tDM
tdm <- TermDocumentMatrix(df.corpus)
m <- as.matrix(tdm)
v <- sort(rowSums(m),decreasing=TRUE)
d <- data.frame(word = names(v),freq=v)
pal <- brewer.pal(9, "BuGn")
pal <- pal[-(1:2)]
#making a worcloud
png("wordcloud.png", width=1280,height=800)
wordcloud(d$word,d$freq, scale=c(8,.3),min.freq=2,max.words=100, random.order=T, rot.per=.15, colors="black", vfont=c("sans serif","plain"))
dev.off()

这将创建一个词云,但是它是每个组成单词的词云,而不是短语的词云。因此,我看到了"A"、"H"、"John"等的相对频率,而不是我想要的"Joseph A"、"Mary A"等的相对频率。
我相信这并不复杂,但我无法解决!我会感激任何帮助。
2个回答

11
你的难点在于 df$names 中的每个元素都被 tm 的函数视为“文档”。例如,文档John A包含单词JohnA。你似乎想保留名称不变,只计算它们出现的次数 - 你可以使用 table 来完成这个任务。
library(wordcloud)
df<-data.frame(theNames=c("John", "John", "Joseph A", "Mary A", "Mary A", "Paul H C", "Paul H C"))
tb<-table(df$theNames)
wordcloud(names(tb),as.numeric(tb), scale=c(8,.3),min.freq=1,max.words=100, random.order=T, rot.per=.15, colors="black", vfont=c("sans serif","plain"))

enter image description here


谢谢,这完全解决了我的问题,而且非常清晰明了! - verybadatthis
1
注意wordcloud函数中的min.freq参数,它可能会影响到预期的输出结果。 - keegan

4

安装RWeka及其依赖项,然后尝试以下操作:

library(RWeka)
BigramTokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 2, max = 2))
# ... other tokenizers
tok <- BigramTokenizer
tdmgram <- TermDocumentMatrix(df.corpus, control = list(tokenize = tok))
#... create wordcloud

上面的分词器将您的文本切成长度为2的短语。
更具体地说,它创建最小长度为2和最大长度为2的短语。
使用Weka的通用NGramTokenizer算法,您可以创建不同的分词器(例如最小长度为1,最大长度为2),并且您可能希望尝试不同的长度。您还可以将它们命名为tok1,tok2,而不是我上面使用的冗长的“BigramTokenizer”。


对不起,你能再解释一下分词器是怎么工作的吗?我不太明白那些参数具体是做什么的,以及在运行后它到底做了些什么。 - verybadatthis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接