— Jose Gonzalez

Using Google maps API and R

The White House This post shows how to use Google Maps‘ API with R making some tweaks to this function. Combine the first part with sapply or Plyr and it becomes a very powerful tool in just a few lines of code. You can find a gist in RMarkdown with the code here or click below to continue reading.

#### This script uses RCurl and RJSONIO to download data from Google's API:
#### Latitude, longitude, location type (see explanation at the end), formatted address
#### Notice ther is a limit of 2,500 calls per day

url <- function(address, return.call = "json", sensor = "false") {
 root <- "http://maps.google.com/maps/api/geocode/"
 u <- paste(root, return.call, "?address=", address, "&sensor=", sensor, sep = "")

geoCode <- function(address,verbose=FALSE) {
 if(verbose) cat(address,"\n")
 u <- url(address)
 doc <- getURL(u)
 x <- fromJSON(doc,simplify = FALSE)
 if(x$status=="OK") {
 lat <- x$results[[1]]$geometry$location$lat
 lng <- x$results[[1]]$geometry$location$lng
 location_type <- x$results[[1]]$geometry$location_type
 formatted_address <- x$results[[1]]$formatted_address
 return(c(lat, lng, location_type, formatted_address))
 } else {
##Test with a single address
#address #address
#[1] "38.8976831"
#[2] "-77.0364972"
#[4] "The White House, 1600 Pennsylvania Avenue Northwest, Washington, D.C., DC 20500, USA"

# Use plyr to ggeocoding for a vector
address <- c("The White House, Washington, DC", "The Capitol, Washington, DC")
locations <- ldply(address, function(x) geoCode(x))
names(locations) <- c("lat", "lon", "location_type", "formatted")
# lat lon location_type
# 1 38.8976831 -77.0364972 APPROXIMATE
# 2 38.8899389 -77.0090505 APPROXIMATE
# 1 The White House, 1600 Pennsylvania Avenue Northwest, Washington, D.C., DC 20500, USA
# 2 United States Capitol, East Capitol St NE & First St, Washington, D.C., DC 20004, USA

#Location type, for more info check here: https://developers.google.com/maps/documentation/directions/
#"ROOFTOP" indicates that the returned result is a precise geocode for which we have location information accurate down to street address precision.
#RANGE_INTERPOLATED" indicates that the returned result reflects an approximation (usually on a road) interpolated between two precise points (such as intersections). Interpolated results are generally returned when rooftop geocodes are unavailable for a street address.
#GEOMETRIC_CENTER" indicates that the returned result is the geometric center of a result such as a polyline (for example, a street) or polygon (region).
#APPROXIMATE" indicates that the returned result is approximate.

  1. Ajay Ohri says: September 3, 20136:44 pm

    Have you looked at the geocode function in ggmap package , i think yours is an enhancement

  2. Jose says: September 3, 20137:17 pm

    I didn’t know the one at ggmap. Although, some Python packages follow a similar structure like the one here. By the way… very cool that stamen maps can be used with ggmap.

  3. John says: September 3, 20138:06 pm

    Have you had any luck doing something similar with the Google Civics API? I’m having trouble getting it to do much of anything.

  4. Danny says: September 3, 201310:15 pm

    I’m relatively new to R, what’s so special about this map?

  5. andi says: September 5, 20139:24 am

    Can you plot a fragments of map?

  6. David says: December 27, 20134:39 pm

    Fairly new to geocoding and json but this code has been very helpful. Is it possible to return the street_name and street_number along with the lat, long, type and formatted address?

    • Jose says: December 27, 20138:28 pm

      You can get the formatted address, look here Not so sure about the street number, perhaps with the google places API..

  7. disqus_DeinPT0BCH says: October 15, 20146:29 pm

    did you know about the ggmap package? I’m trying to extract multiple results from a sigle search in google maps, any thoughs?

    • Jose Carlos Gonzalez says: October 20, 201412:51 pm

      ggmap works in a similar way. Maybe you can loop your queries ? Just check that you are not hitting the google maps ‘ API limit

      • Ricardo says: October 20, 20142:31 pm

        well, I made a loop but it seems that Google.maps doesn’t support ” instantaneous queries and give and error, but if I do debugging and run the code step by step it store the information perfectly.

        • APs says: December 4, 201511:31 am

          Hello. I have the same trouble. Were you able to find a solution at the end?

  8. Shane Davis says: February 11, 20155:15 pm

    Excellent article, thanks. I put a gist together implementing this solution with directions API if interested 😉

  9. Isaque Daniel Eberhardt says: December 16, 20159:24 pm

    Hi Jose, I have worked in “revgeocode” like you did using plyr package functions (because I have to do my PhD thesis and I have a lot of coords to check…), but it doesn’t work. Can you help me?

    #choosing random coordinates
    long.vet<-runif(1000, -48.15,-47.8)
    lat.vet<-runif(1000, -15.87,-15.7)
    # creating a list
    locations.list<-paste(points[,1],",",points[,2],sep="",colapse=" ")

    urlrevgeocode <- function(latlng, return.call = "json", sensor = "true") {
    root <- "http://maps.googleapis.com/maps/api/geocode/&quot;
    u <- paste(root, return.call, "?latlng=", latlng, "&sensor=", sensor, sep = "")

    reverseGeoCode <- function(latlng,verbose=FALSE) {
    if(verbose) cat(latlng,"n")
    u <- urlrevgeocode(latlng)
    doc <- getURL(u)
    x <- fromJSON(doc,simplify = FALSE)
    if(x$status=="OK") {
    lat <- x$results[[1]]$geometry$location$lat
    lng <- x$results[[1]]$geometry$location$lng
    formatted_address <- x$results[[1]]$formatted_address
    location_type <- x$results[[1]]$geometry$location_type
    return(c(lat, lng, formatted_address,location_type))
    } else {

    # applying the function
    locations <- ldply(locations.list, function(x) reverseGeoCode(x))

Submit comment