Erik Gahner Larsen

Publicer indlæg skrevet i R Markdown til WordPress

Forrige indlæg var skrevet i R (med R Markdown). Yihui Xie viser på sin blog, hvordan man med pakkerne RWordPress og knitr nemt kan publicere indlæg direkte fra R til WordPress. Her er scriptet for eventuelt interesserede:

library(RWordPress)
library(knitr)

options(WordPressLogin = c(brugernavn = 'kodeord'),
        WordPressURL = 'http://hjemmeside.dk/xmlrpc.php')
knit2wp('filnavn.Rmd', title = 'Titel på indlæg')

Der er kun fire informationer, der skal udskiftes (brugernavn, kodeord, URL og filnavn). Til ovenstående kan det desuden tilføjes, at knit2wp() giver mulighed for at specificere, hvilke kategorier indlægget skal publiceres under med categories = c('Politik', 'Medier') (og det samme med key words ved at anvende mt_keywords). Hvis man ikke vil have at indlægget skal publiceres direkte, kan man tilføje publish = FALSE, der som standard er sat til at være TRUE.

Det er yderst begrænset, hvor meget der er brug for at arbejde med manuelt i WordPress. Det eneste jeg ændrede manuelt i forrige indlæg var destinationen til billederne. Jeg har det bedst med at figurer anvendt i mine indlæg er at finde ét og samme sted.

Hent åbne data fra Folketinget ind i R

Folketinget er begyndt at gøre informationer tilgængelige i form af åbne data. Dette indlæg viser simpelt og illustrativt, hvordan man kan få hentet disse data ned fra Folketingets hjemmeside ind i R. Til at gøre dette gør jeg brug af pakkerne httr (der kan hente vores data ned fra Folketingets hjemmeside) og ggplot2 (der som altid kan hjælpe os med at lave et par grafer), begge udviklet af Hadley Wickham. Pakkerne er tilgængelige via CRAN og kan – når de er installeret – åbnes med:

library(httr)
library(ggplot2)

For at få et overblik over de forskellige data, der er tilgængelige som åbne data på Folketingets hjemmeside, kan du besøge http://oda.ft.dk/. Jeg valgte som det første at kigge på siden med afstemningerne i Folketinget og hente en sådan side i JSON format ind i R med funktionen GET() i httr pakken (jsonlite pakken er også ganske fin, hvis man skulle have lyst til at forsøge sig med andre pakker):

ft.vote.page <- GET("http://oda.ft.dk/api/Afstemning?$inlinecount=allpages&$skip=0")
ft.vote.page
## Response [http://oda.ft.dk/api/Afstemning?$inlinecount=allpages&$skip=0]
##   Date: 2015-03-15 02:19
##   Status: 200
##   Content-Type: application/json; charset=utf-8
##   Size: 5.92 kB
## {
##   "odata.metadata":"http://oda.ft.dk/api/%24metadata#Afstemning","odata....
##     {
##       "id":1,"nummer":411,"konklusion":"Vedtaget\n\n108 stemmer for fors...
##     },{
##       "id":2,"nummer":412,"konklusion":"Vedtaget\n\n98 stemmer for forsl...
##     },{
##       "id":4,"nummer":7,"konklusion":"3. behandling af L 46. Om akutjob....
##     },{
##       "id":5,"nummer":412,"konklusion":"Eventuelt: 3. behandling af L 20...
## ...

Ovenstående viser de åbne data (der også kan hentes i XML) og nogle af de informationer, der ligger gemt heri. Ved hjælp af content() funktionen i httr kan vi skabe et objekt i R, der gør det hele lidt nemmere at arbejde med. Foruden at gøre dette trækker vi et tal ud der viser, hvor mange afstemninger der er i datasættet i skrivende stund:

ft.vote.content <- content(ft.vote.page)
ft.vote.content$odata.count
## [1] "2463"

Den side vi har hentet rummer dog ikke alle 2463 afstemninger, men blot de første 20. Jeg kunne ikke fremkalde én side med alle afstemninger, men maksimalt få vist 20 afstemninger, hvorfor jeg i stedet lavede et par loops, der gemmer de første tyve afstemninger i en data frame, derefter supplerer med de næste tyve og så videre, indtil der ikke er flere afstemninger at hente. Jeg gemmer i nærværende tilfælde tre simple informationer fra hver afstemning: 1) id, 2) status på om forslaget blev forkastet eller vedtaget samt 3) afstemningstypenummer.

ft.vote <- data.frame(NA,NA,NA)
seqnr <- seq(0, as.numeric(ft.vote.content$odata.count) - 20, 20)

for(i in seqnr) {
  link <- paste0("http://oda.ft.dk/api/Afstemning?$inlinecount=allpages&$skip=",i)
  ft.temp <- GET(link)
  ft.temp.content <- content(ft.temp)
  for(j in 1:20) {
    ft.vote[i + j,] <- c(ft.temp.content$value[[j]]$id,
                         ft.temp.content$value[[j]]$vedtaget,
                         ft.temp.content$value[[j]]$typeid)
  }
}

Den første linje laver en tom data frame, den anden linje en vektor med information omkring, hvilke sider vi skal hente data fra, for at få alle afstemninger. Derefter henter R alle afstemningerne ned, tyve afstemninger pr. side, og gemmer id, vedtaget og typeid i vores data frame ft.vote. Kombineret med en navngivning af vores variable får vi så følgende output:

names(ft.vote) <- c("id","vedtaget","typeid")
head(ft.vote)
##   id vedtaget typeid
## 1  1        1      2
## 2  2        1      1
## 3  4        1      1
## 4  5        1      1
## 5  6        1      1
## 6  7        0      1

