2017-07-03 2 views
1

Ich versuche, Werte in einer data.table mit einem Vektor zu vergleichen, der mehrere Muster enthält. Die Demo-Code, den ich habe, ist:Effiziente Regexp-Anpassung mit einem Mustervektor

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] 

die korrekt zurückgibt:

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

jedoch, weil diese eine verschachtelte sapply enthält, ist es sehr langsam mit größeren data.tables laufen.

Gibt es eine effizientere Möglichkeit, dies zu tun, die mit größeren Tabellen funktioniert?

+0

HINWEIS: In dem eigentlichen Code, 'patterns' hat ein paar hundert Artikel und die Regex gehören Dinge wie Look-Behinds, also wäre es nicht praktisch, sie in eine Linie zu setzen. – Iain

Antwort

3

Wenn Sie nach mehreren Mustern suchen, warum kombinieren Sie die Muster nicht mit einer or Syntax? Wie @Marius andeutet, kann dies unter Verwendung von paste0(patterns, collapse = "|") erstellt werden, wenn Sie viele zu überprüfende Muster haben.

Zum Beispiel

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

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

mit Ihrer data.table Use-Case zu halten, vielleicht

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 =" | ")' um die Regex zu erstellen, wenn Sie eine große Anzahl von Mustern haben. – Marius

+0

Siehe meine Klarstellung - sie in eine Zeile zu setzen wäre nicht praktikabel, die Paste0 könnte man aber – Iain

+0

Es wäre gut zu benchmarken, ob das Kollabieren der Muster in ein großes Muster schneller oder langsamer ist als das Durchlaufen einer Liste von Mustern. – thc