Regex R中的计数模式匹配

Regex R中的计数模式匹配,regex,r,pattern-matching,Regex,R,Pattern Matching,如何有效地计算一个字符串在另一个字符串中出现的实例数 下面是我迄今为止的代码。它成功地识别一个字符串的任何实例是否出现在另一个字符串中。但是,我不知道如何将它从真/假关系扩展到计数关系 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

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

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

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
由于小写字符串“chris”在
lll[1]
中出现两次,我希望
mmm[1,1]
为2而不是1

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

两个快速提示:

  • 避免双for循环,您不需要它;)
  • 使用
    stringr


  • 不要使用
    sum(grepl(dict[j],lll[i])
    ,而是尝试
    sum(gregexpr(dict[j],lll[i])[[1]>0)
    lll您也可以这样做:

    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
    

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


    我也喜欢这个解决方案,因为它不依赖于安装
    stringr
    library。但是
    stringr
    中的代码非常简单。非常感谢您提出的解决方案(我希望我能接受这两种方案)!!将留给SO社区让我知道什么更好。现在也很好。谢谢。看来有多种方法可以剥这只猫的皮。Thx@Ricardo。我还收到了许多其他的好答案。如下文所述……如果其他用户能够参与解决问题的最有效方法(给出以下建议),我会很高兴。这将因您对“高效”的定义而有所不同。请查看
    microbenchmark
    软件包。请注意,
    stringr
    是语法糖,使使用字符串更容易。自己编写代码总是一样快或更快。也就是说,
    效率=n\u使用*code\u运行时间+程序员时间
    。计算机的时间相对便宜。
    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
    
    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  
    
    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
    
    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