2017-07-03 26 views
1

我想匹配包含多个模式的向量data.table中的值。演示代码,我已经是:有效的方法来执行正则表达式匹配与模式向量

library(data.table) 

sites <- c("www.google.com", "plus.google.com", "www.yahoo.com", "www.bbc.co.uk") 
patterns <- c("bb", "goog") 
x <- data.table(sites) 

# Regexp version of the in operator, iterates over a group 
`%match_in%` <- function (values, match_list) { 
    sapply(values, 
     function (x, ml) { 
      any(sapply(ml, grepl, x, ignore.case=TRUE, perl=TRUE)) 
     } 
     ,match_list 
)} 

x[sites %match_in% patterns] 

哪个正确返回:

   sites 
1: www.google.com 
2: plus.google.com 
3: www.bbc.co.uk 

但是因为这包含嵌套sapply,它是具有较大data.tables运行非常缓慢。

有没有更高效的方法来做到这一点,将与更大的表一起工作?

+0

注:在实际的代码,'patterns'有几百个项目和正则表达式包含的东西像向后看,所以把它们放在一条线上是不实际的。 – Iain

回答

3

如果您要搜索多种模式,为什么不将模式与or语法组合起来?正如@Marius所建议的,如果你有很多模式需要检查,可以使用paste0(patterns, collapse = "|")创建。

例如,

all_patterns = paste0(patterns, collapse = "|") 

stringr::str_subset(sites, all_patterns) 
[1] "www.google.com" "plus.google.com" "www.bbc.co.uk" 

要坚持你的data.table用例,也许

x[stringr::str_detect(sites, all_patterns)] 
      sites 
1: www.google.com 
2: plus.google.com 
3: www.bbc.co.uk 
+0

'paste0(patterns,collapse =“|”)'当你有大量的模式时创建正则表达式。 – Marius

+0

查看我的说明 - 将它们放在一行中将不可行,paste0可能 – Iain

+0

如果将模式折叠为一个大模式比迭代模式列表更快或更慢,那么这将是很好的基准。 – thc