7 min read

Ladda hem data från Kolada med R

Det finns en gemensam databas för Sveriges kommuner och landsting/regioner som heter Kolada. Databasen innehåller runt 5 000 olika nyckeltal. Det finns ett API kopplat till databasen vilket gör att vi kan ladda in data i R. Nackdelen är att API:et skapar datastrukturer som är ganska svårjobbade. Men med lite hjälp av funktionerna i purrr-paketet går det att trassla ut de komplicerade liststrukturerna och få fram en dataframe som output. Hur det går till visas nedan.

Om man vill ladda hem data anropas API:et med ett GET-anrop. Databasen nås på “http://api.kolada.se/v2/data/”. Därefter läggs en kpi-kod (Key Performance Indicator) till i URL:en (till exempel “http://api.kolada.se/v2/kpi/N07402”) och dessutom kan år och/eller kommun fogas till URL:en (till exempel “http://api.kolada.se/v2/data/kpi/N07402/municipality/1280/year/2011”). Notera att kommunnummer används för att referera till kommun. Om man vill söka efter flera år och eller kommuner kan man ange flera värden separerade med kommatecken, till exempel “http://api.kolada.se/v2/data/kpi/N07402/municipality/1280,1281/year/2011,2015”.

En del indikatorer går att mäta på enhetsnivå, till exempel en enskild skola. I de fallen byts “municipality/kommunkod” ut mot “ou/enhetskod” (“ou” står förmodligen för “operational unit”) och anropet sker till “http://api.kolada.se/v2/oudata”.

Exempel 1: Våld mot kvinnor

Nedan går jag igenom hur man hittar indikatorn som redovisar antalet fall av grov kvinnofridskränkning per 100 000 invånare, hur man hämtar hem metadata om variabeln och hur man slutligen laddar hem data.

Hitta indikatorkoden

För att ladda hem en indikator måste man först veta vilken KPI-kod den har. Det går att ta reda på vilka indikatorer som finns och vilka koder de har med hjälp av API:et. Med koden nedan kan man få metainformation om alla indikatorer, inklusive KPI-koder, vilka finns under rubriken “id”.

library(httr)
library(purrr)
library(tidyr)

url <- "http://api.kolada.se/v2/kpi?"

lresult <- content(GET(url))
dfmeta <- map_df(.x = lresult$values, ~flatten(.x))

dfmeta
# # A tibble: 4,496 x 13
#    auspices description       has_ou_data id    is_divided_by_g~ municipality_ty~ operating_area   perspective prel_publicatio~ publ_period
#    <chr>    <chr>             <lgl>       <chr>            <int> <chr>            <chr>            <chr>       <chr>            <chr>      
#  1 E        Personalkostnade~ FALSE       N000~                0 K                Kommunen, överg~ Resurser    2018-05-03       2017       
#  2 E        Personalkostnade~ FALSE       N000~                0 K                Kommunen, överg~ Resurser    2018-04-10       2017       
#  3 X        Kommunalekonomis~ FALSE       N000~                0 K                Resultaträkning~ Resurser    2018-04-10       2017       
#  4 NA       Momsavgift, divi~ FALSE       N000~                0 K                Skatter och utj~ Resurser    NA               NA         
#  5 X        Invånarrelaterat~ FALSE       N000~                0 K                Skatter och utj~ Resurser    NA               NA         
#  6 X        Åldersrelaterat ~ FALSE       N000~                0 K                Skatter och utj~ Resurser    NA               NA         
#  7 NA       Externa intäkter~ FALSE       N000~                0 K                Kommunen, överg~ Resurser    NA               2017       
#  8 NA       Inkomstutjämning~ FALSE       N000~                0 K                Skatter och utj~ Resurser    2018-09-28       2019       
#  9 NA       Kostnadsutjämnin~ FALSE       N000~                0 K                Skatter och utj~ Resurser    2018-09-28       2019       
# 10 X        Generellt statsb~ FALSE       N000~                0 K                Skatter och utj~ Resurser    NA               NA         
# # ... with 4,486 more rows, and 3 more variables: publication_date <chr>, title <chr>, ou_publication_date <chr>

