Skip to content

Instantly share code, notes, and snippets.

@andrewheiss
Last active July 14, 2023 18:27
Show Gist options
  • Save andrewheiss/29f261de01768af36b469d42ab38cf92 to your computer and use it in GitHub Desktop.
Save andrewheiss/29f261de01768af36b469d42ab38cf92 to your computer and use it in GitHub Desktop.
library(tidyverse)
library(sf)
library(rnaturalearth)
library(countrycode)
library(gapminder)

# rerturnclass = "sf" makes it so the resulting dataframe has the special
# sf-enabled geometry column
world_map <- ne_countries(scale = 50, returnclass = "sf") %>% 
  filter(iso_a3 != "ATA")  # Remove Antarctica

gapminder_clean <- gapminder %>% 
  filter(year %in% c(1952, 2007)) %>% 
  mutate(ISO3 = countrycode(country, "country.name", "iso3c"))


# world_map has 234 rows
# gapminder_clean has 284 rows

# This new combined dataset has 375 rows. Somehow it added a bunch because of
# different countries present in each dataset
joined <- world_map %>%
  left_join(gapminder_clean, by = c("iso_a3" = "ISO3"))

# SO INSTEAD DO THIS
# Make a skeleton with all the countries in world_map and all the years in gapminder
skeleton <- expand_grid(iso_a3 = unique(world_map$iso_a3),
                        year = unique(gapminder_clean$year))
# This has 468 rows
skeleton
#> # A tibble: 468 × 2
#>    iso_a3  year
#>    <chr>  <int>
#>  1 ABW     1952
#>  2 ABW     2007
#>  3 AFG     1952
#>  4 AFG     2007
#>  5 AGO     1952
#>  6 AGO     2007
#>  7 AIA     1952
#>  8 AIA     2007
#>  9 ALB     1952
#> 10 ALB     2007
#> # ℹ 458 more rows


full_stuff <- skeleton %>% 
  # Add the geography data to each country
  left_join(world_map, by = "iso_a3") %>% 
  # Add the gapminder data to each country/year combination
  left_join(gapminder_clean, by = c("iso_a3" = "ISO3", "year"))

# This also has 468 rows. No new rows were added or removed
full_stuff
#> # A tibble: 468 × 70
#>    iso_a3  year scalerank featurecla  labelrank sovereignt sov_a3 adm0_dif level
#>    <chr>  <int>     <int> <chr>           <dbl> <chr>      <chr>     <dbl> <dbl>
#>  1 ABW     1952         3 Admin-0 co…         5 Netherlan… NL1           1     2
#>  2 ABW     2007         3 Admin-0 co…         5 Netherlan… NL1           1     2
#>  3 AFG     1952         1 Admin-0 co…         3 Afghanist… AFG           0     2
#>  4 AFG     2007         1 Admin-0 co…         3 Afghanist… AFG           0     2
#>  5 AGO     1952         1 Admin-0 co…         3 Angola     AGO           0     2
#>  6 AGO     2007         1 Admin-0 co…         3 Angola     AGO           0     2
#>  7 AIA     1952         1 Admin-0 co…         6 United Ki… GB1           1     2
#>  8 AIA     2007         1 Admin-0 co…         6 United Ki… GB1           1     2
#>  9 ALB     1952         1 Admin-0 co…         6 Albania    ALB           0     2
#> 10 ALB     2007         1 Admin-0 co…         6 Albania    ALB           0     2
#> # ℹ 458 more rows
#> # ℹ 61 more variables: type <chr>, admin <chr>, adm0_a3 <chr>, geou_dif <dbl>,
#> #   geounit <chr>, gu_a3 <chr>, su_dif <dbl>, subunit <chr>, su_a3 <chr>,
#> #   brk_diff <dbl>, name <chr>, name_long <chr>, brk_a3 <chr>, brk_name <chr>,
#> #   brk_group <chr>, abbrev <chr>, postal <chr>, formal_en <chr>,
#> #   formal_fr <chr>, note_adm0 <chr>, note_brk <chr>, name_sort <chr>,
#> #   name_alt <chr>, mapcolor7 <dbl>, mapcolor8 <dbl>, mapcolor9 <dbl>, …

# Oh no this stopped working; the joining killed the magic geometry column
ggplot() +
  geom_sf(data = full_stuff, aes(fill = lifeExp)) +
  theme_void() +
  facet_wrap(vars(year))
## Error in `geom_sf()`:
## ! Problem while computing stat.
## ℹ Error occurred in the 1st layer.
## Caused by error in `compute_layer()`:
## ! `stat_sf()` requires the following missing aesthetics: geometry


# So we can either set the geometry aesthetic ourselves:
ggplot() +
  geom_sf(data = full_stuff, aes(fill = lifeExp, geometry = geometry)) +
  theme_void() +
  facet_wrap(vars(year))

# Or we can use st_set_geometry() to make the geometry column magical again
full_stuff <- skeleton %>% 
  # Add the geography data to each country
  left_join(world_map, by = "iso_a3") %>% 
  # Add the gapminder data to each country/year combination
  left_join(gapminder_clean, by = c("iso_a3" = "ISO3", "year")) %>% 
  st_set_geometry("geometry")

ggplot() +
  geom_sf(data = full_stuff, aes(fill = lifeExp)) +
  theme_void() +
  facet_wrap(vars(year))

Created on 2023-07-14 with reprex v2.0.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment