Как извлечь 1 или 2 слова перед n цифрами? - PullRequest
2 голосов
/ 17 марта 2019

У меня есть этот образец данных:

address <- c("11537 W LARKSPUR RD EL MIRAGE 85335", "6702 E CPT DREYFUS SCOTTSDALE 85254", "114 S PUEBLO ST GILBERT 85233", "16981 W YOUNG ST SURPRISE 85388")
person <- c("Maria", "Jose", "Adan", "Eva")

my_address <- tibble(person, address)

Мне нужно извлечь city из столбца address. Город может состоять из 1 слова или 2, но они всегда перед почтовым индексом, состоящим из 5 цифр .

Из фрейма данных я хотел бы получить: "EL MIRAGE", "SCOTTSDALE" и "GILBERT" в новом столбце: city

Важно:

Города всегда после 2 или 3 буквенных слов, таких как: ST, AVE, RD.

Например, от: «16981 W YOUNG ST SURPRISE 85388». Я хотел бы получить СЮРПРИЗ, который стоит после "ST".

Итак, я пробовал это регулярное выражение:

my_address$city <-gsub("(.*)([a-zA-Z])([0-9]{5})(.*)", "\\2", my_address$address)

Но он возвращает весь текст в столбце, а не нужные города. Кроме того, я заметил, что я не поручил ему проверять 1 или 2 слова перед 5 цифрами, поэтому он будет извлекать только 1 слово?

ОБНОВЛЕНИЕ 1:

string1 <- "114 S PUEBLO ST GILBERT 85233"
sapply(stringr::str_extract_all(string1,"\\w{4,}"),"[",3)

возвращает: 85233, когда ожидалось GILBERT.

Ответы [ 2 ]

2 голосов
/ 17 марта 2019

Это решение dplyr + stringr / tidyverse основано на том факте, что вы знаете, какие 2-3 буквенные слова предшествовали городу ...

# vector with  2-3 letter words before a city?
v.before <- c("ST", "RD", "AVE")
#with this vector, we can build an 'or'-pattern for a regex    

library( dplyr )
library( stringr )
data.frame( person, address) %>% 
  mutate( place = stringr::str_extract( address, paste0("(?<=", paste0(v.before, collapse = " |" ), " ).*(?= [0-9]{5})") ) ) %>%
  #no match found?, then the city is the second last word from address
  mutate( place = ifelse( is.na( place ), stringr::word(address, -2), place))

#   person                             address      place
# 1  Maria 11537 W LARKSPUR RD EL MIRAGE 85335  EL MIRAGE
# 2   Jose 6702 E CPT DREYFUS SCOTTSDALE 85254 SCOTTSDALE
# 3   Adan       114 S PUEBLO ST GILBERT 85233    GILBERT
# 4    Eva     16981 W YOUNG ST SURPRISE 85388   SURPRISE
2 голосов
/ 17 марта 2019

Обычно предпочитают один вкладыш, хотя это кажется слишком сложным и потребует еще один шаг, чтобы удалить «ST» перед «СЮРПРИЗ».Это было сделано при условии, что все начинается с "ST".

 library(stringr)
 new_s<-unlist(str_extract_all(my_address$address,"\\w{2,} \\w{3,}"))
 newer_s<-str_remove_all(new_s,"^\\w{3}.*\\D$")
 newer_s<-str_remove_all(newer_s,"\\s.*\\d")
 res<-str_remove_all(newer_s,"^ST ")
 res[res==""]<-NA 
 my_address$city<-res[complete.cases(res)]

Результат:

 my_address
# A tibble: 4 x 3
#  person address                             city      
#  <chr>  <chr>                               <chr>     
#1 Maria  11537 W LARKSPUR RD EL MIRAGE 85335 EL MIRAGE 
#2 Jose   6702 E CPT DREYFUS SCOTTSDALE 85254 SCOTTSDALE
#3 Peter  16981 W YOUNG ST SURPRISE 85388     SURPRISE  
#4 Paul   114 S PUEBLO ST GILBERT 85233       GILBERT 

Данные:

address <- c("11537 W LARKSPUR RD EL MIRAGE 85335", "6702 E CPT DREYFUS SCOTTSDALE 85254",
             "16981 W YOUNG ST SURPRISE 85388","114 S PUEBLO ST GILBERT 85233")
person <- c("Maria", "Jose","Peter","Paul")

my_address <- tibble::tibble(person, address)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...