Om vi letar bland träffarna ovan så upptäcker vi att kpi-koden vi söker är “N07402”.

Ett annat alternativ är att söka indikator med hjälp av sökord:

url <- "http://api.kolada.se/v2/kpi?title=kvinnofridskränkning"

lresult <- content(GET(url))
dfmeta <- map_df(.x = lresult$values, ~flatten(.x))

dfmeta
# # A tibble: 1 x 11
#   auspices description                 has_ou_data id     is_divided_by_g~ municipality_ty~ operating_area perspective publ_period publication_date title             
#   <chr>    <chr>                       <lgl>       <chr>             <int> <chr>            <chr>          <chr>       <chr>       <chr>            <chr>             
# 1 X        Anmälda brott mot grov kvi~ FALSE       N07402                0 K                Befolkning     Övrigt      2017        2018-03-27       Anmälda brott om ~

Ladda hem metadata

# Ladda hem metadata
url <- "http://api.kolada.se/v2/kpi/N07402"
lresult <- content(GET(url))

dfmeta <- map_df(.x = lresult$values, ~flatten(.x))

dfmeta

# # A tibble: 1 x 11
#   auspices description has_ou_data id    is_divided_by_g~ municipality_ty~ operating_area perspective publ_period publication_date title
#   <chr>    <chr>       <lgl>       <chr>            <int> <chr>            <chr>          <chr>       <chr>       <chr>            <chr>
# 1 X        Anmälda br~ FALSE       N074~                0 K                Befolkning     Övrigt      2017        2018-03-27       Anmä~
# > 

Ladda hem data

Nästa steg är att ladda hem data

# Ladda hem data --------------------------------------------------

# Ladda hem uppgifter om grov kvinnofridskränkning från Kolada. Välj data 
# för Malmö och Lund, vilket motsvarar kommunkodern 1280 och 1281

url <- "http://api.kolada.se/v2/data/kpi/N07402/municipality/1280,1281"
lresult <- content(GET(url))

# Resultatet av frågan till API:et kommer i en komplicerad liststruktur, vilket
# kräver en del omstrukturering av data med hjälp av paketen purrr och tidyr:

ltrans <- transpose(lresult$values)

df <- map_df(.x = ltrans, .f = simplify)

df <- df %>%
  unnest(values) %>%
  mutate(values = map(values, ~flatten(.x) %>% bind_rows() ) ) %>%
  unnest(values)

df
# # A tibble: 40 x 7
#    kpi    municipality period count gender status value
#    <chr>  <chr>         <int> <int> <chr>  <chr>  <dbl>
#  1 N07402 1280           1998     1 T      ""      2.75
#  2 N07402 1281           1998     1 T      ""      0   
#  3 N07402 1280           1999     1 T      ""     14.8 
#  4 N07402 1281           1999     1 T      ""      1.02
#  5 N07402 1280           2000     1 T      ""     17.7 
#  6 N07402 1281           2000     1 T      ""      1.01
#  7 N07402 1280           2001     1 T      ""     17.9 
#  8 N07402 1281           2001     1 T      ""      2.01
#  9 N07402 1280           2002     1 T      ""     19.2 
# 10 N07402 1281           2002     1 T      ""      7.97
# # ... with 30 more rows

Exempel 2: Ladda hem data för en individuell skola

Den här gången vill vi veta “Antal elever i förskoleklass i kommunal skola belägen i kommunen. Uppgiften avser läsår, mätt 15 oktober”. Koden för indikatorn är “N11805”.

Ladda hem metadata

# Ladda hem metadata
url <- "http://api.kolada.se/v2/kpi/N11805"
lresult <- content(GET(url))

dfmeta <- map_df(.x = lresult$values, ~flatten(.x))

dfmeta

# # A tibble: 1 x 12
#   auspices description          has_ou_data id    is_divided_by_g~ municipality_ty~ operating_area ou_publication_~ perspective publ_period
#   <chr>    <chr>                <lgl>       <chr>            <int> <chr>            <chr>          <chr>            <chr>       <chr>      
# 1 T        Antal elever i förs~ TRUE        N118~                0 K                Förskoleverks~ 2016-09-30       Volymer     2017       
# # ... with 2 more variables: publication_date <chr>, title <chr>
# >

