【问题标题】:R count number of commas and stringR计数逗号和字符串的数量
【发布时间】:2012-03-29 02:34:47
【问题描述】:

我有一个字符串:

    str1 <- "This is a string, that I've written 
        to ask about a question, or at least tried to."

我会怎么做:

1) 统计逗号的个数

2) 统计 '-ion' 的出现次数

有什么建议吗?

【问题讨论】:

    标签: r nlp


    【解决方案1】:

    stringr 包有一个函数 str_count 可以很好地为您完成这项工作。

    library(stringr)
    
    str_count(str1, ',')
    [1] 2
    str_count(str1, 'ion')
    [1] 1
    

    编辑:

    因为我很好奇:

    vec <- paste(sample(letters, 1e6, replace=T), collapse=' ')
    
    system.time(str_count(vec, 'a'))
       user  system elapsed 
      0.052   0.000   0.054 
    
    system.time(length(gregexpr('a', vec, fixed=T)[[1]]))
       user  system elapsed 
      2.124   0.016   2.146 
    
    system.time(length(gregexpr('a', vec, fixed=F)[[1]]))
       user  system elapsed 
      0.052   0.000   0.052 
    

    【讨论】:

    • 重要的是要注意gregexpr() 的时间命中完全来自设置fixed=T(这里根本不需要)。您可能想要为system.time(length(gregexpr('a', vec)[[1]])) 添加时间,这应该与str_count() 的时间几乎相同。这是有道理的,因为str_count() 本质上是gregexpr() 的包装器。
    • @JoshO'Brien 好点。我有点惊讶gregexpr 的速度有多慢。
    • 我也是。这就是我检查的原因。当fixed=TRUE 时,我真的没有意识到正则表达式的匹配速度要慢得多。很高兴知道这一点,因此感谢您将这些时间添加到您的帖子中!
    • data.table j 表达式中,您可以使用dt[,n=str_count(str,'a')] 来获取str 中每行'a' 的数量,但dt[,n= length(gregexpr('a',str)] 不起作用,并且解决方法 (Filter & unlist) 需要很长时间。在我的 data.table j 表达式中切换到 str_count 可以将我的执行时间从几个小时减少到 30 分钟(使用大型数据集)。
    【解决方案2】:

    数学文本的一般问题需要正则表达式。在这种情况下,您只想匹配特定字符,但要调用的函数是相同的。你想要gregexpr

    matched_commas <- gregexpr(",", str1, fixed = TRUE)
    n_commas <- length(matched_commas[[1]])
    
    matched_ion <- gregexpr("ion", str1, fixed = TRUE)
    n_ion <- length(matched_ion[[1]])
    

    如果您只想匹配单词末尾的“ion”,那么您确实需要正则表达式。 \b 代表单词边界,需要将反斜杠转义。

    gregexpr(
      "ion\\b", 
      "ionisation should only be matched at the end of the word", 
      perl = TRUE
    )
    

    【讨论】:

    • 谢谢,无需安装stringr 库即可。但是请注意length(gregexpr(",", "no commas", fixed = TRUE)[[1]])length(gregexpr(",", "one , comma", fixed = TRUE)[[1]]) 都是1。所以我们需要检查matched_commas[[1]][1] 是否大于0。
    【解决方案3】:

    这真的是对Richie棉花的答案的适应。我讨厌一遍又一遍地重复相同的功能。此方法允许您在字符串内汇集术语的向量:

    str1 <- "This is a string, that I've written to ask about a question, 
        or at least tried to."
    matches <- c(",", "ion") 
    sapply(matches,  function(x) length(gregexpr(x, str1, fixed = TRUE)[[1]]))
    #  , ion 
    #  2   1 
    

    【讨论】:

    • 再次原因我很好奇,你也可以向@ 987654322提供匹配的向量。 str_count(str1, matches)将返回相同的2和1。 span>
    【解决方案4】:

    另一个选项是stringi

    library(stringi)
    stri_count(str1,fixed=',')
    #[1] 2
    stri_count(str1,fixed='ion')
    #[1] 1
    

    基准测试

    vec <- paste(sample(letters, 1e6, replace=T), collapse=' ')
    f1 <- function() str_count(vec, 'a')
    f2 <- function() stri_count(vec, fixed='a')
    f3 <- function() length(gregexpr('a', vec)[[1]])
    
    library(microbenchmark)
    microbenchmark(f1(), f2(), f3(), unit='relative', times=20L)
    #Unit: relative
    #expr      min       lq     mean   median       uq      max neval cld
    # f1() 18.41423 18.43579 18.37623 18.36428 18.46115 17.79397    20   b
    # f2()  1.00000  1.00000  1.00000  1.00000  1.00000  1.00000    20  a 
    # f3() 18.35381 18.42019 18.30015 18.35580 18.20973 18.21109    20   b
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-18
      • 1970-01-01
      • 1970-01-01
      • 2012-03-28
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多