DR er så venlig at lave en side som viser alle valgresulterne efter område i et fint kort. Uheldigvis er det ikke så nemt at få fat i dataene.
Så er det godt at vi kan skrabe dem. 🙂
Data til download:
Lidt detaljer om koden
Siden loader først et kort (vist ovenfor) og en række mindre områder på kortet (storkredse og kredse) i json format. De egentlige data bliver loadet senere, så vidt jeg kan se. Dataene om kortet indeholder ikke selve valgstederne, som i stedet findes i en liste på siden. Når man vælger et valgsted, så henter browseren en json fil med tallene. Disse filer følger et simpelt ID format, så man kan hente dem alle sammen med et loop. Underligt nok er der en del huller, nemlig IDer som ikke svarer til et valgsted. Når man forsøger at hente en af dem (fx id=4) så gir DR bare en 404. Så hvordan ved man hvor mange der er? Jeg prøver bare alle sammen indtil jeg har fået 100 fejl i træk. Det virker usandsynligt at der skulle være flere bagefter det. Hvis man følger denne regel, så er der 1386 valgsteder. Ved valget til EU i 2014 var der 1396, så det tal lyder plausibelt.
De enkelte json filer indeholder ikke valgstederne beliggenhed, uheldigvis. De indeholder dog id’et på den kreds valgstedet er i, og dette id finder man i dataene fra valgkortet. De indeholder også valgstedets navn, men det er ikke altid brugbart. Fx “Østre” eller “1. Nord”. Sætter man det sammen med kredsens navn, så gir det dog mening: “Østre – Svendborg”, “1. Nord – Østerbro” (Københavns Storkreds).
R kode til skrabning
# udtræk stemmedata fra DR ------------------------------------------------ #json library(pacman) p_load(stringr, rjson) #hent json json = fromJSON(file = "http://www.dr.dk/tjenester/fa15-result-data/map/fa2015") #inspicer #lad hellere vær for det er noget rod! lister i lister i liste str(json) #lav en flad version json_flat = unlist(json) #for at lave om til 2D, så skal de finde hver kolonne #det kan gøres efter navnene. Der er 7 slags. v_kolonnenavne = names(json_flat)[1:7] #df d = list() #loop di loop for (kolonne in v_kolonnenavne) { logi = str_detect(names(json_flat), kolonne) #kan godt fejle hvis en kolonne ikke findes alle steder try({d[[kolonne]] = json_flat[logi]}) } #lav om til df #gir en fejl hvis vektorne ikke er lige lange d = as.data.frame(d) # download valgsteddata --------------------------------------------------------- #startobjekter json2 = list() fejl_i_træk = 0 #loopy loop for (id in 1:5000) { #stop hvis ikke mere data, måske #stop efter 100 fejl i træk if (fejl_i_træk == 100) break #progression str_c("prøver id", id) %>% message #lav url url = str_c("http://www.dr.dk/tjenester/fa15-result-data/results/fa2015/afstemningssted/", id) #download med try trial = try({get = fromJSON(file = url)}, T) if ("try-error" %in% class(trial)) { str_c("id ", id, " fejlede") %>% message fejl_i_træk = fejl_i_træk + 1 next } #ellers gem json2[[id]] = get fejl_i_træk = 0 } #gem data save(json2, file = "valgdata.RDS") #navne names(json2) = 1:length(json2) #fjern de tomme id'er json2 = json2[sapply(json2, Negate(is.null))] #konverter til 2D df #hvilke data vil vi gemme? v_kolonnenavne2 = c("AreaType", "ID", "ParentID", "GrandParentID", "Name", "Eligable", "Turnout", "Yes", "No", "Invalid", "Abstained") #objekt d2 = as.data.frame(matrix(nrow = length(json2), ncol = length(v_kolonnenavne2))) colnames(d2) = v_kolonnenavne2 #loop de loop for (idx in seq_along(json2)) { #main for (var in v_kolonnenavne2[1:5]) { d2[idx, var] = json2[[idx]][var] } #metrics for (var in v_kolonnenavne2[6:7]) { d2[idx, var] = json2[[idx]][["Metrics"]][[var]] } #Chart for (var in v_kolonnenavne2[8:11]) { d2[idx, var] = json2[[idx]][["Chart"]][[var]] } }