2016-09-11 6 views
2

BeispieldatenR - Suche alle Vektorelemente, die alle Strings/Muster enthalten - str_detect grep

files.in.path = c("a.4.0. name 2015 - NY.RDS", 
        "b.4.0. name 2016 - CA.RDS", 
        "c.4.0. name 2015 - PA.RDS") 
strings.to.find = c("4.0", "PA") 

Ich möchte die logische Vektor, der alle Elemente zeigt, die alle strings.to.find enthalten. Das Ergebnis wollte:

FALSE FALSE TRUE 

Dieser Code-Elemente finden, die eine beliebige der strings.to.find enthalten, das heißt, verwendet eine OR-Operator

str_detect(files.in.path, str_c(strings.to.find, collapse="|")) # OR operator 
TRUE TRUE TRUE 

Dieser Code versucht, einen AND-Operator zu verwenden, funktioniert aber nicht.

str_detect(files.in.path, str_c(strings.to.find, collapse="&")) # AND operator 
FALSE FALSE FALSE 

Dies funktioniert in mehreren Zeilen und ich kann eine for Schleife schreiben, die alle einzelnen Linien für die Fälle mit einer größeren Anzahl von strings.to.find

det.1 = str_detect(files.in.path,  "4.0" ) 
det.2 = str_detect(files.in.path,  "PA" ) 
det.all = det.1 & det.2 
FALSE FALSE TRUE 

generieren Aber gibt es eine bessere Art und Weise, die nicht der Fall ist Verwenden Sie Regex, die von der Position oder der Reihenfolge der strings.to.find abhängen. Diese

Antwort

2

Eine Suche der Bahn entweder ‚r regex‚und operaror‘‘ oder ‚regex‚und Operator‘‘ führen zu R grep: is there an AND operator? und Regular Expressions: Is there an AND operator? sind.

So beiden Muster passen die Saiten zusammen

str <- paste0("(?=.*", strings.to.find,")", collapse="") 
grepl(str, files.in.path, perl=TRUE) 

Wie Jota in Kommentar erwähnt durch Abgleichen „4.0“ diese andere stechen auch passen verketten als die Periode ein Metazeichen ist. Eine Lösung besteht darin, den Zeitraum in Ihrer Musterzeichenfolge zu verlassen, dh strings.to.find = c("PA", "4\\.0")

+0

@Jota; guter Punkt. Beispiel, 'grepl (" 4.0 "," 4 0 ")', also können wir vielleicht 'grepl (" 4 \\. 0 "," 4 0 ")' 'entkommen – user2957945

2

ist nicht für schweres Heben, aber str_detect ist sowohl über String und Muster vektorisiert, so können Sie es mit outer Funktion kombinieren Nähe etwas zu bekommen:

library(stringr) 
outer(files.in.path, strings.to.find, str_detect) 

#  [,1] [,2] 
#[1,] TRUE FALSE 
#[2,] TRUE FALSE 
#[3,] TRUE TRUE 

Um zu überprüfen, ob alle Muster in einem String existieren , apply der all logische Operator pro Zeile der resultierenden Matrix:

apply(outer(files.in.path, strings.to.find, str_detect), 1, all) 

#[1] FALSE FALSE TRUE 

Oder wie pro @Jota kommentierte stri_detect_fixed wird sicherer sein, hier zu verwenden, wenn das Muster, das Sie Klo sind König bei sollte genau abgestimmt werden:

library(stringi) 
apply(outer(files.in.path, strings.to.find, stri_detect_fixed), 1, all) 
# [1] FALSE FALSE TRUE