Installation

geofi is not yet in CRAN, but can be installed from Github using

remotes::install_github("ropengov/geofi")

Zipcodes

You can add variables from Paavo data (Statistics Finland) in following manner.

Joining municipality level data from Statistics Finland

municipalities17 <- get_municipalities(year = 2017)
#> Requesting response from: http://geo.stat.fi/geoserver/wfs?service=WFS&version=1.0.0&request=getFeature&typename=tilastointialueet%3Akunta4500k_2017
#> Warning: Coercing CRS to epsg:3067 (ETRS89 / TM35FIN)
#> Data is licensed under: Attribution 4.0 International (CC BY 4.0)

# pull municipality data from Statistics Finland
library(pxweb)
pxweb_query_list <-
  list("Alue 2019"=c("*"),
       "Tiedot"=c("M408","M411","M476","M391","M421","M478","M404","M410","M303","M297","M302","M44","M62","M70","M488","M486","M137","M140","M130","M162","M78","M485","M152","M72","M84","M106","M151","M499","M496","M495","M497","M498"),
       "Vuosi"=c("2017"))

px_data <-
  pxweb_get(url = "http://pxnet2.stat.fi/PXWeb/api/v1/fi/Kuntien_avainluvut/2019/kuntien_avainluvut_2019_aikasarja.px",
            query = pxweb_query_list)

# Convert to data.frame
tk_data <- as.data.frame(px_data, column.name.type = "text", variable.value.type = "text")
tk_data2 <- tk_data %>%
  rename(name = `Alue 2019`) %>%
  mutate(name = as.character(name),
         # Paste Tiedot and Vuosi
         Tiedot = paste(Tiedot, Vuosi)) %>%
  select(-Vuosi) %>%
  spread(Tiedot, `Kuntien avainluvut`) %>%
  as_tibble()
tk_data3 <- janitor::clean_names(tk_data2)

# Join with Statistics Finland attribute data
dat <- left_join(municipalities17, tk_data3)
#> Joining, by = "name"
#> Warning: Column `name` joining factor and character vector, coercing into
#> character vector
dat[1:10,1:10]
#> Simple feature collection with 10 features and 10 fields
#> geometry type:  MULTIPOLYGON
#> dimension:      XY
#> bbox:           xmin: 83747.59 ymin: 6690809 xmax: 610975.5 ymax: 7133254
#> epsg (SRID):    3067
#> proj4string:    +proj=utm +zone=35 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
#>                gml_id vuosi kunta      nimi      namn      name kunta_name
#> 1   kunta4500k_2017.1  2017     5  Alajärvi  Alajärvi  Alajärvi   Alajärvi
#> 2   kunta4500k_2017.2  2017     9 Alavieska Alavieska Alavieska  Alavieska
#> 3   kunta4500k_2017.3  2017    10    Alavus    Alavus    Alavus     Alavus
#> 4   kunta4500k_2017.4  2017    16  Asikkala  Asikkala  Asikkala   Asikkala
#> 5   kunta4500k_2017.5  2017    18    Askola    Askola    Askola     Askola
#> 6   kunta4500k_2017.6  2017    19      Aura      Aura      Aura       Aura
#> 7   kunta4500k_2017.7  2017    20      Akaa      Akaa      Akaa       Akaa
#> 8   kunta4500k_2017.8  2017    35    Brändö    Brändö    Brändö     Brändö
#> 9   kunta4500k_2017.9  2017    43    Eckerö    Eckerö    Eckerö     Eckerö
#> 10 kunta4500k_2017.10  2017    46 Enonkoski Enonkoski Enonkoski  Enonkoski
#>    avi_code                   avi_name ely_code                           geom
#> 1         4  Länsi- ja Sisä-Suomen AVI       11 MULTIPOLYGON (((348733.2 69...
#> 2         5         Pohjois-Suomen AVI       13 MULTIPOLYGON (((370424.7 71...
#> 3         4  Länsi- ja Sisä-Suomen AVI       11 MULTIPOLYGON (((317245.3 69...
#> 4         1           Etelä-Suomen AVI        4 MULTIPOLYGON (((434407.9 67...
#> 5         1           Etelä-Suomen AVI        1 MULTIPOLYGON (((423421.8 67...
#> 6         2         Lounais-Suomen AVI        2 MULTIPOLYGON (((255415.5 67...
#> 7         4  Länsi- ja Sisä-Suomen AVI        5 MULTIPOLYGON (((324952.6 67...
#> 8         7 Ahvenanmaan valtionvirasto       16 MULTIPOLYGON (((176037.2 67...
#> 9         7 Ahvenanmaan valtionvirasto       16 MULTIPOLYGON (((86806.42 66...
#> 10        3             Itä-Suomen AVI        7 MULTIPOLYGON (((598384.5 68...

