<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/metro-systems-over-time-part-2/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://datascienceplus.com/metro-systems-over-time-part-2/"> DataScience+</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Note, at the time of this writing using the packages <code>ggplot2</code> and <code>ggmap</code> from CRAN will result in an error. To avoid the error be sure to install both packages from GitHub with the package <code>devtools</code> and restart R if the problem persists.</p>
<pre>
devtools::install_github(&quot;dkahle/ggmap&quot;)
devtools::install_github(&quot;hadley/ggplot2&quot;)
</pre>
<h2>Introduction</h2>
<p>In <a target="_blank" rel="nofollow" href="https://datascienceplus.com/metro-systems-over-time-part-1/">Part 1</a> of this series we collected geodata from Google of metro stops and plotted them on maps. In Part 2 we’ll be building Delaunay triangulations on top of those maps and computing the centroid of the network. This post will include some pretty advanced use of <code>tidyverse</code> packages. For more information on some of these calls look at the <code>tidyverse</code> <a target="_blank" rel="nofollow" href="http://tidyverse.org/">documentation</a>.</p>
<h2>Data</h2>
<p>As a reminder, our data is the hand corrected values of the data we pulled down from Google. To see how we got the data go back to <a target="_blank" rel="nofollow" href="https://datascienceplus.com/metro-systems-over-time-part-1/">Part 1: Data</a>.</p>
<h2>Maps with Delaunay Triangulations and Centroids</h2>
<p>With our maps and data points in place let’s compute the <a target="_blank" rel="nofollow" href="https://en.wikipedia.org/wiki/Delaunay_triangulation">Delaunay triangulation</a> for each city. This will let us find the area a given city’s metro covers, and allows us to compute a center point, or <a target="_blank" rel="nofollow" href="https://en.wikipedia.org/wiki/Centroid">centroid</a>, for the metro system. We do this with the <code>deldir</code> package. First though, I am going to use a function from <code>tidyr</code> called <code>nest()</code> which allows me to collapse a bunch of data into a single cell. By nesting by <code>city</code> I get one row for each city and then the rest of the data for each column is a list of values in one cell. Additionally, I can collapse all of my other columns into a single column using <code>.key</code>, in this case this new column is called <code>location_info</code>. Think of it as a data frame tucked within a cell of a data frame. With my data nested I can make a new column called <code>deldir</code> that will have all of the information from my <code>deldir()</code> call. The <code>deldir()</code> call simply takes two lists of continuous data points. It then computes several things, including the area of the shape and the edges of all the segments connecting the points. How do we access this information though? We can pull this information out with a <code>purrr</code> call, <code>map()</code>. The <code>map()</code> call takes in some data and a function and applies the data to the function in an iterative fashion. For our purposes though we’re saying we want to take the data in the form of the column <code>deldir</code> and pull out the <code>del.area</code>. Thanks to the <code>mutate()</code> call we can then save it to a new column. We can do the same thing with <code>delsgs</code> (the segments of the shape) and <code>summary</code> (more information about the individual triangles). See the fully nested data frame below.</p>
<pre>
library(purrr)
library(deldir)

data_deldir = data %>%
  nest(-city, .key = location_info) %>%
  mutate(deldir = map(location_info, function(df) deldir(df$lon, df$lat))) %>%
  mutate(del.area = map(deldir, &quot;del.area&quot;)) %>%
  mutate(delsgs = map(deldir, &quot;delsgs&quot;)) %>%
  mutate(summary = map(deldir, &quot;summary&quot;))
