Ein kode for mandatfordeling

Slik kan du rekne på stortingsfordeling av alle moglege meiningsmålingar og røysteresultat.


Då eg byrja som politisk journalist, fekk eg tidleg lyst å lage eit system for sjølv å rekne ut mandatfordelingar. Den gongen (som no) fekk vi gjerne ei meiningsmåling med mandatfordelinga fiks ferdig servert frå eit byrå. Sjølve hadde vi liten kontroll over utrekninga. Og det var tungvint å rekne på eigne tal.

Eg allierte meg den gongen med ein mattekyndig kompis (han er no doktor i matte) som laga eit Excel-rekneark som gjorde jobben. Men det var óg tungvint å bruke, og det var feilkjelder.

No, takka vere R, er slike jobbar blitt enklare. De har kanskje sett denne tenesta som Oddbjørn Øvernes og eg har laga. Der finn du 430 tenkte storting, slik kommunane ville vald dei i 2009.

Eg har laga ein generisk R-kode som kan ta alle slags tallister og berekne mandatfordeling på Stortinget. Utgangspunktet er eit Excel-dokument (.xlsx) med ein kolonne for parti (eller andre namngjevne kategoriar) og ein kolonne for tal. Det kan vere absolutte tal eller prosentfordeling, det speler inga rolle. Men førstnemnde er meir nøyaktig og derfor å føretrekke.

Du treng biblioteket gdata for å lese Excel-filar. Og du set rett sti til mappa du jobbar i først:

# Rekne ut Stortinget
# Ein kolonne med partiar, ein kolonne med resultat
# Bruk .xslx-filer for å få rett æ, ø og å
setwd ('/SETT INN LOKAL STI TIL MAPPE/')
library(gdata)
ting <- read.xls('tot.xlsx', header=TRUE, stringsAsFactors=FALSE)
ting[,2] <- as.numeric(ting[,2])

Når data er lasta inn, kjem sjølve mandatutrekninga. I Norge nyttar vi St. Laguës modifiserte metode: Stemmetala delast først på 1.4, deretter på 3,5,7 osv.
Eg gjer 169 delingar, for det usannsynlege tilfellet at eitt parti får alle 169 plassane på Stortinget.
(Koden kan sjølvsagt modifiserast til andre forsamlingar. Til dømes har bystyret i Bergen 67 plassar.)

#Mandatutrekning, St. Laguës metode
man <- matrix(nrow=length(ting[,2]), ncol=169) #Lagar ein matrise med like mange radar som tal på parti og 169 kolonnar
man[,1] <- round(ting[,2]/1.4, digits=2) #Første deling på 1.4 plasserast i matrisens kolonne 1
o <- 3 # Ein for-loop som delar tala på oddetal og plasserer det heile inn i resten av matrisen
for (i in 2:169) {
man[,i] <- round(ting[,2]/o, digits=2)
o <- o+2
}
man <- data.frame(man) # Eg likar å ha data som ein data frame
ting <- as.data.frame(append(ting,man))

# No må eg trekke ut dei 169 høgaste deletala.
df <- ting

# col1 lagar ei liste med repeterande partinamn, like lang som matrisen.
# col2 fyllast med tal frå matrisen.
col1 <- rep(df[,1],ncol(df)-2)
col2 <- c()
for(i in 3:ncol(df)) {
col2 <- c(col2,df[,i])
}

# man er ein data frame sett saman av listene col1 og col2.
# No sorterer vi 'man' i synkande rekkefølge og klipper han av etter 169 tal (sidan det er 169 representantar på Stortinget.)
man <- data.frame(parti=col1,deltall=col2, stringsAsFactors=FALSE)
man <- man[order(as.numeric(man[,2]),decreasing=TRUE),]
man <- man[1:169,]
rownames(man) <- 1:169

ting <- table(t(man))
mandater <- function(x) { tail(ting, n = x) }

# Du kan lage lista med denne funksjonen viss du veit kor mange parti det er: ting <- mandater(x)

# Denne koden lagar ein data frame med ferdige resultat.
tabell <- tapply(man$deltall, man$parti, length)
tabell <- as.data.frame(tabell)
tabell[is.na(tabell)] <- 0

print(tabell)