我正在尝试对存储在字符向量中的一些地址进行地理编码。我在geocode()
中使用了ggmaps
函数;但是,它只对我的地址的50%进行了分类。我希望使用更基本的方法来查找城市名称(来自world.cities
包中的maps
数据是否在我的地址列表中,如果是,请从中获取经度和纬度信息这个查找表。我会尝试清理返回的文件,并用R提供的其他地理编码方法(调用各种外部API)来补充它。到目前为止我编写的内容如下:
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中的其他任务一样,我认为可以使用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
基本上,逻辑是:
geocode()
和其他服务,以获得更好的信息。geocode()
等填写所有内容(实际上我只想要长/纬度)。这就是亚特兰大乔治亚州的例子。 关于一般方法的思考以及如何在R中做得更好?如上所述,这种方法的动力是看我是否可以补充我已经获得的东西(使用geocode()
函数的50%地理编码地址)
答案 0 :(得分: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
作为一步),但它会让你更进一步,并且应该更快一点。