目的:使用R,获得纬度和经度的数据地址的矢量通过open.mapquestapi地理编码一批地址与开放mapquestapi
出发点:由于geocode
从ggmap
包被限制到一天2500个查询,我需要找到一个不同的方式(我的data.frame由9M条目组成)。数据科学工具包不是一种选择,因为我的大部分地址都位于英国/美国以外。我使用open.mapquestapi在http://rpubs.com/jvoorheis/Micro_Group_Rpres上发现了这个优秀片段。
geocode_attempt <- function(address) {
URL2 = paste("http://open.mapquestapi.com/geocoding/v1/address?key=", "Fmjtd%7Cluub2huanl%2C20%3Do5-9uzwdz",
"&location=", address, "&outFormat='json'", "boundingBox=24,-85,50,-125",
sep = "")
# print(URL2)
URL2 <- gsub(" ", "+", URL2)
x = getURL(URL2)
x1 <- fromJSON(x)
if (length(x1$results[[1]]$locations) == 0) {
return(NA)
} else {
return(c(x1$results[[1]]$locations[[1]]$displayLatLng$lat, x1$results[[1]]$locations[[1]]$displayLatLng$lng))
}
}
geocode_attempt("1241 Kincaid St, Eugene,OR")
我们需要这些库:
library(RCurl)
library(rjson)
library(dplyr)
让我们创建一个实物模型data.frame 5不会忽略。
id <- c(seq(1:5))
street <- c("Alexanderplatz 10", "Friedrichstr 102", "Hauptstr 42", "Bruesseler Platz 2", "Aachener Str 324")
postcode <- c("10178","10117", "31737", "50672", "50931")
city <- c(rep("Berlin", 2), "Rinteln", rep("Koeln",2))
country <- c(rep("DE", 5))
df <- data.frame(id, street, postcode, city, country
对于添加纬度lat
和经度lon
变量,我们可以用一个for
-loop工作data.frame。我将介绍这些代码,只是为了说明该功能在原理上起作用。
for(i in 1:5){
df$lat[i] <- geocode_attempt(paste(df$street[i], df$postcode[i], df$city[i], df$country[i], sep=","))[1]
df$lon[i] <- geocode_attempt(paste(df$street[i], df$postcode[i], df$city[i], df$country[i], sep=","))[2]
}
从性能的角度来看,这段代码非常糟糕。即使对于这个小的数据框架,我的电脑也花了大约9秒,很可能是因为web服务查询,但没关系。所以我可以在我的9M行上运行这些代码,但时间会很长。
我的尝试是利用dplyr
包中的mutate
函数。 这里是我的尝试:在只有2.3秒
df %>%
mutate(lat = geocode_attempt(paste(street, postcode, city, country, sep=","))[1],
lon = geocode_attempt(paste(street, postcode, city, country, sep=","))[2])
system.time
停止。不错。但现在的问题是:
id street postcode city country lat lon
1 1 Alexanderplatz 10 10178 Berlin DE 52.52194 13.41348
2 2 Friedrichstr 102 10117 Berlin DE 52.52194 13.41348
3 3 Hauptstr 42 31737 Rinteln DE 52.52194 13.41348
4 4 Bruesseler Platz 2 50672 Koeln DE 52.52194 13.41348
5 5 Aachener Str 324 50931 Koeln DE 52.52194 13.41348
lat
和lon
正是所有条目的相同。在我的理解中,mutate
函数正在逐行工作。但在这里,纬度和经度是从第一行算起的。因此,第一行是正确的。有没有人有一个想法,为什么?我提供的代码是完整的。没有额外的加载。有任何想法吗?如果你有一个高性能的替代方法,而不是优化我的代码,我会很感激。
@NicE提供的查询如何最终为您的9M行工作?是你能够进行地理编码所有实例的时间相对较少,还是你击中MapQuest的限制? – bshelt141 2017-05-12 11:57:28