2014-09-12 62 views
2

我想對一些存儲在字符向量中的地址進行地理編碼。我在ggmaps中使用了geocode()函數;但是,它只分類了我地址的大約50%。我希望能夠使用更基本的方法來查看城市名稱(來自maps包中的world.cities數據是否在我的地址列表中,如果是,請從此查找表中獲取經度和緯度信息。 。清理返回的文件,並與其他地理編碼方法補充它(調用各種外部API的)的R提供什麼我迄今編碼低於:地理編碼地址在R:grep()查找world.cities數據集

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多個城市,所以雙循環方法有點慢。與RI中的其他任務一樣,假設這可能是與應用家庭的某些成員進行矢量化年。我在如何做到這一點時遇到了麻煩。有什麼想法嗎?

### 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. 如果地方字符串包含多個單詞但國家不匹配任何其他單詞,如美國牛津。然後製作除了城市NA之外的所有東西在這裏,我會嘗試與geocode()和其他服務的運氣,以獲得更好的信息。
  4. 如果地址地址永遠不在查找字典中,請添加它,然後嘗試使用geocode()等來填充所有內容(實際上我只想要長/拉特)。這就是Atlanta Georgia的例子。

關於一般方法和如何在R中做得更好的想法?如上所述,這種方法的動力是看我是否能補足我已經得到的東西(使用geocode()函數的50%地址編碼地址)

回答

2

這使得城市提取更通用(使用字符串正則表達式匹配),然後執行與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爲一步),但它可以讓你進一步,應該是快了些。

+0

'lapply()'示例和正則表達式預清理是有幫助的提示!謝謝!! – Chris 2014-09-12 21:10:37