Google Maps and R
They say if you are asked something once, just respond via email, but if you get asked twice, then blog about it. I’m taking that approach with this one by showing how to get times and distances using the Google Maps API for both R and Python (if you’re looking for the Python version, you can find it here). I’ve had to help provide drive distances and times on numerous occasions, often provided in a large Excel file of cities and countries or postal codes. Clearly, nobody wants to go about placing each item into Google Maps and then entering that value back into their spreadsheet. Who has time for that? Typically, this comes in the form of a bunch of cities or postal codes to get distances to and from, so let’s put a data frame together with these pairs.
library(knitr)
locations = data.frame(origin_city = c("Hamburg", "Toronto", "Sucre", 
                                       "Jaipur", "Wellington"),
                       origin_country = c("Germany", "Canada", "Bolivia",
                                          "India", "New Zealand"),
                       destination_city = c("Zurich", "New York", "Santiago",
                                            "Bengaluru", "Auckland"),
                       destination_country = c("Switzerland", "USA", "Chile",
                                               "India", "New Zealand"))
kable(locations, "markdown", align = "l")
origin_city origin_country destination_city destination_country
Hamburg Germany Zurich Switzerland
Toronto Canada New York USA
Sucre Bolivia Santiago Chile
Jaipur India Bengaluru India
Wellington New Zealand Auckland New Zealand
In my opinion, the best package to use for this is gmapsdistance. Just like for Python's package, you can get an API key to here. Unlike the Python version, I’ve actually found that the key isn’t always necessary for whatever reason. Keep in mind that you only have 2,500 free calls to the API per day. So if you have additional distances to calculate, then consider paying for it, or spreading your load across multiple days (or get a friend’s key, whatever works).
library(gmapsdistance)
key <- "Your Key Here!"
We’ll need to do one thing to our data, and that’s combine the city and country names with ‘+’ and fill in any blanks.
origin <- gsub(" ", "+", 
                         paste(
                           locations$origin_city, locations$origin_country, 
                           sep = "+"))
destination <- gsub(" ", "+", 
                         paste(
                           locations$destination_city, locations$destination_country, 
                           sep = "+"))
locs <- data.frame(origin, destination)
kable(locs, "markdown", align = "l")
origin destination
Hamburg+Germany Zurich+Switzerland
Toronto+Canada New+York+USA
Sucre+Bolivia Santiago+Chile
Jaipur+India Bengaluru+India
Wellington+New+Zealand Auckland+New+Zealand
With the data ready, we’re set to send it to the Google Maps API. Implementation of this is incredibly straightforward and easy to use. You could simply call it and apply it to the vectors in the data frame, but you’d get values for each city combination, and not all of them have driving distances between them considering many are on different continents. Plus, that may not always be necessary and you have a limited number of calls to the API you can make anyway. So it’s better to be wise about how you use them. You’ll notice too, that the result is a list of three, which gives the estimated time it takes, distance, and status (i.e. whether a route exists or not). If you want any one of these in particular, you can extract them by indexing the list or using $Time, $Distance, $Status.
results <- t(mapply(function(x, y) gmapsdistance(origin = x,
                                    destination = y,
                                    mode = "driving"),
       locs$origin, locs$destination))
rownames(results) <- NULL
locations <- cbind(locations, results)
kable(locations, "markdown", align = "l")
origin_city origin_country destination_city destination_country Time Distance Status
Hamburg Germany Zurich Switzerland 30143 865780 OK
Toronto Canada New York USA 28028 789792 OK
Sucre Bolivia Santiago Chile 99951 2318802 OK
Jaipur India Bengaluru India 117000 2001939 OK
Wellington New Zealand Auckland New Zealand 28403 642828 OK
The time is given in minutes and the distances are in meters by default, so convert those units however you like. Overall, great and easy package to use!