在big data.table列中查找子字符串的第一个匹配项

时间:2016-10-05 13:23:18

标签: r regex data.table stringr

我有一个大数据表,我想检查是否存在103a_foo。但是,大表中的文件名以不同的方式编写,因此我必须使用正则表达式。

dt = structure(list(myID = c("86577", "34005","34005", 
"194000", "30252", "71067"), 
filename = c("/scratch/tmpdir/12a_foo.mzXML.gz", 
"/scratch/tmpdir/103b_foo.XML.gz", "/scratch/tmpdir/103a_foo.XML.gz",
 "/scratch/tmpdir/103a_foo.XML.gz", 
"/scratch/tmpdir/100b_foo.XML.gz", "/scratch/tmpdir/108a_foo.XML.gz")),
 class = c("data.table", "data.frame"), 
row.names = c(NA, -5L), 
.Names = c("myID", "filename"))

作为输出,我想要一个索引3,因为这是第一次出现。我会使用grep('103a_foo', dt$filename)[1],但我希望搜索在第一次出现时停止,因为表很大(1000万行)。

2 个答案:

答案 0 :(得分:6)

如果设置fixed = TRUE则不需要那么长时间。对你的需求来说真的太慢了​​吗?

x <- sample(dt$filename, 1e7, TRUE)
library(microbenchmark)
microbenchmark(grep('103a_foo', x),
               grep('103a_foo',dt$filename, fixed = TRUE), 
               times = 5)

#Unit: milliseconds
#                              expr       min       lq      mean   #median        uq       max neval cld
#               grep("103a_foo", x) 2124.8178 2125.707 2128.7849 2127.542 2128.2054 2137.6532     5   b
# grep("103a_foo", x, fixed = TRUE)  826.2298  826.597  832.7058  829.969  840.1974  840.5359     5  

据我所知,没有有效的方法来实现使用纯R突破矢量化循环的grep。如果经常需要,可以使用Rcpp。

答案 1 :(得分:2)

正如@Roland指出的那样,grep你无法在第一场比赛中停下来。但是,如果您需要经常执行您所描述的操作,那么提取一次所有基本名称&#34;会很有帮助。你将要查看,然后使用match(实际上在第一次出现时中断)。类似的东西:

#this line might not work depending on the actual format of your real data
basenames<-gsub("^.*/|\\..*$","",dt$filename)
#then we use match
match("103a_foo",basenames)
#[1] 3