Arne Bergene Fossaa viser deg hvordan du analyserer åpne data, for eksempel om norsk kjøttproduksjon, med R. 📸: Christopher Carson / Unsplash
Arne Bergene Fossaa viser deg hvordan du analyserer åpne data, for eksempel om norsk kjøttproduksjon, med R. 📸: Christopher Carson / Unsplash Vis mer

R og åpen data: Analyse av norsk kjøtt­produksjon

Se hvordan R enkelt lar deg utforske, forme og visualisere data. 🐖

På data.norge.no kan man finne en rekke interessante sett med åpne datasett, som er interessante både fordi de har en mengde med “ekte” data, og siden de er åpne og tilpasset analyse fint kan analysere som man vil.

Her tar jeg for meg statistikk over norsk kjøttproduksjon i 2016, som er et datasett over produksjon av kjøttyper. Det som er fint med datasettet er at det har detaljer ned på hver bonde, slik at det er mulig aggreregere over dataen og finne sammenhenger.

Jeg bruker her det ypperlige verktøyet R, som lar deg utforske, forme og visualisere data meget enkelt.

Først laster vi data fra CSV - data er separaret med semikolon og ikke komma, så det må spesifiseres. Siden “,” er brukt for å separaere desimaler, må det og spesifiseres, siden R som standard forventer at dette skal være “.”

meat_prod = read.csv("2016.csv", sep=";", dec=",")
str(meat_prod)
## 'data.frame':    29433 obs. of  27 variables:
##  $ orgnr             : int  981397290 969907321 985228728 869396982 986122109 969635488 969209713 969822997 969349396 969838729 ...
##  $ navn              : Factor w/ 29239 levels "10/27 WORKS STEFFEN BUCH",..: 17302 6530 4843 28009 14205 19429 20653 24455 5442 25477 ...
##  $ komnr             : int  1032 1216 1511 1548 1101 1635 1144 1432 619 1445 ...
##  $ and_kg            : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ geit_kg           : num  0 0 0 0 0 ...
##  $ kje_kg            : num  0 0 0 0 0 ...
##  $ gris_kg           : num  0 0 0 0 0 92.6 0 0 0 0 ...
##  $ purke_kg          : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ raane_kg          : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ gaas_kg           : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ hane_kg           : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ hest_foll_kg      : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ hons_kg           : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ kalkun_kg         : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ kalv_kg           : num  104 0 0 185 4201 ...
##  $ kylling_kg        : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ lam_kg            : num  0 7193 533 0 3111 ...
##  $ lam_villsau_kg    : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ sau_kg            : num  0 973 256 0 332 ...
##  $ ungsau_kg         : num  0 247.9 142.9 0 35.6 ...
##  $ vaer_kg           : num  0 94.8 48.6 0 46 0 0 0 0 0 ...
##  $ ku_kg             : num  326 0 0 3914 1603 ...
##  $ kvige_kg          : num  0 0 0 264 219 ...
##  $ okse_kg           : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ ungokse_kastrat_kg: num  0 0 0 2351 0 ...
##  $ ungku_kg          : num  189 0 0 3178 1506 ...
##  $ ull_kg            : num  0 848 343 0 508 ...

str() gir en fin kjapp oversikt over variablene - men her er det mye noise når man ser nærmere. Det første man kan se er at all gjennomsnitt er basert på gjennomsnitt produksjon per gårdsbruk, uansett om gårdsbruket produserer kjøttet eller ei.

Det neste er at det er noe feil i dataen; organisjoner med samme organisasjonsummer har rapportert inn flere ganger. Det er dog noen organisasjoner som eksisterer i flere kommuner - dette kan skje om det er større organisasjoner som har flere fjøs - så vi lar primærnøkkelen her være orgnr og komnr.

suppressPackageStartupMessages(library(dplyr))
nrow(meat_prod)
## [1] 29433
nrow(unique(select(meat_prod, orgnr, komnr)))
## [1] 27369

Det er altså 29433 oppslag, mens det er 27369 unike nøkler. La oss fikse dette ved å bruke dplyr - funksjonene group_by og summarise:

meat_prod_values = meat_prod %>% 
  group_by(orgnr,komnr) %>%
  summarise_if(is.numeric,funs(sum))
meat_prod_name = meat_prod %>% 
  group_by(orgnr,komnr) %>%
  summarise_if(is.factor,funs(first))
meat_prod = merge(meat_prod_values, meat_prod_name)
nrow(meat_prod)
## [1] 27369

Kun unike nøkler - bra!

La oss se litt nærmere på dataen vi har, og ta for oss grisekjøtt for nå.

pigs = select(meat_prod, orgnr, navn, komnr,gris_kg, purke_kg, raane_kg)
pigs = filter(pigs, gris_kg > 0 | purke_kg > 0 | raane_kg > 0)
nrow(pigs)
## [1] 2398

