World map using the tidyverse (ggplot2) and an equal-area projection
There are several different ways to make maps in R, and I always have to look it up and figure this out again from previous examples that I’ve used. Today I had another look at what’s currently possible and what’s an easy way of making a world map in ggplot2 that doesn’t require fetching data from various places.
TLDR: Copy this code to plot a world map using the tidyverse:
library(tidyverse)
library(ggthemes)
world_map = map_data("world") %>%
filter(! long > 180)
countries = world_map %>%
distinct(region) %>%
rowid_to_column()
countries %>%
ggplot(aes(fill = rowid, map_id = region)) +
geom_map(map = world_map) +
expand_limits(x = world_map$long, y = world_map$lat) +
coord_map("moll") +
theme_map()

Explanation
To make a map using geom_map() you’ll need two datasets: one that includes the map data (country borders), and another one on how to colour in each area.
I tried doing data = NULL or fill = "grey" to make all countries the same colour, but couldn’t get that to work.
So I’m creating the necessary second dataset with distinct(world_map, region) which is a list of every country from the map data.
This list of countries (=regions) is the first argument to ggplot(), the world_map data goes inside geom_map(). expand_limits() are essential as otherwise you will not see anything.
library(tidyverse)
# Load map data
world_map = map_data("world")
distinct(world_map, region) %>%
ggplot(aes(map_id = region)) +
geom_map(map = world_map) +
expand_limits(x = world_map$long, y = world_map$lat)

Equal area projection
Global maps that do not use an equal area projection are a huge pet peeve of mine. The above map is not ‘equal-area’ and the closer to the equator an area is the more diminished it is.
Let’s just plot Greenland and Algeria for example:
tibble(region = c("Greenland", "Algeria")) %>%
ggplot(aes(map_id = region)) +
geom_map(map = world_map) +
expand_limits(x = world_map$long, y = world_map$lat)

In reality, Algeria is bigger than Greenland: 2.4 million km2 vs 2.2 million km2!
Therefore, I always use an equal-area projection such as Mollweide:
library(tidyverse)
# Load map data
world_map = map_data("world")
distinct(world_map, region) %>%
ggplot(aes(map_id = region)) +
geom_map(map = world_map) +
expand_limits(x = world_map$long, y = world_map$lat) +
coord_map("moll")

But then we get those weird lines in the Northern Hemisphere. That’s because parts of the US and Russia extend across the 180th meridian. And since geom_map() is connecting each area with itself it then draws these lines across the globe.
A simple fix I’ve found is to remove map data that has a longitude greater than 180 degrees:
library(tidyverse)
library(ggthemes)
world_map = map_data("world") %>%
filter(! long > 180)
countries = world_map %>%
distinct(region) %>%
rowid_to_column()
countries %>%
ggplot(aes(fill = rowid, map_id = region)) +
geom_map(map = world_map) +
expand_limits(x = world_map$long, y = world_map$lat) +
coord_map("moll") +
theme_map()

I’ve also thrown in theme_map() from library(ggthemes), put the coutry list which I made with distinct() into a separate object, and added in fill = rowid for some colour.
This is useful as I’m generally plotting chloropleths so I want a tibble with values for each country that I can join with whatever data I have for each country (e.g., student numbers, population, etc.).