Цель: Использование R, получение данных широты и долготы для вектора адресов через open.mapquestapi
Точка отправления: Поскольку geocode
из пакета ggmap
ограничено 2500 запросами в день, мне нужно было найти другой способ (My data.frame состоит из 9M записей). Инструментарий по научным исследованиям данных не является вариантом, так как большинство моих адресов основаны за пределами Великобритании/США. Я нашел этот отличный фрагмент на http://rpubs.com/jvoorheis/Micro_Group_Rpres, используя open.mapquestapi.
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
Для добавления переменной latitude lat
и longitude lon
в data.frame мы могли бы работать с for
-Loop. Я представлю код, чтобы продемонстрировать, что функция работает в принципе.
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]
}
С точки зрения производительности этот код довольно плох. Даже для этого небольшого data.frame мой компьютер занял около 9 секунд, скорее всего, из-за запроса webservice, но неважно. Таким образом, я мог бы запустить этот код на своих девяти строках, но время было бы огромным.
Моя попытка состояла в использовании функции mutate
из пакета dplyr
.
Вот что я пробовал:
df %>%
mutate(lat = geocode_attempt(paste(street, postcode, city, country, sep=","))[1],
lon = geocode_attempt(paste(street, postcode, city, country, sep=","))[2])
system.time
останавливается всего на 2,3 секунды. Не плохо. Но вот проблема:
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
работает в ролях. Но здесь, lat и lon, вычисляются из первого ряда. Соответственно, первая строка верна. У кого-нибудь есть идея, почему? Код, который я предоставил, завершен. Ничего лишнего. Есть идеи? Если у вас есть альтернативный вариант, а не оптимизация моего кода, я был бы также благодарен.