Section 3.3 Mapping rates rather than counts
Subsection 3.3.1 Generating the rates
We have now seen the importance of mapping rates rather than counts of things, and that is for the simple reason that population is not equally distributed in space. That means that if we do not account for how many people are somewhere, we end up mapping population size rather than our topic of interest.
The
manchester object we are working with has a column named respop that includes the residential population in each of the LSOA areas. These areas for the whole of the UK have an average population of around 1500 people. We can see a similar picture for Manchester city, with an average closer to 1700 here.
hist(manchester$respop, main = "Distribution of residential population across LSOAs")

We also have a variable
wkdpop that represents the workday population. This variable re-distributes the usually resident population to their places of work, while those not at work are recorded at their usual residence. The picture it offers is much more diverse than the previous variable and in some ways is closer to the notion of an "ambient population" (with some caveats: for example, it does not capture tourists, people visiting a place to shop or to entertain themselves in the night time economy, etc.).
hist(manchester$wkdpop, main = "Distribution of workday population across LSOAs")

The distribution of the workday population is much more skewed than the residential population, with most LSOAs having only 5,000 or fewer workday population, but the busiest LSOAs attracting over 40,000 people during the work day. This gives an idea of the relevance of the "denominator dilemma" we mentioned earlier. In this section we will create rates of crime using both variables in the denominator to observe how the emerging picture varies.
First we need to create new variables. For this we can use the
mutate() function from the dplyr package. This is a very helpful function to create new variables in a dataframe based on transformations or mathematical operations performed on other variables within the dataframe. In this function, the first argument is the name of the data frame, and then we can pass as arguments all new variables we want to create as well as the instructions as to how we are creating those variables.
First, we want to create a rate using the usual residents, since crime rates are often expressed by 100,000 inhabitants we will multiply the division of the number of crimes by the number of usual residents by 100,000. We will then create another variable,
crimr2, using the workday population as the denominator. We will store this new variables in our existing manchester dataset. You can see that below we then specify the name of a new variable crimr1 and then tell the function we want that variable to equal (for each case) the ratio of the values in the variable count (number of crimes) by the variable respop (number of people residing in the area). We then multiply the result of this division by 100,000 to obtain a rate expressed in those terms. We can do likewise for the alternative measure of crime.
manchester <- mutate(manchester,
# crime per residential population
crimr1 = (count/respop)*100000,
# crime per workday population
crimr2 = (count/wkdpop)*100000)
And now we have two new variables: one for crime rate with residential population as a denominator, and another with workplace population as a denominator.
Subsection 3.3.2 Creating a choropleth map with tmap
The structure of the grammar for producing a choropleth map is similar to what we use for proportional symbols. First, we identify the object with
tm_shape() and then we use a geometry to be represented. We will be using the tm_polygons() passing as an argument the name of the variable with our crime rate.
tm_shape(manchester) +
tm_polygons("crimr1")

We have used
tm_polygons() but we can also add the elements of a polygon map using different functions that break down what we represent here. In the map above, you see the polygons have a dual representation, the borders are represented by lines and the colour is mapped to the intensity of the quantitative variable we are displaying. With darker colours representing more of the variable, the areas with more crimes.
Instead of using
tm_polygon(), we can use the related functions tm_fill(), for the colour inside the polygons, and tm_borders(), for the aesthetics representing the border of the polygons. Say, we find the borders distracting and we want to set them to be transparent. In that case we could just use tm_fill().
tm_shape(manchester) +
tm_fill("crimr1")

tm_fill() functionAs you can see here, the look is a bit cleaner. However, we don’t need to get rid of the borders completely. Perhaps we want to make them a bit more translucent. We could do that by adding the border element but making the drawing of the borders less pronounced.
tm_shape(manchester) +
tm_fill("crimr1") +
tm_borders(alpha = 0.1)

tm_fill() and bordersThe alpha parameter that we are inserting within
tm_borders() controls the transparency of the borders, we can go from 0 (totally transparent) to 1 (not transparent). You can play around with this value and see the results.
Notice as well that the legend in this map is not very informative and could be improved in terms of aesthetics. We can add a title within the
tm_fill to clarify what "crimr1" means, and we can use the tm_layout() function to control the appearance of the legend. This latter function, tm_layout(), allows you to think about many of the more general cosmetics of the map.
tm_shape(manchester) +
tm_fill("crimr1", title = "Crime per 100,000 residents") +
tm_borders(alpha = 0.1) +
tm_layout(main.title = "Crime in Manchester City, Nov/2017",
main.title.size = 0.7 ,
legend.outside = TRUE, # Place legend outside of map
legend.title.size = 0.8)

We can also change the style of the maps we produce, for example by making them more friendly to colour-blind people. We can use the
tmap_style() function to do so. Once you set the style, the subsequent maps will stick to this style. If you want to reverse to a different style when using tmap, you need to do so explicitly.
current_style <- tmap_style("col_blind")
See how the map changes.
tm_shape(manchester) +
tm_fill("crimr1", title = "Crime per 100,000 residents") +
tm_borders(alpha = 0.1) +
tm_layout(main.title = "Crime in Manchester City, Nov/2017",
main.title.size = 0.7 ,
legend.outside = TRUE, # Takes the legend outside the main map
legend.title.size = 0.8,
)

We will discuss more about map aesthetics in Chapter 5. For now, let’s talk about another important decision when it comes to thematic maps, the choice of classification system.
