<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/mapping-the-largest-cities-in-asia-using-r/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://sharpsightlabs.com/blog/mapping-large-asian-cities-r/"> r-bloggers – SHARP SIGHT LABS</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p><a rel="nofollow" href="http://sharpsightlabs.com/join-newsletter-rapid-mastery/" target="_blank"><br>
<img sizes="(max-width: 600px) 100vw, 600px" src="https://i0.wp.com/sharpsightlabs.com/wp-content/uploads/2017/09/asian_cities_watercolor_map_NO-TITLE-600x465.png?w=450" alt="" class="wp-image-3115" data-recalc-dims="1"><br>
</a></p>
<p>As a quick followup to last week’s mapping exercise (where we <a href="http://sharpsightlabs.com/blog/map-european-cities-large-population/">mapped the largest European cities</a>), I want to map the largest cities in Asia.</p>
<p>When we did this last week, we used a variety of tools from the Tidyverse to scrape and <a href="http://sharpsightlabs.com/blog/shipping-analysis-r-data-wrangling/">wrangle the data</a>, and we ultimately mapped the data using base .</p>
<p>In this blog post, we’re going to scrape and wrangle the data in a very similar way, but we will visualize with a combination of  and . Using  will allow us to plot the data on a specialized “watercolor” map. This is a minor change, but it makes the finalized map a little more aesthetically interesting.</p>
<p>Let’s jump in.</p>
<p>First, we’ll load the packages that we’re going to use.</p>
<pre class="wp-code-highlight">
#==============
# LOAD PACKAGES
#==============

library(rvest)
library(tidyverse)
library(ggmap)
library(stringr)
</pre>
<p>Next, we’ll scrape the data using the  package.</p>
<p>Explaining exactly how  works is beyond the scope of this post, but notice that we’re using several functions in series by using the pipe operator ().</p>
<p>Essentially, we are using  to select the “tables” from the Wikipedia page. We want the third table on the page, so we identify it with . Then we use  to extract the text from the table.</p>
<p>The brilliant thing about  and the Tidyverse packages, is that you can ‘chain’ these functions together in series using . This makes writing and debugging your code easier, because you can build and test everything step by step.</p>
<pre class="wp-code-highlight">
#===========================
# SCRAPE DATA FROM WIKIPEDIA
#===========================
html.population &lt;- read_html('https://en.wikipedia.org/wiki/List_of_Asian_cities_by_population_within_city_limits')

df.asia_cities &lt;- html.population %>%
  html_nodes(&quot;table&quot;) %>%
  .[[3]] %>%
  html_table(fill = TRUE)


# inspect
df.asia_cities %>% head()
df.asia_cities %>% names()
</pre>
<p>After executing the web scraping code and inspecting the resulting data, we are going to begin some data wrangling.</p>
<p>First, we’re just going to remove some variables.</p>
<p>When we scraped the data, there were several columns that we don’t care about, like  and . These were appropriate on the Wikipedia page, but we don’t need them for our data visualization.</p>
<p>There are several ways to remove these, but a quick way is to us the <a href="http://sharpsightlabs.com/blog/dplyr-intro-data-manipulation-with-r/"> function from </a>. To remove unwanted variables, all we need to do is put a minus sign (‘-‘) in front of the variable.</p>
<p>Syntactically, this is really easy. In fact, one of the reasons that I strongly recommend using tools from the Tidyverse (like ) is that they are easy to learn, easy to memorize, and ultimately easy to use.</p>
<pre class="wp-code-highlight">
#============================
# REMOVE EXTRANEOUS VARIABLES
#============================
#df.asia_cities &lt;- select(df.asia_cities, -Date, -Image, -Location, -`Ref.`, -`2011 Eurostat\npopulation[3]`)

df.asia_cities &lt;- df.asia_cities[,c(1,2,4)]


# inspect
df.asia_cities %>% names()
df.asia_cities %>% head()

