извлечение информации о городе и штате из почтового адреса Google

У меня есть набор данных, содержащий информацию о широте и долготе для разных местоположений точек, и я хотел бы знать, какой город и штат связаны с каждой точкой.

Следуя этому примеру, я использовал функцию revgeocode из ggmap чтобы получить почтовый адрес для каждого местоположения, создав следующий фрейм данных:

df <- structure(list(PointID = c(1787L, 2805L, 3025L, 3027L, 3028L, 
3029L, 3030L, 3031L, 3033L), Latitude = c(38.36648102, 36.19548585, 
43.419774, 43.437222, 43.454722, 43.452643, 43.411949, 43.255479, 
43.261464), Longitude = c(-76.4802046, -94.21554661, -87.960399, 
-88.018333, -87.974722, -87.978542, -87.94149, -87.986433, -87.968612
), Address = structure(c(2L, 8L, 5L, 3L, 9L, 7L, 4L, 1L, 6L), .Label = c("13004 N Thomas Dr, Mequon, WI 53097, USA", 
"2160 Turner Rd, Lusby, MD 20657, USA", "2805 County Rd Y, Saukville, WI 53080, USA", 
"3701-3739 County Hwy W, Saukville, WI 53080, USA", "3907 Echo Ln, Saukville, WI 53080, USA", 
"4823 W Bonniwell Rd, Mequon, WI 53097, USA", "5100-5260 County Rd I, Saukville, WI 53080, USA", 
"7948 W Gibbs Rd, Springdale, AR 72762, USA", "River Park Rd, Saukville, WI 53080, USA"
), class = "factor")), row.names = c(NA, -9L), class = "data.frame", .Names = c("PointID", 
"Latitude", "Longitude", "Address"))

Я хотел бы использовать R для извлечения информации о городе / штате из полного адреса и создать два столбца для хранения этой информации («Город» и «Штат»).

Я предполагаю, что пакет stringr - это то, что нужно, но я не уверен, как его использовать. В приведенном выше примере использовался следующий код для извлечения почтовый индекс (в этом примере он называется "результат"). Их набор данных:

#       ID Longitude  Latitude                                         result
# 1 311175  41.29844 -72.92918 16 Church Street South, New Haven, CT 06519, USA
# 2 292058  41.93694 -87.66984  1632 West Nelson Street, Chicago, IL 60657, USA
# 3  12979  37.58096 -77.47144    2077-2199 Seddon Way, Richmond, VA 23230, USA

И код для извлечения почтового индекса:

library(stringr)
data$zipcode <- substr(str_extract(data$result," [0-9]{5}, .+"),2,6)
data[,-4]

Можно ли легко изменить приведенный выше код для получения данных о городе и штате?


person Jason    schedule 16.08.2017    source источник
comment
вы получили много отличных ответов ниже. Вы можете выбрать вариант (галочка слева), который больше всего помог вам решить вашу проблему. Это позволит сообществу узнать, что это сработало для вас, и выразить признательность за помощь сообщества.   -  person CPak    schedule 14.09.2017


Ответы (3)


Вы можете получить город и штат, используя сам revgeocode():

df <- cbind(df,do.call(rbind,
               lapply(1:nrow(df),
               function(i) 
               revgeocode(as.numeric(
               df[i,3:2]), output = "more")[c("administrative_area_level_1","locality")])))

df

#   PointID Latitude Longitude                                          Address 
# 1    1787 38.36648 -76.48020             2160 Turner Rd, Lusby, MD 20657, USA 
# 2    2805 36.19549 -94.21555       7948 W Gibbs Rd, Springdale, AR 72762, USA 
# 3    3025 43.41977 -87.96040           3907 Echo Ln, Saukville, WI 53080, USA 
# 4    3027 43.43722 -88.01833       2805 County Rd Y, Saukville, WI 53080, USA 
# 5    3028 43.45472 -87.97472          River Park Rd, Saukville, WI 53080, USA 
# 6    3029 43.45264 -87.97854  5100-5260 County Rd I, Saukville, WI 53080, USA 
# 7    3030 43.41195 -87.94149 3701-3739 County Hwy W, Saukville, WI 53080, USA 
# 8    3031 43.25548 -87.98643         13004 N Thomas Dr, Mequon, WI 53097, USA 
# 9    3033 43.26146 -87.96861       4823 W Bonniwell Rd, Mequon, WI 53097, USA 
#   administrative_area_level_1   locality 
# 1                    Maryland      Lusby 
# 2                    Arkansas Springdale 
# 3                   Wisconsin  Saukville 
# 4                   Wisconsin  Saukville 
# 5                   Wisconsin  Saukville 
# 6                   Wisconsin  Saukville 
# 7                   Wisconsin  Saukville 
# 8                   Wisconsin     Mequon 
# 9                   Wisconsin     Mequon