Leta upp OU-id.

I GET-anropet till Kolada måste vi ange ett unikt ID-nummer för skolan - ett ou-ID. Vi laddar in alla unika ou-ID:n för enheter som innehåller ordet “skola” i en dataframe enligt nedan:

# Hämta lista på skol-id

url <- "http://api.kolada.se/v2/ou?title=skola"
lresult <- content(GET(url))

ltrans <- transpose(lresult$values)

dfobjekt <- map_df(.x = ltrans, .f = simplify)

dfobjekt

# # A tibble: 4,911 x 3
#    id            municipality title                
#    <chr>         <chr>        <chr>                
#  1 V15E011400101 0114         Runby skola          
#  2 V15E011400201 0114         Väsby skola          
#  3 V15E011400805 0114         Grimsta skola        
#  4 V15E011401201 0114         Bollstanäs skola     
#  5 V15E011401601 0114         Breddenskolan        
#  6 V15E011402801 0114         Södervikskolan       
#  7 V15E011402901 0114         Odenskolan           
#  8 V15E011403001 0114         Frestaskolan         
#  9 V15E011403101 0114         Vikskolan            
# 10 V15E011403501 0114         Resursskolan Magneten
# # ... with 4,901 more rows
# Man kan också söka alla enheter som finns i en kommun med:

Sök alla enheter i en viss kommun

Ibland vill man ha reda på alla enheter som finns i en viss kommun. Då kan man skapa en fråga som returnerar den uppgiften:

url <- "http://api.kolada.se/v2/ou?municipality=1280"

lresult <- content(GET(url))

ltrans <- transpose(lresult$values)

dfobjekt <- map_df(.x = ltrans, .f = simplify)

dfobjekt
# # A tibble: 372 x 3
#    id            municipality title                                
#    <chr>         <chr>        <chr>                                
#  1 V15E128000301 1280         Dammfriskolan                        
#  2 V15E128001301 1280         Ribersborgsskolan                    
#  3 V15E128001601 1280         Sofielundsskolan                     
#  4 V15E128001801 1280         Stenkulaskolan                       
#  5 V15E128002101 1280         Videdalsskolan                       
#  6 V15E128002201 1280         Österportsskolan                     
#  7 V15E128003301 1280         Slottsstadens skola                  
#  8 V15E128006301 1280         Bladins grundskola                   
#  9 V15E128006305 1280         Bladins International School of Malmö
# 10 V15E128006601 1280         Ängslättskolan                       
# # ... with 362 more rows

Ladda hem data

Nästa steg är att ladda hem data. Vi väljer att ladda hem data för Dammfriskolan i Malmö, vilken har koden “V15E128000301”.

# Ladda hem data för en skola ---------------------------------------

# Dammfriskolan = V15E128000301

url <-  "http://api.kolada.se/v2/oudata/kpi/N11805/ou/V15E128000301"

lresult <- content(GET(url))

ltrans <- transpose(lresult$values)


df <- map_df(.x = ltrans, .f = simplify)

df <- df %>%
  unnest(values) %>%
  mutate(values = map(values, ~flatten(.x) %>% bind_rows() ) ) %>%
  unnest(values)

# # A tibble: 10 x 7
#    kpi    ou            period count gender status  value
#    <chr>  <chr>          <int> <int> <chr>  <chr>   <dbl>
#  1 N11805 V15E128000301   2006     1 T      Missing    NA
#  2 N11805 V15E128000301   2007     1 T      ""         39
#  3 N11805 V15E128000301   2008     1 T      ""         37
#  4 N11805 V15E128000301   2009     1 T      ""         40
#  5 N11805 V15E128000301   2010     1 T      ""         38
#  6 N11805 V15E128000301   2011     1 T      ""         48
#  7 N11805 V15E128000301   2012     1 T      ""         57
#  8 N11805 V15E128000301   2014     1 T      ""         61
#  9 N11805 V15E128000301   2015     1 T      ""         68
# 10 N11805 V15E128000301   2016     1 T      ""         73
# >