Геокод адреса в R: grep() набор данных world.cities

Я пытаюсь геокодировать некоторые адреса, хранящиеся в символьных векторах. Я использовал geocode() функция в ggmaps; однако, это только классифицировало приблизительно 50% моих адресов. Я надеялся использовать более рудиментарный подход при поиске названия города (из world.cities данные в maps Пакет находится в моем списке адресов, и если да, то берет информацию о долготе и широте из этой таблицы поиска. Я попытаюсь очистить возвращенный файл и дополнить его другими подходами геокодирования (вызовами различных внешних API), которые предоставляет R. То, что я кодировал до сих пор, ниже:

places <- c("Atlanta,Georgia", "My house, Paris, France", "Some Other House, Paris, Ontario, Canada", "Paris", "Oxford", "Oxford, USA")

library(maps)
data(world.cities)
ddd <- world.cities[world.cities$name %in% c("Paris","Oxford","New York"),]

is.integer0 <- function(x) {
is.integer(x) && length(x) == 0L
}

for (i in 1:length(places)) {
  for (j in 1:dim(ddd)[1]) {
  k <- ddd$name[j]
    if (is.integer0(grep(k,places[i],perl=TRUE))==TRUE) next
      if (exists("zzz")==FALSE) {
        zzz <- cbind(places[i],ddd[j,1:5])
      } else {
        zzz <- rbind(zzz,cbind(places[i],ddd[j,1:5])) 
      } 
  }
}

Выход - то, что я хочу (я субъективно уберу это позже). Моя проблема в том, что мои реальные данные о 8000 адресов и world.cities данные о 40000+ городах, так что двойной подход к циклу немного медленный. Как и в случае с другими задачами в R I, предполагается, что это может быть векторизовано некоторым членом семейства apply. У меня проблемы с тем, как я могу это сделать. Какие-нибудь мысли?

### Output
                                      places[i]   name country.etc     pop    lat  long
28245                   My house, Paris, France  Paris      Canada   10570  43.20  0.38
28246                   My house, Paris, France  Paris      France 2141839  48.86   2.34
282451 Some Other House, Paris, Ontario, Canada  Paris      Canada   10570  43.20 -80.38
282461 Some Other House, Paris, Ontario, Canada  Paris      France 2141839  48.86   2.34
282452                                    Paris  Paris      Canada   10570  43.20 -80.38
282462                                    Paris  Paris      France 2141839  48.86   2.34
27671                                    Oxford Oxford      Canada    1271  45.73 -63.87
27672                                    Oxford Oxford New Zealand    1816 -43.30 172.18
27673                                    Oxford Oxford          UK  157568  51.76  -1.26
276711                              Oxford, USA Oxford      Canada    1271  45.73 -63.87
276721                              Oxford, USA Oxford New Zealand    1816 -43.30 172.18
276731                              Oxford, USA Oxford          UK  157568  51.76  -1.26

После некоторой дальнейшей очистки данных мне бы очень хотелось:

### Output
                                      places[i]   name country.etc     pop    lat  long
 28246                   My house, Paris, France  Paris      France 2141839  48.86   2.34
282451 Some Other House, Paris, Ontario, Canada  Paris      Canada   10570  43.20 -80.38
282462                                    Paris  Paris      France 2141839  48.86   2.34
27673                                    Oxford Oxford          UK  157568  51.76  -1.26
276731                              Oxford, USA Oxford          NA       NA    NA  NA
                               Atlanta, Georgia     NA          NA       NA    NA  NA

По сути, логика такова:

  1. Если страна также совпадает со строкой мест, сохраните эту строку. Париж, Франция и Париж, Канада, примеры.
  2. Если строка мест содержит одно слово, то предположите, что он относится к городу с наибольшим населением. Так что по умолчанию Париж - Париж, Франция и Оксфорд - Оксфорд, Великобритания. Поскольку трудно геокодировать неуникальный адрес.
  3. Если строка мест содержит более одного слова, но Страна не соответствует ни одному из этих других слов, например Оксфорд, США. Тогда сделайте все, кроме города Н.А. Здесь я попробую свою удачу с geocode() и другие услуги, чтобы получить лучшую информацию.
  4. Если адрес мест никогда не был в поисковом словаре, добавьте его, а затем попробуйте заполнить все (на самом деле я хочу только long/lat), используя geocode() и т.д. Вот пример Атланты Джорджия.

Мысли о подходе в целом, и как сделать лучше в R? Как упомянуто выше, стимулом для этого подхода было узнать, смогу ли я дополнить то, что уже получил (50% геокодированных адресов с geocode() функция)

1 ответ

Решение

Это делает извлечение города более общим (использует сопоставление с регулярным выражением строки), а затем выполняет слияние с world.cities данные:

places_dat <- cbind(places, Reduce(rbind, 
                lapply(str_match_all(places, ",*\ *([[:alpha:]]+)\ *,\ *([[:alpha:]]+)\ *$"),
                  function(x) {

  if (length(x) == 0) {
    return(data.frame(city=NA, state=NA))
  } else {
    return(data.frame(city=x[,2], state=x[,3]))
  }

})))

places_dat

##                                     places    city   state
## 1                          Atlanta,Georgia Atlanta Georgia
## 2                  My house, Paris, France   Paris  France
## 3 Some Other House, Paris, Ontario, Canada Ontario  Canada
## 4                                    Paris    <NA>    <NA>
## 5                                   Oxford    <NA>    <NA>
## 6                              Oxford, USA  Oxford     USA
## 

merge(places_dat, world.cities, by.x="city", by.y="name", all.x=TRUE)

##      city                                   places   state country.etc     pop    lat    long capital
## 1 Atlanta                          Atlanta,Georgia Georgia         USA  424096  33.76  -84.42       0
## 2   Paris                  My house, Paris, France  France      France 2141839  48.86    2.34       1
## 3   Paris                  My house, Paris, France  France      Canada   10570  43.20  -80.38       0
## 4 Ontario Some Other House, Paris, Ontario, Canada  Canada         USA  175805  34.05 -117.61       0
## 5  Oxford                              Oxford, USA     USA      Canada    1271  45.73  -63.87       0
## 6  Oxford                              Oxford, USA     USA New Zealand    1816 -43.30  172.18       0
## 7  Oxford                              Oxford, USA     USA          UK  157568  51.76   -1.26       0
## 8    <NA>                                    Paris    <NA>        <NA>      NA     NA      NA      NA
## 9    <NA>                                   Oxford    <NA>        <NA>      NA     NA      NA      NA

Это все еще требует некоторого просеивания (возможно complete.cases в качестве одного шага), но это продвигает вас дальше и должно быть немного быстрее.

Другие вопросы по тегам