P.S. Вы можете сделать все (включая получение адреса и / или почтового индекса) за один шаг. Просто добавьте "address" или / и "postal_code" к c("administrative_area_level_1","locality"), который представляет собой список переменных, которые вы хотите извлечь.

person M--    schedule 16.08.2017

Если вы хотите использовать Stringr, вы можете сделать это:

library(stringr)
library(data.table)

parse_address <- function(address){

  address <- address %>% 
    str_split(",") %>% 
    .[[1]]
  state <- address %>% 
    .[3] %>% 
    str_replace_all("[^A-Z]","")

  zip <- address %>% 
    .[3] %>% 
    str_replace_all("[^0-9]","")

  city <- address %>% 
    .[2] %>% 
    str_trim()

  street <- address %>% 
    .[1] %>% 
    str_trim()

  data.table(street, city, state, zip)
}

lapply(df$Address, parse_address) %>% 
  rbindlist
person be_green    schedule 16.08.2017

1) sub Используйте sub вот так. Пакеты не нужны.

Регулярное выражение соответствует началу (^), за которым следует самая короткая строка, до запятой и пробела, за которым следует самая короткая строка (представляющая город), до следующей запятой и пробела, за которыми следуют два символа (представляющие состояние), пробел, 5 символов ( представляет почтовый индекс), запятую, пробел, США и конец строки. На совпадения с частями в скобках можно ссылаться через \ 1, \ 2 и \ 3, но в двойных кавычках \ необходимо удвоить.

Если ваш почтовый индекс не состоит из пяти цифр, попробуйте pat <- "^.*?, (.*?), (..) (.*), USA$".

pat <- "^.*?, (.*?), (..) (.....), USA$"
transform(df, City = sub(pat, "\\1", Address), 
              State = sub(pat, "\\2", Address), 
              Zip = sub(pat, "\\3", Address))

давая:

  PointID Latitude Longitude                                          Address       City State   Zip
1    1787 38.36648 -76.48020             2160 Turner Rd, Lusby, MD 20657, USA      Lusby    MD 20657
2    2805 36.19549 -94.21555       7948 W Gibbs Rd, Springdale, AR 72762, USA Springdale    AR 72762
3    3025 43.41977 -87.96040           3907 Echo Ln, Saukville, WI 53080, USA  Saukville    WI 53080
4    3027 43.43722 -88.01833       2805 County Rd Y, Saukville, WI 53080, USA  Saukville    WI 53080
5    3028 43.45472 -87.97472          River Park Rd, Saukville, WI 53080, USA  Saukville    WI 53080
6    3029 43.45264 -87.97854  5100-5260 County Rd I, Saukville, WI 53080, USA  Saukville    WI 53080
7    3030 43.41195 -87.94149 3701-3739 County Hwy W, Saukville, WI 53080, USA  Saukville    WI 53080
8    3031 43.25548 -87.98643         13004 N Thomas Dr, Mequon, WI 53097, USA     Mequon    WI 53097
9    3033 43.26146 -87.96861       4823 W Bonniwell Rd, Mequon, WI 53097, USA     Mequon    WI 53097

2) read.pattern. Другой вариант - read.pattern с тем же pat, что и выше:

library(gsubfn)

cn <- c("City", "State", "Zip")
Address <- as.character(df$Address)
cbind(df, read.pattern(text = Address, pattern = pat, as.is = TRUE, col.names = cn))
person G. Grothendieck    schedule 16.08.2017