data_deldir
<em># A tibble: 4 × 6
city location_info deldir del.area delsgs summary
&lt;fctr> &lt;list> &lt;list> &lt;list> &lt;list> &lt;list>
1 Paris &lt;tibble [298 × 9]> &lt;S3: deldir> &lt;dbl [1]> &lt;data.frame [849 × 6]> &lt;data.frame [287 × 9]>
2 Berlin &lt;tibble [173 × 9]> &lt;S3: deldir> &lt;dbl [1]> &lt;data.frame [499 × 6]> &lt;data.frame [171 × 9]>
3 Barcelona &lt;tibble [149 × 9]> &lt;S3: deldir> &lt;dbl [1]> &lt;data.frame [433 × 6]> &lt;data.frame [148 × 9]>
4 Prague &lt;tibble [58 × 9]> &lt;S3: deldir> &lt;dbl [1]> &lt;data.frame [161 × 6]> &lt;data.frame [58 × 9]></em>
</pre>
<p>Based on these areas it looks like the Berlin metro covers the most area at 0.059279 while Barcelona covers the smallest area at 0.016332. Now that we have our nested data frame with all pertinent information, we’re going to unnest the data necessary for our new plots. First we need the <code>delsgs</code> data, which we use to draw the lines connecting the metro stops. To do this we’ll make a new data frame, dropping all columns except for <code>city</code> and <code>delsgs</code>. Then we <code>unnest()</code> the data frame. This will expand the <code>delsgs</code> column that had nested values, giving us many more rows and many more columns. The x1, y1, x2, and y1 values will be used later in our plot to draw the edges of our triangles. See part of the unnested data frame below.</p>
<pre>
data_deldir_delsgs = data_deldir %>%
  select(city, delsgs) %>%
  unnest()
head(data_deldir_delsgs)
<em># A tibble: 6 × 7
city x1 y1 x2 y2 ind1 ind2
&lt;fctr> &lt;dbl> &lt;dbl> &lt;dbl> &lt;dbl> &lt;int> &lt;int>
1 Paris 2.366928 48.78793 2.359279 48.79272 283 282
2 Paris 2.433489 48.77262 2.366928 48.78793 72 283
3 Paris 2.450590 48.78984 2.433489 48.77262 74 72
4 Paris 2.450590 48.78984 2.459319 48.77978 74 73
5 Paris 2.455281 48.76805 2.433489 48.77262 198 72
6 Paris 2.455281 48.76805 2.459319 48.77978 198 73</em>
</pre>
<p>In addition to the edges of the shape, we also want the centroid. To do this we’ll first make a new data frame focusing on just the city and summary information. We then <code>unnest()</code> the data frame just as we did for the edges, however we don’t stop here. What we’re really interested in is the centroid, which we need to compute ourselves. To do this we’ll first <code>group_by()</code> city. Then we’re going to <code>summarise()</code> the data. To compute the x-value for the centroid, <code>cent_x</code>, we’re going to take the <code>x</code> column, which contains the x-coordinates of all of the points, and multiply each point by the <code>del.wts</code> column, which contains the weights of the areas of each triangle. By adding these numbers together we get the x-value of the centroid of the entire figure. We can do the same thing for the y-value. See the table below for the data summarised to give us the centroids for each city.</p>
<pre>
data_deldir_cent = data_deldir %>%
  select(city, summary) %>%
  unnest() %>%
  group_by(city) %>%
  summarise(cent_x = sum(x * del.wts),
            cent_y = sum(y * del.wts)) %>%
  ungroup()