</pre>
<p>Now we have only three variables in the data, but we need to clean the variable names up a little.</p>
<p>Ideally, you want simple variable names. You also typically want your variable names to start with lower case letters (they are easier to type that way).</p>
<p>Here, we will manually provide new column names. We are using the  function to create a vector of strings (the new names), and we are assigning that vector of names as the column names of  by using the  function. </p>
<pre class="wp-code-highlight">
#===============
# RENAME COLUMNS
#===============
colnames(df.asia_cities) &lt;- c(&quot;city&quot;, &quot;country&quot;, &quot;population&quot;)


# inspect
df.asia_cities %>% colnames()
df.asia_cities %>% head()


#-------------------------------------------------------------------
# REMOVE EXTRA ROW AT TOP
# - when we scraped the data, part of the column name
#   for the 'Population, City proper&quot; column
#   was parsed as a row of data, instead of part of the column name
# - here, we're just removing that extraneous row
#-------------------------------------------------------------------

df.asia_cities &lt;- df.asia_cities[-1,]


# inspect
df.asia_cities %>% head()

</pre>
<p>Now that the names are cleaned up, we will do a little cleaning on the data values.</p>
<p>On the Wikipedia table that originally contained the data, there were some footnotes associated with the population numbers. The footnotes were marked by bracketed numbers (e.g. [1]).</p>
<p>We need to remove those footnote markers. To do this, we will use  inside of . Remember that <a href="http://sharpsightlabs.com/blog/dplyr-intro-data-manipulation-with-r/"> allows us to “mutate” a dataframe</a> and modify existing variables.</p>
<p>We will use a regular expression inside of  to identify the footnote markers and “replace” them with empty strings (i.e., we are replacing the information with <em>nothing at all</em>).</p>
<pre class="wp-code-highlight">
#==========================================================================
# REMOVE &quot;notes&quot; FROM POPULATION NUMBERS NAMES
# - two cities had extra characters for footnotes
#   ... we will remove these using stringr::str_replace and dplyr::mutate()
#==========================================================================

df.asia_cities &lt;- df.asia_cities %>% mutate(population = str_replace_all(population, &quot;\\[.*\\]&quot;,&quot;&quot;) %>% parse_number())

# inspect
df.asia_cities %>% head()

</pre>
<p>Now that we’ve removed the footnote characters, we need to create a new variable.</p>
<p>We will create a variable that has both the city <em>and</em> country in the following format: “Tokyo, Japan”.</p>
<p>You might be wondering why we are creating this new variable; the data already has a ‘city’ column as well as a ‘country’ column. Why do we want to duplicate this by creating a combined city/country column?</p>
<p>You’ll see why in a moment, but essentially, we will need this new column when we “geocode” our data to get the latitude and longitide coordinates of every city (we will need the lat/long when we plot the data).</p>
<p>The problem is that if we geocode based on only the city name (without the country), the geocoding process can encounter some errors due to ambiguity. (For example, would the city name “Naples” refer to Naples, Florida or Naples, Italy?)</p>
<p>To make sure that we don’t have any problems, we will create a variable that contains both city and country information.</p>
<pre class="wp-code-highlight">
#==============================================================
# CREATE VARIABLE: &quot;city_full_name&quot;
# - we need to have a combined name of the form 'City, Country'
# - we need this because when we use the geocode() function to
#   get long/lat data, there is some ambiguity in the city names
#==============================================================

df.asia_cities &lt;- df.asia_cities %>% mutate(city_full_name = str_c(df.asia_cities$city, df.asia_cities$country, sep = ', '))


#inspect
df.asia_cities %>% head()

</pre>
<p>Before we move on, we’ll quickly reorder the variables.</p>
<p>This is a quick and simple <a href="http://sharpsightlabs.com/blog/dplyr-intro-data-manipulation-with-r/">use of </a>. When we use , all we need to do is list out the variable names in the exact order we want them to appear in the data frame.</p>
<pre class="wp-code-highlight">
#==================
# REORDER VARIABLES
#==================

df.asia_cities &lt;- df.asia_cities %>% select(city, country, city_full_name, population)


# inspect
df.asia_cities %>% head()



#========================================
# COERCE TO TIBBLE
# - this just makes the data print better
#========================================

