<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="http://www.r-bloggers.com/placement-an-r-package-to-access-the-google-maps-api/"></div></div><div><a data-url="http://www.r-bloggers.com/placement-an-r-package-to-access-the-google-maps-api/" data-counturl="http://www.r-bloggers.com/placement-an-r-package-to-access-the-google-maps-api/" data-count="horizontal" data-text="Placement: An R package to Access the Google Maps API" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://derekyves.github.io/2016/07/24/placement-pkg.html"> R from Stata</a></strong>, and kindly contributed to <a rel="nofollow" href="http://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>A few months ago I set out to write an R package for accessing the Maps API with<br>
my employer’s (paid) <a target="_blank" href="https://developers.google.com/maps/documentation/directions/get-api-key#premium-auth">Google for Work/Premium account</a>. At the time, I was unable to find an R package that could generate the encrypted signature, send the URL to Google and process the JSON returns in one fell swoop. Following Google’s <a target="_blank" href="https://github.com/googlemaps/google-maps-services-python">directions for Python</a>, however, I was able to create an R function that creates valid signatures for a URL request using the <a target="_blank" href="https://cran.r-project.org/web/packages/digest/index.html"><code>digest</code></a> package’s implementation of the <em>sha-1</em> algorithm. Along the way I added a few additional features that are useful in our workgroup, including (1) a function to retrieve Google Map’s distance and travel time estimates (via public transit, driving, cycling, or walking) between two places (<a target="_blank" href="https://github.com/DerekYves/placement/blob/master/R/drive_time.R"><code>drive_time</code></a>), (2) a general purpose function for stripping address vectors of nasty characters that may break a geocode request (<a target="_blank" href="https://github.com/DerekYves/placement/blob/master/R/address_cleaner.R"><code>address_cleaner</code></a>), and (3) methods for accessing the Google API with a (free) standard account (see also the excellent <a target="_blank" href="https://cran.r-project.org/web/packages/ggmap/ggmap.pdf"><code>ggmaps</code></a> package, which provides a similar facility for geocoding with Google’s standard API).</p>
<p>In daily use I’ve seen few issues thus far, and I’ve used earlier versions of this package to geocode about a quarter million physical locations in North America. The placement package, which includes examples, can be <a target="_blank" href="https://github.com/DerekYves/placement">viewed on Github</a> and installed in the usual way:</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>devtools</span><span>)</span><span>
</span><span>install_github</span><span>(</span><span>&quot;DerekYves/placement&quot;</span><span>)</span><span>
</span><span>library</span><span>(</span><span>placement</span><span>)</span></code></pre>
</figure>
<p>Here’s a few examples using the standard (free) API (see <a target="_blank" href="https://developers.google.com/maps/documentation/directions/get-api-key">here</a> to get a free API key from Google, which has higher quota limits than supplying an empty string):</p>
<figure>
<pre><code data-lang="r"><span># Get coordinates for the Empire State Building and Google
</span><span>address</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>&quot;350 5th Ave, New York, NY 10118, USA&quot;</span><span>,</span><span>
</span><span>&quot;1600 Amphitheatre Pkwy,
Mountain View, CA 94043, USA&quot;</span><span>)</span><span>
</span><span>coordset</span><span> </span><span>&lt;-</span><span> </span><span>geocode_url</span><span>(</span><span>address</span><span>,</span><span> </span><span>auth</span><span>=</span><span>&quot;standard_api&quot;</span><span>,</span><span> </span><span>privkey</span><span>=</span><span>&quot;&quot;</span><span>,</span><span>
</span><span>clean</span><span>=</span><span>TRUE</span><span>,</span><span> </span><span>add_date</span><span>=</span><span>'today'</span><span>,</span><span> </span><span>verbose</span><span>=</span><span>TRUE</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## Sending address vector (n=2) to Google...
## Finished. 2 of 2 records successfully geocoded.</code></pre>
</figure>
<figure>
<pre><code data-lang="r"><span># View the returns
</span><span>print</span><span>(</span><span>coordset</span><span>[</span><span> </span><span>,</span><span> </span><span>1</span><span>:</span><span>5</span><span>])</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">##        lat        lng location_type
## 1 40.74844  -73.98566       ROOFTOP
## 2 37.42234 -122.08437       ROOFTOP
##                                             formatted_address status
## 1 Empire State Building, 350 5th Ave, New York, NY 10118, USA     OK
## 2        1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA     OK</code></pre>
</figure>
<p>Distance calculations (note that some transit options are not accessible with the standard API):</p>
<figure>
<pre><code data-lang="r"><span># Bike from the NYC to Google!
</span><span>address</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>&quot;350 5th Ave, New York, NY 10118, USA&quot;</span><span>,</span><span>
</span><span>&quot;1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA&quot;</span><span>)</span><span>
</span><span># Google allows you to supply geo coordinates *or* a physical address # for the distance API. In this example, we will supply coordinates
# from our previous call. Google requires a string format of: # &quot;lat,lng&quot; (with no spaces) for coordinates.
</span><span>
</span><span>start</span><span> </span><span>&lt;-</span><span> </span><span>paste</span><span>(</span><span>coordset</span><span>$</span><span>lat</span><span>[</span><span>1</span><span>],</span><span>coordset</span><span>$</span><span>lng</span><span>[</span><span>1</span><span>],</span><span> </span><span>sep</span><span>=</span><span>&quot;,&quot;</span><span>)</span><span>
</span><span>end</span><span> </span><span>&lt;-</span><span> </span><span>paste</span><span>(</span><span>coordset</span><span>$</span><span>lat</span><span>[</span><span>2</span><span>],</span><span>coordset</span><span>$</span><span>lng</span><span>[</span><span>2</span><span>],</span><span> </span><span>sep</span><span>=</span><span>&quot;,&quot;</span><span>)</span><span>
</span><span># Get the travel time by bike (a mere 264 hours!) and distance in miles:
</span><span>howfar_miles</span><span> </span><span>&lt;-</span><span> </span><span>drive_time</span><span>(</span><span>address</span><span>=</span><span>start</span><span>,</span><span> </span><span>dest</span><span>=</span><span>end</span><span>,</span><span> </span><span>auth</span><span>=</span><span>&quot;standard_api&quot;</span><span>,</span><span>
</span><span>privkey</span><span>=</span><span>&quot;&quot;</span><span>,</span><span> </span><span>clean</span><span>=</span><span>FALSE</span><span>,</span><span> </span><span>add_date</span><span>=</span><span>'today'</span><span>,</span><span>
</span><span>verbose</span><span>=</span><span>FALSE</span><span>,</span><span> </span><span>travel_mode</span><span>=</span><span>&quot;bicycling&quot;</span><span>,</span><span>
</span><span>units</span><span>=</span><span>&quot;imperial&quot;</span><span>)</span><span>
</span><span># Get the distance in kilometers using physical addresses instead of lat/lng:
</span><span>howfar_kms</span><span> </span><span>&lt;-</span><span> </span><span>drive_time</span><span>(</span><span>
</span><span>address</span><span>=</span><span>&quot;350 5th Ave, New York, NY 10118&quot;</span><span>,</span><span>
</span><span>dest</span><span>=</span><span>&quot;1600 Amphitheatre Pkwy, Mountain View, CA&quot;</span><span>,</span><span>
</span><span>auth</span><span>=</span><span>&quot;standard_api&quot;</span><span>,</span><span> </span><span>privkey</span><span>=</span><span>&quot;&quot;</span><span>,</span><span> </span><span>clean</span><span>=</span><span>FALSE</span><span>,</span><span>
</span><span>add_date</span><span>=</span><span>'today'</span><span>,</span><span> </span><span>verbose</span><span>=</span><span>FALSE</span><span>,</span><span> </span><span>travel_mode</span><span>=</span><span>&quot;bicycling&quot;</span><span>,</span><span>
</span><span>units</span><span>=</span><span>&quot;metric&quot;</span><span>
</span><span>)</span><span>
</span><span>with</span><span>(</span><span>howfar_kms</span><span>,</span><span> </span><span>cat</span><span>(</span><span>&quot;Cycling from NYC to &quot;</span><span>,</span><span> </span><span>destination</span><span>,</span><span>
</span><span>&quot;:\n&quot;</span><span>,</span><span> </span><span>dist_txt</span><span>,</span><span> </span><span>&quot; over &quot;</span><span>,</span><span> </span><span>time_txt</span><span>,</span><span> </span><span>sep</span><span>=</span><span>&quot;&quot;</span><span>),</span><span> </span><span>sep</span><span>=</span><span>&quot;&quot;</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## Cycling from NYC to 1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA:
## 5,345 km over 11 days 17 hours</code></pre>
</figure>
<p>Address cleaning function:</p>
<figure>
<pre><code data-lang="r"><span># Clean a &quot;messy&quot; or otherwise incompatible address vector:
</span><span>address</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>&quot; 350 5th Ave. ½, New York, NY 10118, USA &quot;</span><span>,</span><span>
</span><span>&quot; ª1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA&quot;</span><span>)</span><span>
</span><span># View the return:
</span><span>address_cleaner</span><span>(</span><span>address</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## 	* Replacing non-breaking spaces
## 	* Removing control characters
## 	* Removing leading/trailing spaces, and runs of spaces
## 	* Transliterating latin1 characters
## 	* Converting special address markers
## 	* Removing all remaining non-ASCII characters
## 	* Remove single/double quotes and asterisks
## 	* Removing leading, trailing, and repeated commas
## 	* Removing various c/o string patterns</code></pre>
</figure>
<figure>
<pre><code data-lang="text">## [1] &quot;350 5th Ave.  1/2, New York, NY 10118, USA&quot;           
## [2] &quot;a1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA&quot;</code></pre>
</figure>
<p>If you would like to apply this function to multiple address fields stored in separate columns (e.g., only “street 1” and “city”), you might try something like:</p>
<figure>
<pre><code data-lang="r"><span>address_df</span><span>[]</span><span> </span><span>&lt;-</span><span> </span><span>sapply</span><span>(</span><span>address_df</span><span>,</span><span> </span><span>placement</span><span>::</span><span>address_cleaner</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## Error in lapply(X = X, FUN = FUN, ...): object 'address_df' not found</code></pre>
</figure>
<p>Using your Google for Work account obviously requires a client ID and API key, but the methods to do so are well documented in the package help files. Feel free to shoot me an email if you run into any issues!</p>
<p><div><div><div><div data-width="55" data-show-faces="false" data-send="true" data-layout="box_count" data-height="62" data-href="http://www.r-bloggers.com/placement-an-r-package-to-access-the-google-maps-api/"></div></div><div><a data-url="http://www.r-bloggers.com/placement-an-r-package-to-access-the-google-maps-api/" data-counturl="http://www.r-bloggers.com/placement-an-r-package-to-access-the-google-maps-api/" data-count="vertical" data-text="Placement: An R package to Access the Google Maps API" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://derekyves.github.io/2016/07/24/placement-pkg.html"> R from Stata</a></strong>.</div>
<hr>
<a rel="nofollow" href="http://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="http://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="http://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="http://www.r-bloggers.com/?s=data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="http://www.r-bloggers.com/?s=Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="http://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="http://www.r-bloggers.com/?s=map">maps</a>, <a title="Animation in R" rel="nofollow" href="http://www.r-bloggers.com/?s=animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="http://www.r-bloggers.com/?s=RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="http://www.r-bloggers.com/?s=sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="http://www.r-bloggers.com/?s=LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="http://www.r-bloggers.com/?s=SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="http://www.r-bloggers.com/?s=eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="http://www.r-bloggers.com/?s=git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="http://www.r-bloggers.com/?s=hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="http://www.r-bloggers.com/?s=Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="http://www.r-bloggers.com/?s=PCA">PCA</a>, <a title="Time series" rel="nofollow" href="http://www.r-bloggers.com/?s=time+series">time series</a>, <a title="finance trading" rel="nofollow" href="http://www.r-bloggers.com/?s=trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/lF85A5N_kZY"></a></div>