r - 从 R 中的字符串中查找姓氏的最快方法
问题描述
我正在尝试从 R 中各种格式的名称字符串的一部分中识别可能的姓氏。识别从姓氏数据集到给定名称字符串的最长字符串匹配的最快方法是什么(我正在使用 wru surnames2010 数据集)?
我需要最长的可能性而不是任何可能性。即在下面的示例中,第一个字符串“scottcampbell”包含可能的姓氏“scott”和“campbell”。我只想返回最长的可能匹配项,在这种情况下只有“campbell”。
重现示例数据:
library(wru)
data("surnames2010")
#filter out names under 4 characters
lnames <- surnames2010[nchar(as.character(surnames2010$surname))>3,]
testvec <- c("scottcampbell","mattbaker","tsmith","watkins","burnsmary","terri","frankrodriguez","neal")
所需的想象功能+结果:
foo_longest_matches(testvec)
#Desired imagined result:
[1] "campbell" "baker" "smith" "watkins" "burns" "terri" "rodriguez" "neal")
解决方案
你可以使用adist
. 请注意,您正在进行超过 100 万次比较以获得最长的比较。我希望你使用不同的方法。到目前为止我想到的最好的是
a <- adist(toupper(testvec), surnames2010$surname, counts = TRUE)
b <- attr(a, "trafos")
d <- array(grepl("S|I", b) + nchar(gsub("(.)\\1++", "1",b, perl=TRUE)), dim(a)) * 10 + a
as.character(surnames2010$surname[max.col(-d)])
[1] "CAMPBELL" "BAKER" "SMITH" "WATKINS" "BURNS" "TERRI" "RODRIGUEZ" "NEAL"
基准:
longest <- function(testvec,namevec){
a <- adist(testvec, namevec, counts = TRUE)
b <- attr(a, "trafos")
d <- array(grepl("S|I", b) + nchar(gsub("(.)\\1++", "1",b, perl=TRUE)), dim(a)) * 10 + a
as.character(namevec[max.col(-d)])
}
编辑:能够获得更快的方法(不一定是最快的)
longest2 <- function(testvec,namevec){
a <- stack(sapply(namevec,grep,testvec,value = TRUE,simplify = FALSE))
tapply(as.character(a[, 2]), a[, 1], function(x) x[which.max(nchar(x))])[testvec]
}
microbenchmark::microbenchmark(longest(testvec,lnames$surname),longest2(testvec,lnames$surname),foo_longest_matches(testvec),times = 5)
Unit: seconds
expr min lq mean median uq max neval
longest(testvec, lnames$surname) 3.316550 3.984128 5.308339 6.265192 6.396348 6.579477 5
longest2(testvec, lnames$surname) 1.817059 1.917883 2.835354 3.350068 3.538278 3.553481 5
foo_longest_matches(testvec) 10.093179 10.325489 11.610619 10.756714 10.889326 15.988384 5
推荐阅读
- python - 根据一个简单的条件,将一个数字列表分成几个列表,在列表中领先和落后
- c++ - AVX2:AVX 寄存器中 8 位元素的 BitScanReverse 或 CountLeadingZeros
- ios - 多个表视图使用的单一 UITableViewDiffableDataSource
- javascript - 具有两种不同颜色状态的导航栏
- vb.net - 循环无法读取所有访问记录
- google-drive-api - 如何使用google api获取有权访问共享驱动器的用户列表
- node.js - 如何使用 npm 并发包同时运行 Nextjs 应用程序和 Express 服务器?
- twilio - 从测试帐户购买 Twilio 上的虚拟号码
- javascript - Chart.js 和 react-chartjs-2 属性 translate 缺少类型
- python - 在 Django 中使用 rpy2 调用 R 脚本时出错:UnicodeDecodeError, invalid continuation byte