在 big data.table 的列中查找子字符串的第一个匹配项
Find first match of a substring in a column of big data.table
我有一个大数据 table,我想检查其中是否存在 103a_foo
。但是,大文件名 table 它们的写法不同,所以我必须使用正则表达式。
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]
,但我希望搜索在第一次出现时停止,因为 table 很大(1000 万行)。
如果您设置 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。
正如@Roland 指出的那样,grep
你将无法在第一场比赛中停下来。但是,如果您需要执行您经常描述的操作,那么一次性提取您将要查看的 "base names" 然后使用 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
我有一个大数据 table,我想检查其中是否存在 103a_foo
。但是,大文件名 table 它们的写法不同,所以我必须使用正则表达式。
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]
,但我希望搜索在第一次出现时停止,因为 table 很大(1000 万行)。
如果您设置 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。
正如@Roland 指出的那样,grep
你将无法在第一场比赛中停下来。但是,如果您需要执行您经常描述的操作,那么一次性提取您将要查看的 "base names" 然后使用 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