2013-11-22 12 views
10

So habe ich die folgenden Daten, lassen Sie uns als „my_data“ sagen:Regular Expression in R mit einem negativen Lookbehind

Storm.Type 
TYPHOON 
SEVERE STORM 
TROPICAL STORM 
SNOWSTORM AND HIGH WINDS 

Was ich will ist zu klassifizieren, ob jedes Element in my_data $ Storm.Type ist ein Sturm, aber ich will nicht tropische Stürme wie Stürme sind (ich werde sie separat klassifizieren), so dass ich hätte

Storm.Type     Is.Storm 
TYPHOON      0 
SEVERE STORM     1 
TROPICAL STORM    0 
SNOWSTORM AND HIGH WINDS  1 

ich den folgenden Code geschrieben haben:

my_data$Is.Storm <- my_data[grep("(?<!TROPICAL) (?i)STORM"), "Storm.Type"] 

Aber das gibt den "SEVERE STORM" nur als Sturm zurück (aber ohne SNOWSTORM UND HOHE WINDS). Vielen Dank!

+0

Was ist der Sinn von '' in Ihrem regulären Ausdruck (i?)? Das Problem ist, dass Sie nach der Zeichenfolge '" STORM "' mit einem vorangestellten Leerzeichen suchen, so dass '" SNOWSTORM "nicht qualifiziert ist. –

+1

Hallo Blau. Während ich Bens Antwort akzeptiert habe, bist du tatsächlich mit MY-Code auf das Problem gestoßen. Ich möchte meinen Code so machen, dass er sich nicht um diesen Raum kümmert (wenn STORM also in THUNDERSTORM oder SNOWSTORM ist, möchte ich das ebenso wie STORM selbst). Weißt du, wie ich diesen Raum, den mein Code sucht, loswerden würde? Der Punkt der (? I) ist die Chance, dass jemand einen Sturm als "Sturm" oder "Storm" oder "Storm", usw. –

Antwort

8

Das Problem ist, dass Sie für die Zeichenfolge " STORM" mit einem vorhergehenden Leerzeichen suchen, so "SNOWSTORM" nicht qualifiziert.

Als fix, betrachten den Raum in Ihre negative Lookbehind Behauptung zu bewegen, etwa so:

ss <- c("TYPHOON","SEVERE STORM","TROPICAL STORM","SNOWSTORM AND HIGH WINDS", 
     "THUNDERSTORM") 
grep("(?<!TROPICAL)(?i)STORM", ss, perl = TRUE) 
# [1] 2 4 5 
grepl("(?<!TROPICAL)(?i)STORM", ss, perl = TRUE) 
# [1] FALSE TRUE FALSE TRUE TRUE 

Ich wusste nicht, dass (?i) und (?-i) einstellen, ob Sie Fall oder nicht in regex ignorieren. Cooler Fund. Eine andere Möglichkeit, es zu tun ist, die ignore.case Flagge:

grepl("(?<!tropical)storm", ss, perl = TRUE, ignore.case = TRUE) 
# [1] FALSE TRUE FALSE TRUE TRUE 

Dann definieren Sie Ihre Spalte:

my_data$Is.Storm <- grepl("(?<!tropical)storm", my_data$Storm.Type, 
          perl = TRUE, ignore.case = TRUE) 
+0

FANTASTISCH !!!!!!!!!! –

+1

Gern geschehen. Danke, dass du mir etwas über '(? I)' beigebracht hast. Ich bin es gewohnt, das 'ignore.case' Argument zu verwenden, aber' (? I) 'ist flexibler für allgemeine PCRE Ausdrücke. –

0

so etwas wie

x <- my_data$Storm.Type 
grep("STORM", x)[!grep("STORM", x)%in%grep("TROPICAL", x)] 
3

Ich bin nicht so gut im regexps auch nicht, aber was ist los mit

ss <- c("TYPHOON","SEVERE STORM","TROPICAL STORM","SNOWSTORM AND HIGH WINDS") 
grepl("STORM",ss) & !grepl("TROPICAL STORM",ss) 
## [1] FALSE TRUE FALSE TRUE 

...?

+0

Vielen Dank! Das hat definitiv funktioniert. –