Skip to contents

County & Municipality

Statistics Sweden (SCB) have a lot of interesting statistics that can be analyzed on a geographical level. Through their Database Statistikdatabasen you can download the data as Excel tables. Even better, you can use the R Open Gov package pxweb to query data from SCB.

By running pxweb_interactive() you can interactively choose which data to query. In this case we’re going to use data from Statistics Sweden.

When you have clicked through which data you want to query you can get the call to the database as R code. In the code below I have manipulated the code that was returned by pxweb to only query county codes that are in swemaps2::county.

The data queried here is population count with higher education.

library(pxweb)
library(janitor)
library(swemaps2)
library(tidyverse)

pxweb_query_list <- 
  list("Region"=county$ln_kod,
       "Kon"=c("1+2"),
       "ContentsCode"=c("BE0101U1"),
       "Tid"=c("2021"))

# Download data 
px_data <- 
  pxweb_get(url = "https://api.scb.se/OV0104/v1/doris/sv/ssd/BE/BE0101/BE0101C/BefArealTathetKon",
            query = pxweb_query_list)

# Convert to data.frame 
px_data_frame <- as.data.frame(px_data, column.name.type = "text", variable.value.type = "text")

population_per_kvm <- px_data_frame |> 
  clean_names()

Unfortunately, we do not get the region codes from SCB. But if we remove the " län from the region names we can join it by name:

population_per_kvm <- population_per_kvm %>% 
  mutate(region = str_replace(region, " län", "")) 

county_pop <- left_join(county, population_per_kvm, by = c("ln_namn" = "region"))

county_pop
#> Simple feature collection with 21 features and 5 fields
#> Geometry type: MULTIPOLYGON
#> Dimension:     XY
#> Bounding box:  xmin: 277247.6 ymin: 6133891 xmax: 917271.4 ymax: 7669870
#> Projected CRS: SWEREF99 TM
#> # A tibble: 21 × 6
#>    ln_kod ln_namn                                   geometry kon   ar    invan…¹
#>    <chr>  <chr>                           <MULTIPOLYGON [m]> <chr> <chr>   <dbl>
#>  1 01     Stockholms    (((627791.9 6569168, 630226.6 65721… tota… 2021    371. 
#>  2 03     Uppsala       (((633496.1 6610607, 632895.2 66095… tota… 2021     48.2
#>  3 04     Södermanlands (((555102.6 6536546, 549484.9 65402… tota… 2021     49.7
#>  4 05     Östergötlands (((496094.6 6443310, 493792.5 64387… tota… 2021     44.5
#>  5 06     Jönköpings    (((498999.7 6421417, 500271.5 64171… tota… 2021     35.2
#>  6 07     Kronobergs    (((504095.5 6338410, 505156.2 63401… tota… 2021     24.1
#>  7 08     Kalmar        (((544656.8 6325506, 540241.9 63273… tota… 2021     22.1
#>  8 09     Gotlands      (((706606.9 6415775, 709951.4 64170… tota… 2021     19.5
#>  9 10     Blekinge      (((473443 6228381, 472071.2 6231138… tota… 2021     54.2
#> 10 12     Skåne         (((420135.8 6254456, 425339.2 62566… tota… 2021    128. 
#> # … with 11 more rows, and abbreviated variable name
#> #   ¹​invanare_per_kvadratkilometer

We can now easily visualize this data on a Swedish map

library(scales)
ggplot(county_pop, aes(fill = log10(invanare_per_kvadratkilometer))) +
  geom_sf() +
  theme_swemap2() +
  scale_fill_viridis_c(option = "magma", labels = number) +
  labs(
    title = "",
    fill = "log10(population\nper square meter)",
    caption = "Source: SCB"
  )

We can also create an interactive map with simplevis

library(mapview)

mapView(county_pop, zcol = "invanare_per_kvadratkilometer")

DeSO & RegSO

Using pxweb we can query lots of statistics from SCB on DeSO level. For example, we might be interested in the proportion of children with low economic standard in Stockholm. Using pxweb_interactive() we get a good skeleton of code. Below I have only changed the code to only query regions that are in deso_sthlm.

deso <- load_deso()
#> Reading layer `DeSO_2018_v2' from data source 
#>   `/private/var/folders/pn/9hhpnpd15_d2k3qp5k814nnh0000gq/T/RtmpPmunBV/deso_2018_2021-10-21/DeSO_2018_v2.gpkg' 
#>   using driver `GPKG'
#> Simple feature collection with 5984 features and 7 fields
#> Geometry type: POLYGON
#> Dimension:     XY
#> Bounding box:  xmin: 266646.3 ymin: 6132476 xmax: 920877.4 ymax: 7671055
#> Projected CRS: SWEREF99 TM

deso_sthlm <- deso %>% 
  filter(kommunnamn == "Stockholm")

pxweb_query_list <- 
  list("Region"= deso_sthlm$deso,
       "Alder"=c("0-19"),
       "ContentsCode"=c("000006TA"),
       "Tid"=c("2019"))

# Download data 
px_data <- 
  pxweb_get(url = "https://api.scb.se/OV0104/v1/doris/sv/ssd/START/HE/HE0110/HE0110I/TabVX4InkDesoN1",
            query = pxweb_query_list)

# Convert to data.frame 
px_sthlm <- as.data.frame(px_data, column.name.type = "text", variable.value.type = "text") %>% 
  clean_names() %>% 
  as_tibble()

deso_sthlm <- deso_sthlm %>% 
  left_join(px_sthlm, by = c("deso" = "region"))

Finally, we can use this data to create a map:

ggplot(deso_sthlm , aes(fill = lag_ekonomisk_standard_procent)) +
  geom_sf() +
  scale_fill_viridis_c(option = "magma") + 
  theme_swemap2() +
  labs(
    title = "% Barn med Låg ekonomisk standard",
    subtitle = "Andel personer 0-19 år med låg ekonomisk standard per Demografiskt statistikområde\ni Stockholm stad",
    fill = "% Låg\nekonomisk\nstandard"
  )