6

如何有效地计算一个字符串在另一个字符串中出现的实例数?

以下是我迄今为止的代码。它成功地识别一个字符串的任何实例是否出现在另一个字符串中。但是,我不知道如何将它从 TRUE/FALSE 关系扩展到计数关系。

x <- ("Hello my name is Christopher. Some people call me Chris")
y <- ("Chris is an interesting person to be around")
z <- ("Because he plays sports and likes statistics")

lll <- tolower(list(x,y,z))
dict <- tolower(c("Chris", "Hell"))

mmm <- matrix(nrow=length(lll), ncol=length(dict), NA)

for (i in 1:length(lll)) {
for (j in 1:length(dict)) {
    mmm[i,j] <- sum(grepl(dict[j],lll[i]))
}
}
mmm

它产生:

       [,1] [,2]
 [1,]    1    1
 [2,]    1    0
 [3,]    0    0

由于小写字符串“chris”在lll[1]I would like mmm[1,1]to be 2 而不是 1 中出现了两次。

真实的例子是更高的维度......所以如果代码可以被矢量化而不是使用我的蛮力循环,我会很高兴。

4

5 回答 5

8

两个快速提示:

  1. 避免双重for循环,你不需要它;)
  2. 使用stringr

library(stringr)

dict <- setNames(nm=dict)  # simply for neatness
lapply(dict, str_count, string=lll)
# $chris
# [1] 2 1 0
#
# $hell
# [1] 1 0 0

或作为矩阵:

#  sapply(dict, str_count, string=lll)
#      chris hell
# [1,]     2    1
# [2,]     1    0
# [3,]     0    0
于 2013-10-29T19:07:24.140 回答
4

你也可以这样做:

count.matches <- function(pat, vec) sapply(regmatches(vec, gregexpr(pat, vec)), length)
mapply(count.matches, c('chris', 'hell'), list(lll))
#      chris hell
# [1,]     2    1
# [2,]     1    0
# [3,]     0    0
于 2013-10-29T19:20:28.780 回答
2

而不是sum(grepl(dict[j],lll[i])),尝试sum(gregexpr(dict[j],lll[i])[[1]] > 0)

于 2013-10-29T19:07:28.997 回答
1
llll<-rep(lll,length(dict))
dict1<-rep(dict,each=length(lll))


 do.call(rbind,Map(function(x,y)list(y,sum(gregexpr(y,x)[[1]] > 0)), llll,dict1))
                                                        [,1]    [,2]
hello my name is christopher. some people call me chris "chris" 2   
chris is an interesting person to be around             "chris" 1   
because he plays sports and likes statistics            "chris" 0   
hello my name is christopher. some people call me chris "hell"  1   
chris is an interesting person to be around             "hell"  0   
because he plays sports and likes statistics            "hell"  0  

然后,您可以使用它reshape来获得您想要的东西。

于 2013-10-29T19:13:14.773 回答
1

这使用 qdap 包。CRAN 版本应该可以正常工作,但您可能需要开发版本

library(qdap)

termco(c(x, y, z), 1:3, c('chris', 'hell'))

##   3 word.count     chris      hell
## 1 1         10 2(20.00%) 1(10.00%)
## 2 2          8 1(12.50%)         0
## 3 3          7         0         0


termco(c(x, y, z), 1:3, c('chris', 'hell'))$raw

##   3 word.count chris hell
## 1 1         10     2    1
## 2 2          8     1    0
## 3 3          7     0    0
于 2013-10-29T20:32:08.547 回答