Cel: Korzystanie R, dostać szerokości i długości geograficznej danych dla wektora adresów poprzez open.mapquestapiadresy partii przetwarzania danych geograficznych w R z otwartym mapquestapi
punkt wyjścia: Od geocode
z pakietu ggmap
jest ograniczone do 2500 zapytań dziennie, musiałem znaleźć inny sposób (Moja data.frame składa się z 9M wpisów). Zestaw narzędzi do nauki danych nie wchodzi w grę, ponieważ większość moich adresów znajduje się poza Wielką Brytanią/USA. Znalazłem ten wspaniały fragment na http://rpubs.com/jvoorheis/Micro_Group_Rpres z wykorzystaniem 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")
Potrzebujemy tych bibliotek:
library(RCurl)
library(rjson)
library(dplyr)
Stwórzmy mock-up data.frame z 5 adresów.
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
Przez dodanie zmienną szerokość i długość geograficzna lon
lat
do data.frame mogliśmy pracować z for
-loop. Przedstawię kod, aby pokazać, że funkcja działa w zasadzie.
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]
}
Z punktu widzenia wydajności ten kod jest dość zły. Nawet dla tego małego pliku data.frame mój komputer trwał około 9 sekund, najprawdopodobniej z powodu zapytania do usługi sieciowej, ale nieważne. Mógłbym uruchomić ten kod w moich wierszach 9M, ale czas byłby olbrzymi.
Moja próba polegała na wykorzystaniu funkcji mutate
z pakietu dplyr
. Oto, co starałem:
df %>%
mutate(lat = geocode_attempt(paste(street, postcode, city, country, sep=","))[1],
lon = geocode_attempt(paste(street, postcode, city, country, sep=","))[2])
system.time
przystanki w zaledwie 2,3 sekundy. Nieźle. Ale tutaj jest problem:
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
i lon
są dokładnie takie same dla wszystkich wpisów. W moim rozumieniu funkcja mutate
działa w sposób wierszowy. Ale tutaj, lat i lon są obliczane z pierwszego rzędu. W związku z tym pierwszy wiersz jest poprawny. Czy ktoś ma pomysł, dlaczego? Podany przeze mnie kod jest kompletny. Nic ekstra załadowanego. Jakieś pomysły? Jeśli masz alternatywny sposób działania zamiast optymalizacji mojego kodu, również byłbym wdzięczny.
W jaki sposób zapytanie dostarczone przez @NicE zakończyło pracę dla twoich wierszy 9M? czy byłeś w stanie geokodować wszystkie instancje w stosunkowo niewielkim czasie, czy też trafiłeś w MapQuest? – bshelt141