Регулярное выражение в R с отрицательным lookbehind

Итак, у меня есть следующие данные, например, "my_data":

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

Я хочу, чтобы классифицировать, является ли каждый элемент в my_data $Storm.Type штормом, НО я не хочу включать тропические штормы в виде штормов (я собираюсь их классифицировать отдельно), так что я будет

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

Я написал следующий код:

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

Но это только возвращает "SEVERE STORM" как шторм (но не оставляет SNOWSTORM AND HIGH WINDS). Спасибо!

Ответ 1

Проблема в том, что вы ищете строку " STORM" с предыдущим пространством, поэтому "SNOWSTORM" не подходит.

В качестве исправления рассмотрим перемещение пространства в ваше отрицательное утверждение lookbehind, например:

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

Я не знал, что (?i) и (?-i) установлено, игнорируете ли вы регистр или нет в regex. Крутая находка. Другой способ сделать это - флаг ignore.case:

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

Затем определите свой столбец:

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

Ответ 2

Я тоже не очень хорошо разбираюсь в регулярных выражениях, но что не так с

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

...?

Ответ 3

что-то вроде

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