【问题标题】:Finding common phrases within a character vector在字符向量中查找常用短语
【发布时间】:2014-08-20 19:40:27
【问题描述】:

如何在字符向量中找到常用短语。例如,我有下面的字符向量,我想确定 Foo Bar 1 对 2 和 3 很常见,Foo Bar 2 在 4 和 5 中很常见,但我事先不知道我在寻找 Foo Bar 1 和 @ 987654325@.

示例输入是

a <- c("index", "bla Foo Bar 1", "blah Foo Bar 1",
       "blaa Foo Bar 2", "blahh Foo Bar 2")

所需的输出类似于

output <- list(`Foo Bar 1` = c(2, 3), `Foo Bar 2` = c(4, 5))

输出格式可能不同,但我正在寻找原始向量中的常用短语和对应位置。

我想匹配最长的常用短语(顺序很重要),所以在这种情况下,单独匹配 Foo Bar 是不可取的。开头和结尾的空格也可以返回(我可以稍后剥离是必要的)。在这个例子中,我也不想匹配Foo Bar 1a,所以我们应该假设单词是用空格分隔的。

我的问题类似于之前问过的this one,尽管在我的情况下,我只有一个向量并且想要匹配完整的单词而不是字符。

【问题讨论】:

  • 您可能希望提供一些示例输出。我不清楚你对这里的输出有什么期望。
  • 我添加了更多细节,感谢您的建议。
  • 小心:,因为在 R 中这是一个范围生成函数。也许您更愿意将c(2,3) 用作常见而不是2:3
  • @user338714 说Foo Bar 1 应该是匹配项而不是Foo Bar 的逻辑是什么,它将匹配2、3、4、5。为什么不是“Foo”或“Bar”他们自己?如果包含“Foo Bar 10d”的内容也应该匹配“Foo Bar 1”(Foo Bar 1 是 Foo Bar 10d 的子字符串)。请添加更多详细信息。
  • 另一个好建议。

标签: r


【解决方案1】:

这里有一些可行的方法。一、样本输入

#sample input
a <- c("index", "bla Foo Bar 1", "blah Foo Bar 1",
       "blaa Foo Bar 2", "blahh Foo Bar 2")

然后是一个将字符串分解为短语的函数

allcomp <- function(x) {
    unname(do.call(c, lapply(1:length(x), 
        function(z) lapply(1:(length(x)-z+1), 
            function(i) x[i:(i+z-1)]))))
}

getPhrases <- function(a) {
    parts <- Map(allcomp, strsplit(a, " "))
    vals <- sapply(parts, sapply, paste0, collapse=" ")
    len <- sapply(parts, sapply, length)
    do.call(rbind, Map(cbind.data.frame, i=seq_along(a), v=vals, l=len))
}

现在我们可以制表了

pp<-getPhrases(a)

tbl<-Map(function(x) list(ids=unique(x$i), len=max(x$l), 
    cnt=length(unique(x$i))), split(pp, pp$v))

maxlen<-max(sapply(tbl, `[[`,  "len") * as.numeric(sapply(tbl, `[[`,  "cnt")>1))
maxcnt<-max(sapply(tbl[sapply(tbl, `[[`,  "len")==maxlen], `[[`, "cnt"))


Map(function(x) x$ids, tbl[sapply(tbl, `[[`,  "len")==maxlen & 
    sapply(tbl, `[[`,  "cnt")==maxcnt])

返回

$`Foo Bar 1`
[1] 2 3

$`Foo Bar 2`
[1] 4 5

【讨论】:

  • 我在使用 allcomp 时遇到错误。我需要加载库或定义另一个变量吗?谢谢。
  • @user338714 抱歉,我忘了我正在使用该功能。我已经编辑了我的帖子以包含定义。
  • 效果很好,谢谢。我之前没有意识到,但我实际上想通过最大匹配数而不是最大字数进行过滤。交换 maxlen 和 maxcnt 计算就可以了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-12
相关资源
最近更新 更多