<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/do-know-shake-shacks-locations-outside-of-the-us-youd-be-surprised/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://nandeshwar.info/data-visualization/shake-shack-locations/"> R – nandeshwar.info</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<h2>Madison Shake</h2>
<p>I had heard that the lines to get some food at <a rel="nofollow" href="http://www.businessinsider.com/why-people-wait-in-line-for-shake-shack-cronuts-iphones-2014-6" target="_blank">Shake Shack are long</a>. So when I saw a new location opening in downtown LA, I wondered how many locations does it have and how fast are they spreading across the US. The answers surprised me. Using R and previous code, I created a few maps:</p>
<p><img src="https://i0.wp.com/i.imgur.com/E1CoBvM.gif?w=456&ssl=1" data-recalc-dims="1"></p>
<p><img alt="Shake it like a globetrotter" src="https://i2.wp.com/i.imgur.com/gwTV2U6.gif?w=456&ssl=1" data-recalc-dims="1"></p>
<p>Read on to learn how I got the data and plotted them.</p>
<h2>Load Libraries</h2>
<p>First, let’s load our favourite libraries.</p>
<div><table><tr><td><pre>1
2
3
4
5
</pre></td><td><pre><span>library</span><span>(</span>rvest<span>)</span>
<span>library</span><span>(</span>readr<span>)</span>
<span>library</span><span>(</span>tidyverse<span>)</span>
<span>library</span><span>(</span>scales<span>)</span>
<span>library</span><span>(</span>ggmap<span>)</span></pre></td></tr></table></div>
<h2>Figure out locations</h2>
<p>On its <a rel="nofollow" href="https://www.shakeshack.com/location" target="_blank">site, Shake Shack</a> fortunately has all the locations and opening dates, going back to April 23, 2012. The archive pages run from 1 to 20 with this URL structure:</p>
<pre><code>https://www.shakeshack.com/location/page/
<p>Using <a rel="nofollow" href="http://selectorgadget.com/" target="_blank">SelectorGadget</a>, I figured out the XPath and CSS code to find the opening date, location name, and location page link. Then, I wrote a function to retrieve these values from a given archive page.</p>

<div><table><tr><td><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td><pre>get_locations <span>&lt;-</span> <span>function</span><span>(</span><span>url</span><span>)</span> <span>{</span>
  page_html <span>&lt;-</span> read_html<span>(</span><span>url</span><span>)</span>
  nodes <span>&lt;-</span> page_html <span>%>%</span> 
    html_nodes<span>(</span>xpath <span>=</span> <span>'//*[contains(concat( &quot; &quot;, @class, &quot; &quot; ), concat( &quot; &quot;, &quot;span4&quot;, &quot; &quot; ))]'</span><span>)</span>
 
  <span>data.<span>frame</span></span><span>(</span>opdate <span>=</span> html_nodes<span>(</span>x <span>=</span> nodes,
                                 xpath <span>=</span> <span>'//*[contains(concat( &quot; &quot;, @class, &quot; &quot; ), concat( &quot; &quot;, &quot;date&quot;, &quot; &quot; ))]'</span><span>)</span> <span>%>%</span> 
               html_text<span>(</span>trim <span>=</span> TRUE<span>)</span>,
             store_loc_name <span>=</span> html_nodes<span>(</span>x <span>=</span> nodes,
                                         css <span>=</span> <span>'h2'</span><span>)</span> <span>%>%</span> 
               html_text<span>(</span>trim <span>=</span> TRUE<span>)</span>,
             store_loc_link <span>=</span> html_nodes<span>(</span>x <span>=</span> nodes,
                                         css <span>=</span> <span>'h2 a'</span><span>)</span> <span>%>%</span> 
               html_attr<span>(</span><span>&quot;href&quot;</span><span>)</span>,
             stringsAsFactors <span>=</span> FALSE<span>)</span>
<span>}</span></pre></td></tr></table></div>

<p>I applied this function to retrieve all location opening dates, names, and individual location urls:</p>

