Регулярное выражение в 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)]