Som vi ser, er det 2398 gårder som produserer gris. La oss gå dypere og se hvor disse gårdene er plassert. Vi må da først laste inn en database over kommuner i Norge. Dette datasette er hentet ned fra SSB.

knr = read.csv2("knr.csv", sep=";", encoding="UTF-8")
knr = select(knr, komnr = Kodeverdi, kommunenavn = Beskrivelse)
knr$fylkesnr = floor(knr$komnr / 100) #De 2 første sifrene i et kommunenummer er fylkesnummeret - vi trenger det senere
pigs = merge(pigs,knr)
pigs$kommunenavn = as.factor(pigs$kommunenavn)
head(summary(pigs$kommunenavn))
##         Hå  Ringsaker      Klepp       Time Vindafjord   Levanger 
##        145         83         78         70         67         63

Det er 1 kommune som ruver øverst på antall gårder som produserer grisekjøtt. Men er det fordi det er mange små produsenter eller fordi de produserer mest?

pigs$total_kg = pigs$gris_kg + pigs$purke_kg + pigs$raane_kg
head(sort(tapply(pigs$total_kg,pigs$kommunenavn,sum), decreasing=TRUE))
##         Hå  Ringsaker      Klepp   Levanger       Time Vindafjord 
##    9023840    7722147    5824330    5116636    5020248    4379787
sum(pigs$total_kg[pigs$kommunenavn %in% c("Hå")]) / sum(pigs$total_kg) 
## [1] 0.06575006

Som vi ser er det og de som produserer mest, der over 9000 tonn grisekjøtt eller 6,5 % av alt grisekjøtt som produserers i Norge kommer fra den lille kommunen - det er rimelig imponerende.

La oss se på hvor vi finner den aller største grisebonden i landet:

pigs[which.max(pigs$total_kg),]
##     komnr     orgnr                  navn  gris_kg purke_kg raane_kg
## 188   234 970481893 HANS ANDERS FJELDSTAD 372661.2   1261.4        0
##     kommunenavn fylkesnr total_kg
## 188    Gjerdrum        2 373922.6
max(pigs$total_kg) / sum(pigs$total_kg)
## [1] 0.002724498

Den største grisebonden heter altså Hans Anders Fjeldstad befinner seg i Gjerdrum, og lever alene 0.27 % av all grisekjøtt i Norge.

La oss se om vi kan vise denne informasjonen på en litt mer spennende måte. Vi kan da bruke Google Charts til å representere dataen geografisk. Google har kun oppløsning på fylkesnivå, så før vi kan bruke Google sitt API må først konsolidere opp dataen opp til fylkesnivå.

fylker = data.frame(fylkesnr=1:20,
                    fylkesnavn=c("Østfold", "Akershus", "Oslo", "Hedmark", "Oppland", "Buskerud", "Vestfold", "Telemark", "Aust-Agder","Vest-Agder","Rogaland","Hordaland","Bergen","Sogn og Fjordane","Møre og Romsdal", "Sør-Trøndelag","Nord-Trøndelag","Nordland","Troms","Finnmark" ))
pigs_fylker = group_by(pigs,fylkesnr) %>%
  summarise(total_kg = floor(sum(total_kg)))
pigs_fylker = merge(pigs_fylker,fylker)

Vi bruker så pakken “googleVis” som bruker Google sitt API til å lage interaktive grafer.

suppressPackageStartupMessages(library(googleVis))

## Creating a generic function for 'toJSON' from package 'jsonlite' in package 'googleVis'

op <- options(gvis.plot.tag='chart')
geostates = gvisGeoChart(pigs_fylker, "fylkesnavn", "total_kg",options=list(
  region="NO", 
  displaymode="regions", 
  resolution="provinces", 
  width=600,height=400,
  datalessRegionColor="#FFFFFF",
  colorAxis="{minValue:0,maxValue:50000000}"
  ))

plot(geostates)

Men… hva har skjedd med Aust-Agder? Det viser seg at Google har en feil i sin fylkesstruktur, slik at Aust-Agder er satt til å være det samme som Vest-Agder!

Undertegnede har sendt en bugrapport til Google, men inntil videre må vi istedet bruke koder fra ISO-3166-2 som navn på fylkene. Dette er koder som er på formen “NO-XX” der XX er fylkesnummeret. Om man bruker denne standarden vil Google plassere Aust-Agder riktig.

pigs_fylker$iso_code = sprintf("NO-%02d", pigs_fylker$fylkesnr)
geostates = gvisGeoChart(pigs_fylker, "iso_code", "total_kg",hovervar = "fylkesnavn", options=list(
  region="NO", 
  displaymode="regions", 
  resolution="provinces", 
  width=600,height=400,
  datalessRegionColor="#FFFFFF",
  colorAxis="{minValue:0,maxValue:50000000}"
  ))
plot(geostates)

Aust-Agder er på plass og vi har en fin statistikk over produksjon av grisekjøtt i Norge.