<div><table><tr><td><pre>1
2
3
</pre></td><td><pre>all_loc_pages <span>&lt;-</span> paste0<span>(</span><span>&quot;https://www.shakeshack.com/location/page/&quot;</span>, <span>1</span><span>:</span><span>20</span>, <span>&quot;/&quot;</span><span>)</span>
 
all_locations <span>&lt;-</span> <span>do.<span>call</span></span><span>(</span><span>rbind</span>, <span>lapply</span><span>(</span>all_loc_pages, get_locations<span>)</span><span>)</span></pre></td></tr></table></div>

<h2>Find addresses of all locations</h2>
<p>If you visit an individual location’s page, such as <a rel="nofollow" href="https://www.shakeshack.com/location/tokyo-japan-tokyo-dome" target="_blank">this Tokyo Dome page,</a> you will see that often the exact address is not listed, or if it is, you can’t directly geocode it. But, luckily, there’s a Google Map right below the location. I thought, they must be passing some parameters to Google Maps API. I spend a good amount of time, but couldn’t figure out how they were getting the map. And. Then. I found out that the text “CLICK MAP FOR DIRECTIONS” block had a valid address as part of the hyperlink!!</p>
<p><img src="https://i0.wp.com/media.giphy.com/media/uTuLngvL9p0Xe/giphy.gif?w=456&ssl=1" data-recalc-dims="1"> </p>
<p><img sizes="(max-width: 1024px) 100vw, 1024px" src="https://i0.wp.com/d2py08v4b28rs4.cloudfront.net/wp-content/uploads/click-map-directions-shake-shack-address-1024x327.png?w=450" alt="" class="wp-image-2709" data-recalc-dims="1"></p>
<p> I wrote another simple function to get the addresses from the given URL:</p>

<div><table><tr><td><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td><pre>get_loc_cords <span>&lt;-</span> <span>function</span><span>(</span>loc_url<span>)</span> <span>{</span>
  location_html <span>&lt;-</span> read_html<span>(</span>loc_url<span>)</span>
  <span>data.<span>frame</span></span><span>(</span>loc_url <span>=</span> loc_url,
             goog_map_url <span>=</span>  location_html <span>%>%</span>
               html_nodes<span>(</span>xpath <span>=</span> <span>'//a[text()=&quot;Click here for directions&quot;]'</span><span>)</span> <span>%>%</span>
               html_attr<span>(</span><span>&quot;href&quot;</span><span>)</span>,
             stringsAsFactors <span>=</span> FALSE<span>)</span>
<span>}</span>
 
location_google_maps_address <span>&lt;-</span> <span>do.<span>call</span></span><span>(</span><span>rbind</span>, <span>lapply</span><span>(</span>all_locations$store_loc_link, get_loc_cords<span>)</span><span>)</span></pre></td></tr></table></div>

<p>Then I joined the location name with the address data frame:</p>

<div><table><tr><td><pre>1
</pre></td><td><pre>all_locations <span>&lt;-</span> left_join<span>(</span>all_locations, location_google_maps_address, <span>by</span> <span>=</span> <span>c</span><span>(</span><span>&quot;store_loc_link&quot;</span> <span>=</span> <span>&quot;loc_url&quot;</span><span>)</span><span>)</span></pre></td></tr></table></div>

<h2>Geocoding the addresses</h2>
<p>Using the fantastic ggmap library and mutate_geocode function, I geocoded all the addresses:</p>

<div><table><tr><td><pre>1
2
3
</pre></td><td><pre>all_locations <span>&lt;-</span> all_locations <span>%>%</span>
  mutate<span>(</span>google_addr_string <span>=</span> str_sub<span>(</span>goog_map_url, <span>start</span> <span>=</span> <span>36</span><span>)</span><span>)</span> <span>%>%</span>
  mutate_geocode<span>(</span>google_addr_string, output <span>=</span> <span>&quot;latlon&quot;</span><span>)</span></pre></td></tr></table></div>

<p>Here’s what the data frame looks like now:</p>
<p><img sizes="(max-width: 954px) 100vw, 954px" src="https://i2.wp.com/d2py08v4b28rs4.cloudfront.net/wp-content/uploads/geocoded-shake-shack-locations.png?w=450" alt="" class="wp-image-2710" data-recalc-dims="1"></p>
<div></div>
<div>
<div>
<h3>Tip</h3>
<p>You may want to create a Google developer key for mass geocoding. Since the mutate_geocode function is used by many people, sometimes you may not get all the addresses geocoded. Use register_google(key = </div></div></code></pre>