r - 在 R 中快速计算字符串中的数字

标签 r regex string performance count

有没有更有效的方法来计算字符串中出现频率最高的数字?我下面的 R 代码为每个字符串调用 gsub() 10 次;我有无数的字符串要处理。

> txt = 'wow:011 test 234567, abc=8951111111111aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
> max(vapply(0:9, function(i) nchar(gsub(paste0('[^',i,']'), '', txt)), integer(1L)))
[1] 12

我不关心数字本身。我只想要最频繁的计数。

我更愿意使用 R 的核心包,除非某些外部包提供了显着的性能。我在 Windows 10 上使用 x64 R 版本 3.4.1 (2017-06-30)。

更新:

这是以下优秀建议的(同类)性能比较。

> microbenchmark(
+     original = max(vapply(0:9, function(i) nchar(gsub(paste0('[^',i,']'), '', s)), integer(1L))),
+     strsplit = max(table(unlist(strsplit(gsub("\\D+", "", s), "")))),
+     gregexpr = max(vapply(0:9, function(d) sum(unlist(gregexpr(d, s)) > 0), integer(1L))),
+     stringi = max(vapply(0:9, function(x) stri_count_fixed(s, x), integer(1L))),
+     raw=max(vapply(0x30:0x39, function(x) sum(charToRaw(s)==x), integer(1L))),
+     tabulate = max(tabulate(as.integer(charToRaw(paste('a',s))))[48:57]),
+     times=1000L)
Unit: microseconds
     expr     min       lq      mean   median       uq      max neval
 original 476.172 536.9770 567.86559 554.8600 580.0530 8054.805  1000
 strsplit 366.071 422.3660 448.69815 445.3810 469.6410  798.389  1000
 gregexpr 302.622 345.2325 423.08347 360.3170 378.0455 9082.416  1000
  stringi 112.589 135.2940 149.82411 144.6245 155.1990 3910.770  1000
      raw  58.161  71.5340  83.57614  77.1330  82.1090 6249.642  1000
 tabulate  18.039  29.8575  35.20816  36.3890  40.7430   72.779  1000

为什么计算很奇怪?

这个奇怪的公式有助于识别用户输入的一些看起来很普通的假标识符。例如,一些非创意用户(我也是一个有罪的人)为他们的电话号码填写相同的数字。通常,在数据分析中,没有电话号码总比从一个数据集更改为另一个数据集的假电话号码要好。当然,如果有校验位,这将是一个额外的简单验证。

最佳答案

max(table(unlist(strsplit(gsub("\\D+", "", txt), ""))))
#OR
max(sapply(0:9, function(d) sum(unlist(gregexpr(d, txt)) > 0)))
#[1] 12

或者如果你确实关心数字

with(rle(sort(unlist(strsplit(gsub("\\D+", "", txt), "")))),
     setNames(c(max(lengths)), values[which.max(lengths)]))
# 1 
#12 

library(microbenchmark)
set.seed(42)
t = paste(sample(c(letters, 0:9), 1e5, TRUE), collapse = "")
microbenchmark(original = max(sapply(0:9, function(i) nchar(gsub(paste0('[^',i,']'), '', t)))),
               strsplit = max(table(unlist(strsplit(gsub("\\D+", "", t), "")))),
               gregexpr = max(sapply(0:9, function(d) sum(unlist(gregexpr(d, t)) > 0))))
#Unit: milliseconds
#     expr        min         lq       mean     median         uq       max neval cld
# original 215.371764 220.862807 233.368696 228.757529 239.809292 308.94393   100   c
# strsplit  11.224226  11.856327  12.956749  12.320586  12.893789  30.61072   100  b 
# gregexpr   7.542871   7.958818   8.680391   8.302971   8.728735  13.79921   100 a  

关于r - 在 R 中快速计算字符串中的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47516752/

相关文章:

R创建矩阵数组

javascript - Node.js 中通过正则表达式分割数组

regex - Powershell中的路径和字符串斩波

c - 以空格为分隔符的字符串三角形C语言

r - 获取 R 数据框中的位置序列

r - 在 R 中分配向量的一半

r - tm 自定义 removePunctuation 除了主题标签

c++ - 相同的正则表达式,但在 Linux 和 Windows 上结果不同(仅限 C++)

javascript - "?:^"正则表达式是什么意思?

r - 使用R从字符串中提取特定格式的子字符串(ID、代码)