For at blive klogere på, hvilke typer af afstemninger der er tale om, henter vi siden med afstemningstyper ned i R og kobler informationerne herfra sammen med typeid i vores ft.vote data frame.

typer.get <- GET("http://oda.ft.dk/api/Afstemningstype?$inlinecount=allpages")
typer.indhold <- content(typer.get)

ft.vote$type <- NA
ft.vote$type[ft.vote$typeid==1] <- typer.indhold$value[[1]]$type
ft.vote$type[ft.vote$typeid==2] <- typer.indhold$value[[2]]$type
ft.vote$type[ft.vote$typeid==3] <- typer.indhold$value[[3]]$type
ft.vote$type[ft.vote$typeid==4] <- typer.indhold$value[[4]]$type

ft.vote$type <- gsub("<U\\+00c6>", "Æ", ft.vote$type)

Den sidste linje i ovenstående ændrer <U+00c6> til et Æ, da Folketingets system ikke kan vise den slags tegn. Derefter laver vi en variabel, vedtaget, der har teksten Forkastet såfremt lovforslaget er forkastet og Vedtaget hvis lovforslaget er, ja, vedtaget. Dette giver os en samlet data frame, der ser ud som følger:

ft.vote$resultat <- NA
ft.vote$resultat[ft.vote$vedtaget==FALSE] <- "Forkastet"
ft.vote$resultat[ft.vote$vedtaget==TRUE] <- "Vedtaget"

head(ft.vote)
##   id vedtaget typeid               type  resultat
## 1  1        1      2 Udvalgsindstilling  Vedtaget
## 2  2        1      1 Endelig vedtagelse  Vedtaget
## 3  4        1      1 Endelig vedtagelse  Vedtaget
## 4  5        1      1 Endelig vedtagelse  Vedtaget
## 5  6        1      1 Endelig vedtagelse  Vedtaget
## 6  7        0      1 Endelig vedtagelse Forkastet

Vi kan nu få et visuelt overblik over, hvilke typer af afstemninger, der er i databasen med de åbne data:

ggplot(ft.vote, aes(type)) + geom_bar() +
  theme_bw() +
  xlab("Type") +
  ylab("Antal")

Langt de flete afsteninger i de åbne data vedrører afstemninger sendt til endelig vedtagelse og kun meget få vedrører udvalgsindstillinger. Vi kan også se nærmere på, om der er forskelle i hvilke typer af afstemninger der bliver vedtaget (hvilket der af meget logiske årsager er):

ggplot(ft.vote, aes(resultat)) + geom_bar() +
  facet_wrap(~ type) + 
  theme_bw() +
  xlab("") +
  ylab("Antal") 

Som det kan ses bliver afstemninger omkring endelig vedtagelse oftere vedtaget end forkastet, hvor det modsatte er tilfældet for ændringsforslag. Ovenstående er ét eksempel på, hvordan man kan hente data ned og kombinere dem fra Folketingets åbne data, og der er givetvis mange forskellige måder at gøre dette på. Ligeledes er der flere forskellige sider at hente ned og kombinere på hjemmesiden, så bare fordi afstemninger ikke nødvendigvis er det mest interessante, betyder det ikke, at det ikke kan kombineres med andre spændende data. God fornøjelse.

Hvornår kommer folketingsvalget? De politiske kommentatorers bud

Det har været behageligt at følge medierne i den seneste tid sammenlignet med perioden forud for forrige folketingsvalg, hvor blandt andet tætte meningsmålinger gjorde, at medierne allerede et år før der senest skulle udskrives valg, talte om valgkamp.

Der kommer et folketingsvalg i år. Så meget ved vi. Vi ved dog ikke, hvornår det helt præcist kommer til at ligge. Heldigvis har vi en lang række af politiske kommentatorer, der kan gøre os klogere på, hvornår valget efter al sandsynlighed vil finde sted. Berlingske og TV2 News har spurgt 12 politiske kommentatorer, og deres svar er overordnet set ikke just i nærheden af hinanden. Én ting kan vi derfor sige med sikkerhed: Der vil være kommentatorer, der tager grueligt fejl. Dette er der selvfølgelig intet nyt i.

De tolv politiske kommentatorer, med deres forudsigelse i parentes, er David Trads (29. april), Søs Marie Serup (5. maj), Jarl Cordua (12. maj), Jesper Termansen (19. maj), Christine Cordsen (28. maj), Anders Langballe (9. juni), Hans Engell (9. juni), Casper Dall (25. august), Erik Holsten (1. september), Troels Mylenberg (8. september), Helle Ib (10. september) og Peter Mogensen (15. september).

På samme måde som vi kan sige, at der er kommentatorer der vil tage fejl, er der også en kommentator eller to, der vil ramme en dato tæt på hvad der vil vise sig at være valgdagen. Denne præstation bør give den samme faglige respekt som den kunst det er at ramme bullseye på en dartskive med bind for øjnene efter otte fadøl. Der er i bund og grund ingen grund til at tage sådanne gæt seriøst, men når man læser kommentatorernes argumentation for deres respektive valg, virker det rent faktisk som om, at de selv tror på det. Det er mig en gåde at journalister formidler den slags, med mindre formålet selvfølgelig er at udstille, hvor lidt vi kan bruge politiske kommentatorer til.

Det betyder selvfølgelig ikke, at vi ikke kan diskutere om nogle dage er mere sandsynlige end andre. Hvis man kigger på meningsmålingerne, taler intet for et tidligt valg. David Trads’ manglende evne til at forstå meningsmålinger kan eksempelvis være en plausibel forklaring på, at han som den eneste regner med et valg allerede i april. Det er ærgerligt hvis sådanne gætterier er glemt når først valget er udskrevet, hvornår det så end finder sted. Derfor: Gem ovenstående datoer og hold de politiske kommentatorer ansvarlige for deres gætterier.