假设文本数据如下所示:
txt <- c("peter likes red", "mary likes green", "bob likes blue")
我想将这些字符串从这个受控词汇表中减少为单词:
voc <- c("peter", "mary", "bob", "red", "green", "blue")
结果应该是一个向量:
c("peter red", "mary green", "bob blue")
可以使用tm
库但这只能给我一个密集的文档术语矩阵:
foo <- VCorpus(VectorSource(txt))
inspect(DocumentTermMatrix(foo, list(dictionary = voc)))
Non-/sparse entries: 6/12
Sparsity : 67%
Maximal term length: 5
Weighting : term frequency (tf)
Terms
Docs blue bob green mary peter red
1 0 0 0 0 1 1
2 0 0 1 1 0 0
3 1 1 0 0 0 0
如何获得每个向量元素一个字符串的向量解?
解决方案应该很快。我也是基地R的忠实粉丝。
编辑:迄今为止的解决方案比较
根据我的数据,詹姆斯的解决方案比Sotos快四倍。但是当我从length(text)
1k步进到10k时,它会耗尽内存。 Sotos的解决方案仍然以10k的速度运行。
鉴于我的数据有length(txt)
〜1M和length(voc)
~5k,我估计Sotos的解决方案需要18个小时才能完成,因为它的内存不足。
有没有更快的东西?
答案 0 :(得分:3)
仅基础方法是:
apply(sapply(paste0("\\b",voc,"\\b"), function(x) grepl(x,txt)), 1, function(x) paste(voc[x],collapse=" "))
[1] "peter red" "mary green" "bob blue"
sapply
部分重新创建您使用tm包的成员资格矩阵,而apply
遍历其行以从词汇表中提取相关术语以粘贴在一起。
答案 1 :(得分:2)
您可以使用stringi
library(stringi)
sapply(stri_extract_all_regex(txt, paste0('\\b', voc, collapse = '|', '\\b')), paste, collapse = ' ')
#[1] "peter red" "mary green" "bob blue"
或完整stringi
stri_paste_list(stri_extract_all_regex(txt, paste0('\\b', voc, collapse = '|', '\\b')), sep = ' ')
#[1] "peter red" "mary green" "bob blue"