【问题标题】:R: Extract controlled vocabulary from character vectorR:从字符向量中提取受控词汇
【发布时间】:2017-01-24 13:10:22
【问题描述】:

假设文本数据如下所示:

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

如何获得每个向量元素一个字符串的向量解?

解决方案应该很快。我也是base R的忠实粉丝。

编辑:迄今为止的解决方案比较

根据我的数据,James 的解决方案比 Sotos 的解决方案快四倍。但是当我从length(text) 1k 到 10k 时,内存不足。 Sotos 的解决方案仍然以 10k 的速度运行。

鉴于我的数据有 length(txt) ~1M 和 length(voc) ~5k 我估计 Sotos 的解决方案需要 18 小时才能完成,因为它不会耗尽内存。

没有更快的方法吗?

【问题讨论】:

  • 非正则表达式方法是否足以满足您的情况?例如。类似sapply(strsplit(txt, " ", TRUE), function(x) paste(collapse = " ", x[x %in% voc]))
  • @alexis_laz 你赢了!您的解决方案在 10 分钟内完成,而不是 18 小时。您想创建一个专门的答案以便我将其标记为解决方案吗?

标签: r extraction corpus vocabulary


【解决方案1】:

基本方法是:

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 迭代其行以从词汇表中提取相关术语以粘贴在一起。

【讨论】:

  • @Sotos 我已经修复了它以添加单词边界,所以它现在应该可以工作了。
【解决方案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" 

【讨论】:

  • 我正在检查您的解决方案。注意txt &lt;- c("peters like reds", "marys like greens", "bobs like blues")的结果应该是空的。
  • “应该是空的”是什么意思?
  • 我的意思是你的第一个解决方案不应该从peters 中提取peter。换句话说,peters 不在受控词汇中,peter 在。
  • 第一个解决方案的问题是它为txt1 &lt;- c("peter likes red", "mary likes green", "bob likes blue")txt2 &lt;- c("peters like reds", "marys like greens", "bobs like blues") 产生相同的输出。对于txt2,结果应该为空,因为词汇表中没有单词。对于您的第二个解决方案,我可能必须更新 stringi 库,因为找不到 stri_paste_list 函数。
  • 你明白我的意思吗?
猜你喜欢
  • 2021-11-28
  • 1970-01-01
  • 2017-10-09
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
  • 2017-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多