data_deldir_cent
<em># A tibble: 4 × 3
city cent_x cent_y
&lt;fctr> &lt;dbl> &lt;dbl>
1 Barcelona 2.137923 41.38708
2 Berlin 13.402654 52.51054
3 Paris 2.353365 48.85813
4 Prague 14.447439 50.07588</em>
</pre>
<p>Now we can update our figures with the triangulations and centroids. I’ve again made a function to build the four maps. As before we start with <code>ggmap()</code> and our city specific map object. Next we’ll use <code>geom_segment()</code> to draw our edges. To do this we’ll use <code>x1</code>, <code>y1</code>, <code>x2</code>, and <code>y2</code> from our <code>data_deldir_delsgs</code> data frame we made earlier. We then plot the actual metro stop points just as we did in our original map with <code>geom_point()</code>. Finally we end with one more <code>geom_point()</code> call, this time on our <code>data_deldir_cent</code> data frame to plot the centroid specific to each city. See the four updated maps below. Again, I’ve left the code visible for the Paris map to see how the function works and hidden the rest.</p>
<pre>
del_plot = function(city_name, city_map){
  ggmap(city_map, extent = &quot;device&quot;) +
    geom_segment(data = subset(data_deldir_delsgs, city == city_name), aes(x = x1, y = y1, xend = x2, yend = y2),
                 size = 1, color= &quot;#92c5de&quot;) +
    geom_point(data = subset(data, city == city_name), aes(x = lon, y = lat),
               color = &quot;#0571b0&quot;, size = 3) +
    geom_point(data = subset(data_deldir_cent, city == city_name),
               aes(x = cent_x, y = cent_y),
               size = 6, color= &quot;#ca0020&quot;)
}

paris_del.plot = del_plot(&quot;Paris&quot;, paris_map)
paris_del.plot
</pre>
<p>Plot for Paris:<br>
<a title="" data-rel="lightbox-0" target="_blank" rel="nofollow" href="https://i2.wp.com/datascienceplus.com/wp-content/uploads/2017/01/paris_del.png?ssl=1"><img sizes="(max-width: 490px) 100vw, 490px" alt="" class="wp-image-5257" src="https://i1.wp.com/datascienceplus.com/wp-content/uploads/2017/01/paris_del-490x345.png?resize=456%2C321&ssl=1" data-recalc-dims="1"></a></p>
<h2>Conclusion</h2>
<p>In Part 2 of this series we computed Delaunay triangulations and centroids for each of our our city’s metro systems. This included some more complicated <code>tidyverse</code> calls such as nesting and unnesting our data. In the third and final part of this series we’ll look at how the systems change over time and show it with a .gif.</p>
<ul></ul>
<p><strong>
<p>Related Post</p>
<p>
<ol>
<li><a title="Permanent Link toMetro Systems Over Time: Part 1" target="_blank" rel="nofollow" href="https://datascienceplus.com/metro-systems-over-time-part-1/">Metro Systems Over Time: Part 1</a></li>
<li><a title="Permanent Link toOutlier App: An Interactive Visualization of Outlier Algorithms" target="_blank" rel="nofollow" href="https://datascienceplus.com/outlier-app-an-interactive-visualization-of-outlier-algorithms/">Outlier App: An Interactive Visualization of Outlier Algorithms</a></li>
<li><a title="Permanent Link toCreating an animation using R" target="_blank" rel="nofollow" href="https://datascienceplus.com/creating-an-animation-using-r/">Creating an animation using R</a></li>
<li><a title="Permanent Link toThe importance of Data Visualization" target="_blank" rel="nofollow" href="https://datascienceplus.com/the-importance-of-data-visualization/">The importance of Data Visualization</a></li>
<li><a title="Permanent Link toggplot2 themes examples" target="_blank" rel="nofollow" href="https://datascienceplus.com/ggplot2-themes-examples/">ggplot2 themes examples</a></li>
</ol></strong>
<div>
<a target="_blank" rel="nofollow" href="http://feeds.feedburner.com/~ff/datascienceplus?a=eXTydTwezDc:mQtgVCRp9EY:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/datascienceplus?i=eXTydTwezDc:mQtgVCRp9EY:D7DqB2pKExk" border="0"></a> <a target="_blank" rel="nofollow" href="http://feeds.feedburner.com/~ff/datascienceplus?a=eXTydTwezDc:mQtgVCRp9EY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/datascienceplus?d=qj6IDK7rITs" border="0"></a> <a target="_blank" rel="nofollow" href="http://feeds.feedburner.com/~ff/datascienceplus?a=eXTydTwezDc:mQtgVCRp9EY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/datascienceplus?d=yIl2AUoC8zA" border="0"></a>
</div>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://datascienceplus.com/metro-systems-over-time-part-2/"> DataScience+</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://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="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/BoiHfu7Ywjw"></a></div>