df.asia_cities &lt;- df.asia_cities %>% as_tibble()

</pre>
<p>Almost finished.</p>
<p>Now we’re going to obtain the longitude and latitude data by using .</p>
<p>After obtaining the geo-data, we’ll join it to the original data using .</p>
<pre class="wp-code-highlight">
#========================================================
# GEOCODE
# - here, we're just getting longitude and latitude data 
#   using ggmap::geocode()
#========================================================

data.geo &lt;- geocode(df.asia_cities$city_full_name)

print(data.geo)



#==================================================
# JOIN
# - here, we're just attaching the geocode data to
#   the original dataframe
#==================================================

df.asia_cities &lt;- cbind(df.asia_cities, data.geo)


# inspect
df.asia_cities %>% head()

</pre>
<p>To map the data points that we’ve just gathered, we will need a map on which to plot them.</p>
<p>In recent posts, we have been using the  function to retrieve a set of polygons; essentially, we’ve been just getting the country shapes, plotting them with , and then plotting data points on top of the polygons.</p>
<p>Here though, we’re going to do something different. We will use the  function to get a map of Asia from a 3rd party source. I won’t explain  and  completely here, but essentially, these tools allow you to get maps from Google Maps and other sources.</p>
<p>Here, we will retrieve a map from <em>Stamen Maps</em>. Stamen is a design firm in San Francisco that has created a set of maps that we can query by using . There are a variety of different “types” of maps, and in this case, we will get a “watercolor” map.</p>
<pre class="wp-code-highlight">
#=============
# GET ASIA MAP
#=============

map.asia &lt;- get_map('Asia', zoom = 3, source = &quot;stamen&quot;, maptype = &quot;watercolor&quot;)


# map it ...
map.asia %>% ggmap()


</pre>
<p>What’s great about this (and one of the reasons that I like the Tidyverse) is that the tools are largely interchangeable. It is extremely easy to use a map from  in a visualization instead of a <a href="http://sharpsightlabs.com/blog/simple-practice-maps-tidyverse/">basic polygon from </a>.</p>
<p>Ok. Now that we have all of the components (the cleaned dataset and the background watercolor-map of Asia) we can plot the data.</p>
<p>First, we will do a quick “first iteration” version just to check everything. This version is unformatted; we just want to plot the data to make sure that the points are aligned properly, and that our data is properly “cleaned.”</p>
<pre class="wp-code-highlight">
#============================================================================
# PLOT CITIES ON MAP
# - we are using the watercolor map of asia as the background (using ggmap())
# - we are using geom_point() to plot the city data as points
#   on top of the map
#============================================================================

# FIRST ITERATION
ggmap(map.asia) +
  geom_point(data = df.asia_cities, aes(x = lon, y = lat, size = population), color = &quot;red&quot;, alpha = .3) +
  geom_point(data = df.asia_cities, aes(x = lon, y = lat, size = population), color = &quot;red&quot;, shape = 1) 

</pre>
<p>To be clear, the “first iteration” map that I’m showing your looks pretty good; there’s nothing wrong with the data, etc. However, when I initially ran this code, I found a few things amiss, and had to go back and make some adjustments to the previous data wrangling code. Keep that in mind. As you progress through a project, you may find things that are wrong with your data, and you need to iteratively go back and adjust your code until you get everything just right.</p>
<p>Now that we have a “first iteration” of our map that looks good, we’re going to polish everything. </p>
<p>This is where we will <a href="http://sharpsightlabs.com/blog/format-titles-and-axes-in-ggplot2/">modify the theme elements</a> of the plot, add a title and subtitles, remove extraneous non-data elements (like the axis ticks, etc).</p>
<pre class="wp-code-highlight">
#==================================================
# FINALIZED MAP
# - here I've added titles, modified theme elements
#   like the text, etc
#==================================================