Aggregating municipality level data using internal municipality_key-files

Or if you prefer aggregating at vaalipiiri-level you can

mk_data <- dat %>% 
  group_by(va_name,va_code) %>% 
  # And compute population at maakunta level
  summarise(vakiluku_2017 = sum(vakiluku_2017))

ggplot(mk_data) + 
  geom_sf(aes(fill = vakiluku_2017)) +
  geom_sf_text(aes(label = paste(va_name, "\n",vakiluku_2017)), 
               size = 3, 
               color = "white")

Or if you want the population at the national level aggregated up from municipality level you can:

mk_data <- dat %>% 
  summarise(vakiluku_2017 = sum(vakiluku_2017))

ggplot(mk_data) + 
  geom_sf(aes(fill = vakiluku_2017)) +
  geom_sf_text(aes(label = vakiluku_2017), 
               size = 3, 
               color = "white")

Interactive maps using leaflet-package

Population grid data

Helsinki at 1km by 1km as interactive leaflet map

Using custom geofacet grids

From Ryan Hafen’s blog:

The geofacet package extends ggplot2 in a way that makes it easy to create geographically faceted visualizations in R. To geofacet is to take data representing different geographic entities and apply a visualization method to the data for each entity, with the resulting set of visualizations being laid out in a grid that mimics the original geographic topology as closely as possible.

geofi-package contains custom grids to be used with various Finnish administrative breakdowns. Below is an example where population data at municipality level is pulled from Statistics Finland fom 1987 to 2018, then aggregated at the levels of regions (maakunta) and then plotted with ggplot2 using grid geofi::grid_mk_2019.


# Let pull population data from Statistics Finland
pxweb_query_list <- 
  list("Alue 2019"=c("*"),
       "Tiedot"=c("M411"),
       "Vuosi"=c("1987","1988","1989","1990","1991","1992","1993","1994","1995","1996","1997","1998","1999","2000","2001","2002","2003","2004","2005","2006","2007","2008","2009","2010","2011","2012","2013","2014","2015","2016","2017","2018"))

# Download data 
px_data <- 
  pxweb_get(url = "http://pxnet2.stat.fi/PXWeb/api/v1/fi/Kuntien_avainluvut/2019/kuntien_avainluvut_2019_aikasarja.px",
            query = pxweb_query_list)

# Convert to data.frame 
px_data <- as.data.frame(px_data, column.name.type = "text", variable.value.type = "text")
names(px_data) <- c("kunta_name","var","year","value")

# lets aggregate population data
dat <- left_join(geofi::municipality_key_2019,px_data) %>% 
  group_by(mk_code, mk_name,year) %>% 
  summarise(population = sum(value, na.rm = TRUE)) %>% 
  na.omit() %>% 
  ungroup() %>% 
  rename(code = mk_code, name = mk_name)
#> Joining, by = "kunta_name"
#> Warning: Column `kunta_name` joining character vector and factor, coercing into
#> character vector

library(geofacet)
#> Registered S3 method overwritten by 'geofacet':
#>   method from   
#>   +.gg   ggplot2
library(ggplot2)

ggplot(dat, aes(x = year, y = population/1000, group = name)) + 
  geom_line() + 
  facet_geo(facets = ~name, grid = grid_mk_2019, scales = "free_y") +
  theme(axis.text.x = element_text(size = 6)) +
  scale_x_discrete(breaks = seq.int(from = 1987, to = 2018, by = 5)) +
  labs(title = "Population 1987-2018", y = "population (1000)")
#> Note: You provided a user-specified grid. If this is a generally-useful
#>   grid, please consider submitting it to become a part of the geofacet
#>   package. You can do this easily by calling:
#>   grid_submit(__grid_df_name__)


dat <- left_join(geofi::municipality_key_2019 %>% filter(mk_name == "Ahvenanmaa"),
                 px_data) %>% 
  group_by(mk_code, mk_name,year) %>% 
  rename(code = kunta, name = kunta_name, population = value)
#> Joining, by = "kunta_name"
#> Warning: Column `kunta_name` joining character vector and factor, coercing into
#> character vector

library(geofacet)
library(ggplot2)

ggplot(dat, aes(x = year, y = population/1000, group = name)) + 
  geom_line() + 
  facet_geo(facets = ~name, grid = grid_ahvenanmaa_2019, scales = "free_y") +
  theme(axis.text.x = element_text(size = 6)) +
  scale_x_discrete(breaks = seq.int(from = 1987, to = 2018, by = 5)) +
  labs(title = "Population 1987-2018", y = "population (1000)")
#> Note: You provided a user-specified grid. If this is a generally-useful
#>   grid, please consider submitting it to become a part of the geofacet
#>   package. You can do this easily by calling:
#>   grid_submit(__grid_df_name__)