{"id":3202,"date":"2015-12-04T19:48:43","date_gmt":"2015-12-04T18:48:43","guid":{"rendered":"http:\/\/emilkirkegaard.dk\/da\/?p=3202"},"modified":"2015-12-04T20:12:42","modified_gmt":"2015-12-04T19:12:42","slug":"valgdata-fra-eu-valget-i-2015-fra-dr-dk","status":"publish","type":"post","link":"https:\/\/emilkirkegaard.dk\/da\/?p=3202","title":{"rendered":"Valgdata fra EU-valget i 2015 fra DR.dk"},"content":{"rendered":"<p><a href=\"http:\/\/www.dr.dk\/nyheder\/politik\/eu15\/resultater\">DR er s\u00e5 venlig at lave en side<\/a> som viser alle valgresulterne efter omr\u00e5de i et fint kort. Uheldigvis er det ikke s\u00e5 nemt at f\u00e5 fat i dataene.<\/p>\n<p><a href=\"http:\/\/emilkirkegaard.dk\/da\/wp-content\/uploads\/valg_dr.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3203\" src=\"http:\/\/emilkirkegaard.dk\/da\/wp-content\/uploads\/valg_dr.png\" alt=\"valg_dr\" width=\"543\" height=\"678\" srcset=\"https:\/\/emilkirkegaard.dk\/da\/wp-content\/uploads\/valg_dr.png 543w, https:\/\/emilkirkegaard.dk\/da\/wp-content\/uploads\/valg_dr-240x300.png 240w\" sizes=\"auto, (max-width: 543px) 100vw, 543px\" \/><\/a><\/p>\n<p>S\u00e5 er det godt at vi kan <a href=\"https:\/\/en.wikipedia.org\/wiki\/Web_scraping\">skrabe<\/a> dem. \ud83d\ude42<\/p>\n<p>Data til download:<\/p>\n<ul>\n<li><a href=\"http:\/\/emilkirkegaard.dk\/da\/wp-content\/uploads\/valgkort.csv\">Data fra kortet, uden valgdata men med struktur.<\/a><\/li>\n<li><a href=\"http:\/\/emilkirkegaard.dk\/da\/wp-content\/uploads\/valgdata.csv\">Valgdata<\/a>.<\/li>\n<\/ul>\n<h3>Lidt detaljer om koden<\/h3>\n<p>Siden loader f\u00f8rst et kort (vist ovenfor) og en r\u00e6kke mindre omr\u00e5der p\u00e5 kortet (storkredse og kredse) i <a href=\"https:\/\/en.wikipedia.org\/wiki\/JSON\">json<\/a> format. De egentlige data bliver loadet senere, s\u00e5 vidt jeg kan se. Dataene om kortet indeholder ikke selve valgstederne, som i stedet findes i en liste p\u00e5 siden. N\u00e5r man v\u00e6lger et valgsted, s\u00e5 henter browseren <a href=\"http:\/\/www.dr.dk\/tjenester\/fa15-result-data\/results\/fa2015\/afstemningssted\/1806\">en json fil med tallene<\/a>. Disse filer f\u00f8lger et simpelt ID format, s\u00e5 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\u00e5r man fors\u00f8ger at hente en af dem (<a href=\"http:\/\/www.dr.dk\/tjenester\/fa15-result-data\/results\/fa2015\/afstemningssted\/4\">fx id=4<\/a>) s\u00e5 gir DR bare en 404. S\u00e5 hvordan ved man hvor mange der er? Jeg pr\u00f8ver bare alle sammen indtil jeg har f\u00e5et 100 fejl i tr\u00e6k. Det virker usandsynligt at der skulle v\u00e6re flere bagefter det. Hvis man f\u00f8lger denne regel, s\u00e5 er der 1386 valgsteder. <a href=\"http:\/\/www.dr.dk\/nyheder\/politik\/valg2015\/valgsteder-stemmeoptaelling-og-valgdeltagelse-valget-i-tal\">Ved valget til EU i 2014 var der 1396<\/a>, s\u00e5 det tal lyder plausibelt.<\/p>\n<p>De enkelte json filer indeholder ikke valgstederne beliggenhed, uheldigvis. De indeholder dog id&#8217;et p\u00e5 den kreds valgstedet er i, og dette id finder man i dataene fra valgkortet. De indeholder ogs\u00e5 valgstedets navn, men det er ikke altid brugbart. Fx &#8220;\u00d8stre&#8221; eller &#8220;1. Nord&#8221;. S\u00e6tter man det sammen med kredsens navn, s\u00e5 gir det dog mening: &#8220;\u00d8stre &#8211; Svendborg&#8221;, &#8220;1. Nord &#8211; \u00d8sterbro&#8221; (K\u00f8benhavns Storkreds).<\/p>\n<h3>R kode til skrabning<\/h3>\n<pre># udtr\u00e6k stemmedata fra DR ------------------------------------------------\r\n#json\r\nlibrary(pacman)\r\np_load(stringr, rjson)\r\n\r\n#hent json\r\njson = fromJSON(file = \"http:\/\/www.dr.dk\/tjenester\/fa15-result-data\/map\/fa2015\")\r\n\r\n#inspicer\r\n#lad hellere v\u00e6r for det er noget rod! lister i lister i liste\r\nstr(json)\r\n\r\n#lav en flad version\r\njson_flat = unlist(json)\r\n\r\n#for at lave om til 2D, s\u00e5 skal de finde hver kolonne\r\n#det kan g\u00f8res efter navnene. Der er 7 slags.\r\nv_kolonnenavne = names(json_flat)[1:7]\r\n\r\n#df\r\nd = list()\r\n\r\n#loop di loop\r\nfor (kolonne in v_kolonnenavne) {\r\n\u00a0 logi = str_detect(names(json_flat), kolonne)\r\n\u00a0 \r\n\u00a0 #kan godt fejle hvis en kolonne ikke findes alle steder\r\n\u00a0 try({d[[kolonne]] = json_flat[logi]})\r\n}\r\n\r\n#lav om til df\r\n#gir en fejl hvis vektorne ikke er lige lange\r\nd = as.data.frame(d)\r\n\r\n\r\n# download valgsteddata ---------------------------------------------------------\r\n#startobjekter\r\njson2 = list()\r\nfejl_i_tr\u00e6k = 0\r\n\r\n#loopy loop\r\nfor (id in 1:5000) {\r\n\u00a0 #stop hvis ikke mere data, m\u00e5ske\r\n\u00a0 #stop efter 100 fejl i tr\u00e6k\r\n\u00a0 if (fejl_i_tr\u00e6k == 100) break\r\n\u00a0 \r\n\u00a0 #progression\r\n\u00a0 str_c(\"pr\u00f8ver id\", id) %&gt;% message\r\n\u00a0 \r\n\u00a0 #lav url\r\n\u00a0 url = str_c(\"http:\/\/www.dr.dk\/tjenester\/fa15-result-data\/results\/fa2015\/afstemningssted\/\", id)\r\n\u00a0 \r\n\u00a0 #download med try\r\n\u00a0 trial = try({get = fromJSON(file = url)}, T)\r\n\u00a0 if (\"try-error\" %in% class(trial)) {\r\n\u00a0\u00a0\u00a0 str_c(\"id \", id, \" fejlede\") %&gt;% message\r\n\u00a0\u00a0\u00a0 fejl_i_tr\u00e6k = fejl_i_tr\u00e6k + 1\r\n\u00a0\u00a0\u00a0 next\r\n\u00a0 }\r\n\u00a0 \r\n\u00a0 #ellers gem\r\n\u00a0 json2[[id]] = get\r\n\u00a0 fejl_i_tr\u00e6k = 0\r\n}\r\n\r\n#gem data\r\nsave(json2, file = \"valgdata.RDS\")\r\n\r\n#navne\r\nnames(json2) = 1:length(json2)\r\n\r\n#fjern de tomme id'er\r\njson2 = json2[sapply(json2, Negate(is.null))]\r\n\r\n#konverter til 2D df\r\n#hvilke data vil vi gemme?\r\nv_kolonnenavne2 = c(\"AreaType\", \"ID\", \"ParentID\", \"GrandParentID\", \"Name\", \"Eligable\", \"Turnout\", \"Yes\", \"No\", \"Invalid\", \"Abstained\")\r\n\r\n#objekt\r\nd2 = as.data.frame(matrix(nrow = length(json2), ncol = length(v_kolonnenavne2)))\r\ncolnames(d2) = v_kolonnenavne2\r\n\r\n#loop de loop\r\nfor (idx in seq_along(json2)) {\r\n\u00a0 #main\r\n\u00a0 for (var in v_kolonnenavne2[1:5]) {\r\n\u00a0\u00a0\u00a0 d2[idx, var] = json2[[idx]][var]\r\n\u00a0 }\r\n\u00a0 \r\n\u00a0 #metrics\r\n\u00a0 for (var in v_kolonnenavne2[6:7]) {\r\n\u00a0\u00a0\u00a0 d2[idx, var] = json2[[idx]][[\"Metrics\"]][[var]]\r\n\u00a0 }\r\n\u00a0 \r\n\u00a0 #Chart\r\n\u00a0 for (var in v_kolonnenavne2[8:11]) {\r\n\u00a0\u00a0\u00a0 d2[idx, var] = json2[[idx]][[\"Chart\"]][[var]]\r\n\u00a0 }\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>DR er s\u00e5 venlig at lave en side som viser alle valgresulterne efter omr\u00e5de i et fint kort. Uheldigvis er det ikke s\u00e5 nemt at f\u00e5 fat i dataene. S\u00e5 er det godt at vi kan skrabe dem. \ud83d\ude42 Data til download: Data fra kortet, uden valgdata men med struktur. Valgdata. Lidt detaljer om koden [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1711],"tags":[244,1749,1750,1747,1748],"class_list":["post-3202","post","type-post","status-publish","format-standard","hentry","category-politik-videnskab-og-lign","tag-data","tag-dr","tag-eu-valg-2015","tag-r","tag-skrabning"],"_links":{"self":[{"href":"https:\/\/emilkirkegaard.dk\/da\/index.php?rest_route=\/wp\/v2\/posts\/3202","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/emilkirkegaard.dk\/da\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/emilkirkegaard.dk\/da\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/emilkirkegaard.dk\/da\/index.php?rest_route=\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/emilkirkegaard.dk\/da\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3202"}],"version-history":[{"count":4,"href":"https:\/\/emilkirkegaard.dk\/da\/index.php?rest_route=\/wp\/v2\/posts\/3202\/revisions"}],"predecessor-version":[{"id":3210,"href":"https:\/\/emilkirkegaard.dk\/da\/index.php?rest_route=\/wp\/v2\/posts\/3202\/revisions\/3210"}],"wp:attachment":[{"href":"https:\/\/emilkirkegaard.dk\/da\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3202"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/emilkirkegaard.dk\/da\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3202"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/emilkirkegaard.dk\/da\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3202"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}