ggmap(map.asia) +
  geom_point(data = df.asia_cities, aes(x = lon, y = lat, size = population), color = &quot;red&quot;, alpha = .1) +
  geom_point(data = df.asia_cities, aes(x = lon, y = lat, size = population), color = &quot;red&quot;, shape = 1) +
    labs(x = NULL, y = NULL) +
    labs(size = 'Population (millions)') +
    labs(title = &quot;Largest Cities in Asia&quot;, subtitle = &quot;source: https://en.wikipedia.org/wiki/List_of_Asian_cities_by_population_within_city_limits&quot;) +
    scale_size_continuous(range = c(.6,18), labels = scales::comma_format(), breaks = c(1500000, 10000000, 20000000)) +
    theme(text = element_text(color = &quot;#4A4A4A&quot;, family = &quot;Gill Sans&quot;)) +
    theme(axis.text = element_blank()) +
    theme(axis.ticks = element_blank()) +
    theme(plot.title = element_text(size = 32)) +
    theme(plot.subtitle = element_text(size = 10)) +
    theme(legend.key = element_rect(fill = &quot;white&quot;))

</pre>
<p>And here is the finalized map:</p>
<p><a rel="nofollow" href="http://sharpsightlabs.com/join-newsletter-rapid-mastery/" target="_blank"><br>
<img sizes="(max-width: 600px) 100vw, 600px" src="https://i2.wp.com/sharpsightlabs.com/wp-content/uploads/2017/09/asian_cities_watercolor_map-600x516.png?w=450" alt="" class="wp-image-3113" data-recalc-dims="1"><br>
</a></p>
<p>I want to emphasize that after you’ve <a href="http://sharpsightlabs.com/blog/master-r-obsolete/">mastered the essential syntax</a> of the most important R functions, <a href="http://sharpsightlabs.com/blog/choose-project-practice-data-science/">small projects</a> like this are <a href="http://sharpsightlabs.com/blog/one-thing-master-data-science/">excellent practice</a>.</p>
<p>Having said that, I want to stress that if you <strong>don’t</strong> already know those “most important functions” backwards and forwards, you should focus your time on <em>memorizing those first</em>. Your first goal is to <a href="http://sharpsightlabs.com/blog/data-learning-vs-remembering/">memorize essential syntax</a> so that you know it “backwards and forwards.” After you’ve mastered the basic syntax, small projects like this will help you “put the pieces together.” </p>
<p>Once you’ve mastered the basic toolkit, small projects like this are excellent practice.</p>
<h1>Sign up now, and discover how to rapidly master data science</h1>
<p>To rapidly master data science, you need to master the essential tools.</p>
<p>You need to know what tools are important, which tools are <em>not</em> important, and <em>how to practice</em>.</p>
<p>Sharp Sight is dedicated to teaching you how to master the tools of data science as quickly as possible.</p>
<p><a rel="nofollow" href="http://sharpsightlabs.com/join-newsletter-rapid-mastery/" target="_blank">Sign up now for our email list</a>, and you’ll receive regular tutorials and lessons. </p>
<p>You’ll learn:</p>
<ul>
<li>What data science tools you should learn (and what not to learn)</li>
<li>How to practice those tools</li>
<li>How to put those tools together to execute analyses and machine learning projects</li>
<li>… and more </li>
</ul>
<p>If you <a rel="nofollow" href="http://sharpsightlabs.com/join-newsletter-rapid-mastery/" target="_blank">sign up for our email list <em>right now</em></a>, you’ll also get access to our “Data Science Crash Course” <u>for free</u>.</p>
<p><a rel="nofollow" href="http://sharpsightlabs.com/join-newsletter-rapid-mastery/" target="_blank">
<p><strong>SIGN UP NOW</strong></p>
<p></p></a>
<p>The post <a rel="nofollow" href="http://sharpsightlabs.com/blog/mapping-large-asian-cities-r/" target="_blank">Mapping the largest cities in Asia using R</a> appeared first on <a rel="nofollow" href="http://sharpsightlabs.com/" target="_blank">SHARP SIGHT LABS</a>.</p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://sharpsightlabs.com/blog/mapping-large-asian-cities-r/"> r-bloggers – SHARP SIGHT LABS</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 rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/j68q0EqquJE" height="1"></a></div>