/
CShapesMaps.Rmd
103 lines (88 loc) · 3.97 KB
/
CShapesMaps.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
---
title: "Building historical maps with CShapes"
author: "Bernhard Bieri"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Building historical maps with CShapes}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.align = "center"
)
pkgs <- c("WDI", "ggplot2", "dplyr", "countrycode", "manystates")
lapply(pkgs, library, character.only = TRUE)
```
Providing visualizations about of the structure of the international
governance system at certain times is desirable, but not always straightforward.
While not aiming at being a comprehensive guide to the
[different ways of creating maps in R](https://geocompr.robinlovelace.net/),
this articles introduces the process of building maps in R with data
from [`{cshapes}` package](https://cran.r-project.org/web/packages/cshapes/index.html)
and GDP data from the World Bank.
In the following example, we'll see how to build a heatmap showing GDP per
capita in 1980.
## Step 1: Import the data from `{cshapes}` and the World Bank
First, we extract data from the `{WDI}` package of the
[NY.GDP.PCAP.KD](https://data.worldbank.org/indicator/NY.GDP.PCAP.KD)
indicator of the World Bank which yields information
about the GDP per capita of countries in 2010 $.
We then clean this data and then convert the ISO country code to
the COW number we have in the `{cshapes}` dataset
with the `{countrycode}` package.
```{r data, echo=TRUE, warning=FALSE, message=FALSE}
# Extract GDP from World Bank for the period between 1980 and 1990
library(WDI)
library(countrycode)
library(dplyr)
GDP <- WDI::WDI(indicator = 'NY.GDP.PCAP.KD', start = 1980, end = 1980)
GDP <- dplyr::slice(GDP, 50:266)
GDP <- dplyr::as_tibble(GDP) %>%
dplyr::mutate(cowID = as.character(countrycode::countrycode(GDP$iso2c,
origin = "iso2c",
destination = "cowc",
warn = FALSE)))
```
Second, we use the `{cshapes}` package by importing a world map
in a way that is consistent with the many packages universe with the
`import_cshapes()` function.
```{r cshapes, echo=TRUE, warning=FALSE, message=FALSE}
# Import map data with import_cshapes()
mapdata <- manystates::import_cshapes(date = "1980-01-01")
```
Finally, we perform a `left_join()` between both dataframes to combine mapping
data (especially the `geometry` variable which contains the shapes of countries)
and data about GDP in 1980.
Since this is a historical map, it takes the information about states and
distances according what they were in 1980 (e.g. West and East Germany or USSR).
```{r join, echo=TRUE, warning=FALSE, message=FALSE}
# Left join on cowNr
data <- dplyr::left_join(mapdata, GDP, by = "cowID")
```
## Step 2: Create a heatmap
To plot the data, we leverage `{ggplot}` and its `geom_sf()`
layer that takes a vector of polygons as an input
(in this case the `geometry` variable of the combined
dataframe) to create a map.
We also use a neat theme from the `{hrbrthemes}`
package and tweak it a little for a prettier output.
```{r plot, echo=TRUE, warning=FALSE, message=FALSE}
library(ggplot2)
library(hrbrthemes) # for a pretty map
ggplot2::ggplot(data = data$geometry) + # Main plot options
geom_sf(mapping = aes(fill = data$NY.GDP.PCAP.KD), lwd = 0.1) + # Map options
scale_fill_viridis_c(option = "plasma", na.value = "grey80") + # Color options
labs(title = "GDP per capita in 1980",
subtitle = "Some fact about the GDP in 1980.",
caption = "Source: World Bank (retrieved 15/07/2021)",
fill = "GDP per capita") + # Define labels
hrbrthemes::theme_ipsum() + # Set a default theme
theme(panel.background = element_rect(fill = "light blue"), # Make oceans blue
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank()) # Remove grids
```