Compare commits
11
Commits
package
...
b110df35ac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b110df35ac | ||
|
|
41a70eaaf0 | ||
|
|
8e473bf094 | ||
|
|
ce8e9fdf62 | ||
|
|
56e5efa0d4 | ||
|
|
a4b822099c | ||
|
|
2abb3467e8 | ||
|
|
f09cbac172 | ||
|
|
ab55363c4e | ||
|
|
a86ddfec83 | ||
|
|
574480a9bb |
@@ -0,0 +1,2 @@
|
|||||||
|
^doc$
|
||||||
|
^Meta$
|
||||||
@@ -1 +1,6 @@
|
|||||||
*.xml
|
*.xml
|
||||||
|
/doc/
|
||||||
|
/Meta/
|
||||||
|
/reports/
|
||||||
|
!/reports/*.pdf
|
||||||
|
!/reports/*.tex
|
||||||
|
|||||||
+4
-1
@@ -17,10 +17,13 @@ RoxygenNote: 7.1.1
|
|||||||
Imports:
|
Imports:
|
||||||
dplyr,
|
dplyr,
|
||||||
pbapply,
|
pbapply,
|
||||||
|
purrr,
|
||||||
rvest,
|
rvest,
|
||||||
stringr,
|
stringr,
|
||||||
|
tibble,
|
||||||
xml2
|
xml2
|
||||||
Suggests:
|
Suggests:
|
||||||
rmarkdown,
|
rmarkdown,
|
||||||
knitr
|
knitr,
|
||||||
|
ggplot2
|
||||||
VignetteBuilder: knitr
|
VignetteBuilder: knitr
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
# Generated by roxygen2: do not edit by hand
|
# Generated by roxygen2: do not edit by hand
|
||||||
|
|
||||||
|
export(fetch_all)
|
||||||
|
export(read_all)
|
||||||
|
export(repair)
|
||||||
import(dplyr)
|
import(dplyr)
|
||||||
import(pbapply)
|
import(pbapply)
|
||||||
|
import(purrr)
|
||||||
import(stringr)
|
import(stringr)
|
||||||
import(tibble)
|
import(tibble)
|
||||||
|
import(utils)
|
||||||
import(xml2)
|
import(xml2)
|
||||||
|
|||||||
@@ -30,17 +30,50 @@ fetch_batch <- function(offset, download_dir) {
|
|||||||
# TODO: error handling
|
# TODO: error handling
|
||||||
# - what if: page not reachable
|
# - what if: page not reachable
|
||||||
# - wrong format, etc.
|
# - wrong format, etc.
|
||||||
fetch_all <- function(download_dir="records/") {
|
|
||||||
|
#' Download available records
|
||||||
|
#'
|
||||||
|
#' This fetches all available records of the 19th legislative period of the german Bundestag.
|
||||||
|
#'
|
||||||
|
#' @param download_dir character
|
||||||
|
#'
|
||||||
|
#' @export
|
||||||
|
fetch_all <- function(download_dir="records/", create=FALSE) {
|
||||||
|
# check if download_dir path is a directory path
|
||||||
|
if (str_sub(download_dir, -1) != .Platform$file.sep)
|
||||||
|
download_dir <- str_c(download_dir, .Platform$file.sep)
|
||||||
|
|
||||||
|
# check if download_dir exists
|
||||||
|
if(file.access(download_dir, mode=0) == -1) {
|
||||||
|
if (create) {
|
||||||
|
tryCatch(dir.create(download_dir),
|
||||||
|
error = stop_dir_not_creatable,
|
||||||
|
warning = stop_dir_not_creatable)
|
||||||
|
} else {
|
||||||
|
stop("Directory does not exist. Use create = TRUE if you wish to create the directory.")
|
||||||
|
}
|
||||||
|
} else if (file.access(download_dir, mode=2) == -1) {
|
||||||
|
stop("Directory exists, but is not writeable.")
|
||||||
|
}
|
||||||
cat("Fetching all available records from bundestag.de. This may take a while ...\n")
|
cat("Fetching all available records from bundestag.de. This may take a while ...\n")
|
||||||
|
|
||||||
# create progress bar
|
# create progress bar
|
||||||
pb <<- timerProgressBar(min=0, max=250, width=40, char="+")
|
pb <<- timerProgressBar(min=0, max=250, width=40, char="+")
|
||||||
progress <<- 0
|
progress <<- 0
|
||||||
# close progress bar on exit (also on error)
|
# close progress bar on exit (also on error)
|
||||||
on.exit({close(pb); cat("Done.\n")})
|
on.exit({close(pb); cat("Done.\n")})
|
||||||
|
|
||||||
# fetch batch by batch
|
# fetch batch by batch
|
||||||
offset <- 0
|
offset <- 0
|
||||||
while(fetch_batch(offset, download_dir)) offset <- offset + 10
|
while(fetch_batch(offset, download_dir)) offset <- offset + 10
|
||||||
|
|
||||||
# if successful, set progressbar to 100%
|
# if successful, set progressbar to 100%
|
||||||
setTimerProgressBar(pb, 250)
|
setTimerProgressBar(pb, 250)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stop_dir_not_creatable <- function(cond) {
|
||||||
|
# currently this has call: dir.create(download_dir)
|
||||||
|
# do we want to change this to fetch_all(...) ?
|
||||||
|
cond$message <- "Directory does not exist and can't be created. Probably because the path is not writeable."
|
||||||
|
stop(cond)
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#' @import pbapply
|
#' @import pbapply
|
||||||
#' @import stringr
|
#' @import stringr
|
||||||
#' @import xml2
|
#' @import xml2
|
||||||
|
#' @import utils
|
||||||
|
#' @import purrr
|
||||||
#' @keywords internal
|
#' @keywords internal
|
||||||
"_PACKAGE"
|
"_PACKAGE"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
`%$%` <- function(f, x) f(x)
|
`%$%` <- function(f, x) f(x)
|
||||||
`%.%` <- function(f, g) function(...) f(g(...))
|
`%.%` <- function(f, g) function(...) f(g(...))
|
||||||
|
flip <- function(f) function(x, y) f(y, x)
|
||||||
|
|
||||||
clear_na <- function(xs) xs[!is.na(xs)]
|
clear_na <- function(xs) xs[!is.na(xs)]
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
# for usage see the example at the end
|
# for usage see the example at the end
|
||||||
|
|
||||||
|
#' Parse xml records
|
||||||
|
#'
|
||||||
|
#' Creates a list of tibbles containing relevant information from all records
|
||||||
|
#' stored in the input directory.
|
||||||
|
#'
|
||||||
|
#' @param path character
|
||||||
|
#'
|
||||||
|
#' @export
|
||||||
read_all <- function(path="records/") {
|
read_all <- function(path="records/") {
|
||||||
cat("Reading all records from", path, "\n")
|
cat("Reading all records from", path, "\n")
|
||||||
available_protocols <- list.files(path)
|
available_protocols <- list.files(path)
|
||||||
@@ -20,7 +28,14 @@ read_all <- function(path="records/") {
|
|||||||
distinct() ->
|
distinct() ->
|
||||||
talks
|
talks
|
||||||
|
|
||||||
list(redner = redner, reden = reden, talks = talks)
|
lapply(res, `[[`, "comments") %>%
|
||||||
|
bind_rows() %>%
|
||||||
|
distinct() ->
|
||||||
|
comments
|
||||||
|
|
||||||
|
if (length(available_protocols) == 0)
|
||||||
|
warning("The given directory is empty or does not exist.")
|
||||||
|
list(redner = redner, reden = reden, talks = talks, comments = comments)
|
||||||
}
|
}
|
||||||
|
|
||||||
# this reads all currently parseable data from one xml
|
# this reads all currently parseable data from one xml
|
||||||
@@ -42,7 +57,7 @@ read_one <- function(name, path) {
|
|||||||
parse_redenliste() ->
|
parse_redenliste() ->
|
||||||
res
|
res
|
||||||
|
|
||||||
list(redner = redner, reden = res$reden, talks = res$talks)
|
list(redner = redner, reden = res$reden, talks = res$talks, comments = res$comments)
|
||||||
}
|
}
|
||||||
|
|
||||||
xml_get <- function(node, name) {
|
xml_get <- function(node, name) {
|
||||||
@@ -78,23 +93,39 @@ parse_rede <- function(rede_xml) {
|
|||||||
principal_redner <- NA_character_
|
principal_redner <- NA_character_
|
||||||
cur_content <- ""
|
cur_content <- ""
|
||||||
reden <- list()
|
reden <- list()
|
||||||
|
comments <- list()
|
||||||
for (node in cs) {
|
for (node in cs) {
|
||||||
if (xml_name(node) == "p") {
|
if (xml_name(node) == "p" || xml_name(node) == "name") {
|
||||||
klasse <- xml_attr(node, "klasse")
|
klasse <- xml_attr(node, "klasse")
|
||||||
if (!is.na(klasse) && klasse == "redner") {
|
if ((!is.na(klasse) && klasse == "redner") || xml_name(node) == "name") {
|
||||||
if (!is.na(cur_redner)) {
|
if (!is.na(cur_redner)) {
|
||||||
rede <- c(rede_id = rede_id,
|
rede <- c(rede_id = rede_id,
|
||||||
redner = cur_redner,
|
redner = cur_redner,
|
||||||
content = cur_content)
|
content = cur_content)
|
||||||
reden <- c(reden, list(rede))
|
reden <- c(reden, list(rede))
|
||||||
cur_content <- ""
|
cur_content <- ""
|
||||||
} else {
|
}
|
||||||
|
if (is.na(principal_redner) && xml_name(node) != "name") {
|
||||||
principal_redner <- xml_child(node) %>% xml_attr("id")
|
principal_redner <- xml_child(node) %>% xml_attr("id")
|
||||||
}
|
}
|
||||||
cur_redner <- xml_child(node) %>% xml_attr("id")
|
if (xml_name(node) == "name") {
|
||||||
|
cur_redner <- "BTP"
|
||||||
|
} else {
|
||||||
|
cur_redner <- xml_child(node) %>% xml_attr("id")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cur_content <- paste0(cur_content, xml_text(node), sep="\n")
|
cur_content <- paste0(cur_content, xml_text(node), sep="\n")
|
||||||
}
|
}
|
||||||
|
} else if (xml_name(node) == "kommentar") {
|
||||||
|
# comments are of the form
|
||||||
|
# <kommentar>(blabla [Fraktion] – blabla liasdf – bla)</kommentar>
|
||||||
|
xml_text(node) %>%
|
||||||
|
str_sub(2, -2) %>%
|
||||||
|
str_split("–") %>%
|
||||||
|
`[[`(1) %>%
|
||||||
|
lapply(parse_comment, rede_id = rede_id, on_redner = cur_redner) ->
|
||||||
|
cs
|
||||||
|
comments <- c(comments, cs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rede <- c(rede_id = rede_id,
|
rede <- c(rede_id = rede_id,
|
||||||
@@ -102,7 +133,30 @@ parse_rede <- function(rede_xml) {
|
|||||||
content = cur_content)
|
content = cur_content)
|
||||||
reden <- c(reden, list(rede))
|
reden <- c(reden, list(rede))
|
||||||
list(rede = c(id = rede_id, redner = principal_redner),
|
list(rede = c(id = rede_id, redner = principal_redner),
|
||||||
parts = reden)
|
parts = reden,
|
||||||
|
comments = comments)
|
||||||
|
}
|
||||||
|
|
||||||
|
fraktionspattern <- "BÜNDNIS(SES)?\\W*90/DIE\\W*GRÜNEN|CDU/CSU|AfD|SPD|DIE LINKE|FDP|LINKEN"
|
||||||
|
fraktionsnames <- c("BÜNDNIS 90/DIE GRÜNEN", "CDU/CSU", "AfD", "SPD", "DIE LINKE", "FDP")
|
||||||
|
|
||||||
|
parse_comment <- function(comment, rede_id, on_redner) {
|
||||||
|
base <- c(rede_id = rede_id, on_redner = on_redner)
|
||||||
|
str_extract_all(comment, fraktionspattern) %>%
|
||||||
|
`[[`(1) %>%
|
||||||
|
sapply(partial(flip(head), 1) %.% agrep, x=fraktionsnames, max=0.2, value=T) %>%
|
||||||
|
str_c(collapse=",") ->
|
||||||
|
by
|
||||||
|
# classify comment
|
||||||
|
# TODO:
|
||||||
|
# - actually separate content properly
|
||||||
|
# - differentiate between [AfD] and AfD in by
|
||||||
|
if(str_detect(comment, "Beifall")) {
|
||||||
|
c(base, type = "applause", fraktion = by, kommentator = NA_character_, content = comment)
|
||||||
|
} else {
|
||||||
|
ps <- str_match(comment, "(.*) \\[(.*?)\\]: (.*)")[1,]
|
||||||
|
c(base, type = "comment", fraktion = ps[3], kommentator = ps[2], content = ps[4])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# creates a tibble of reden and a tibble of talks from a list of xml nodes representing reden
|
# creates a tibble of reden and a tibble of talks from a list of xml nodes representing reden
|
||||||
@@ -110,10 +164,17 @@ parse_redenliste <- function(redenliste_xml) {
|
|||||||
d <- sapply(redenliste_xml, parse_rede)
|
d <- sapply(redenliste_xml, parse_rede)
|
||||||
reden <- simplify2array(d["rede", ])
|
reden <- simplify2array(d["rede", ])
|
||||||
parts <- simplify2array %$% unlist(d["parts", ], recursive=FALSE)
|
parts <- simplify2array %$% unlist(d["parts", ], recursive=FALSE)
|
||||||
|
comments <- simplify2array %$% unlist(d["comments", ], recursive=FALSE)
|
||||||
list(reden = tibble(id = reden["id",], redner = reden["redner",]),
|
list(reden = tibble(id = reden["id",], redner = reden["redner",]),
|
||||||
talks = tibble(rede_id = parts["rede_id", ],
|
talks = tibble(rede_id = parts["rede_id", ],
|
||||||
redner = parts["redner", ],
|
redner = parts["redner", ],
|
||||||
content = parts["content", ]))
|
content = parts["content", ]),
|
||||||
|
comments = tibble(rede_id = comments["rede_id",],
|
||||||
|
on_redner = comments["on_redner",],
|
||||||
|
type = comments["type",],
|
||||||
|
fraktion = comments["fraktion",],
|
||||||
|
kommentator = comments["kommentator",],
|
||||||
|
content = comments["content", ]))
|
||||||
}
|
}
|
||||||
|
|
||||||
# create a tibble of redner from a list of xml nodes representing redner
|
# create a tibble of redner from a list of xml nodes representing redner
|
||||||
@@ -132,7 +193,7 @@ parse_rednerliste <- function(rednerliste_xml) {
|
|||||||
# EXAMPLE USE
|
# EXAMPLE USE
|
||||||
|
|
||||||
# make sure data ist downloaded via fetch.R
|
# make sure data ist downloaded via fetch.R
|
||||||
# res <- read_one("19126-data.xml")
|
# res <- read_one("records/19126-data.xml")
|
||||||
#
|
#
|
||||||
# res$redner
|
# res$redner
|
||||||
# res$reden
|
# res$reden
|
||||||
|
|||||||
+48
-5
@@ -23,25 +23,68 @@ collect_unique <- function(xs) xs %>% clear_na() %>% unique() %>% str_c(collapse
|
|||||||
|
|
||||||
# expects a tibble of redner and repairs
|
# expects a tibble of redner and repairs
|
||||||
repair_redner <- function(redner) {
|
repair_redner <- function(redner) {
|
||||||
redner %>% mutate(fraktion = Vectorize(repair_fraktion)(fraktion)) %>% # fix fraktion
|
if (nrow(redner) == 0) return(redner)
|
||||||
group_by(id, vorname, nachname) %>%
|
redner %>%
|
||||||
summarize(fraktion = collect_unique(fraktion),
|
filter(id != "10000") %>% # invalid id's
|
||||||
|
mutate(fraktion = Vectorize(repair_fraktion)(fraktion)) %>% # fix fraktion
|
||||||
|
group_by(id) %>%
|
||||||
|
summarize(vorname = head(vorname, 1),
|
||||||
|
nachname = head(nachname, 1),
|
||||||
|
fraktion = collect_unique(fraktion),
|
||||||
titel = longest_titel(titel),
|
titel = longest_titel(titel),
|
||||||
rolle_kurz = collect_unique(str_squish(rolle_kurz)),
|
rolle_kurz = collect_unique(str_squish(rolle_kurz)),
|
||||||
rolle_lang = collect_unique(str_squish(rolle_lang)))
|
rolle_lang = collect_unique(str_squish(rolle_lang))) %>%
|
||||||
|
ungroup() #%>%
|
||||||
|
# arrange(id) %>%
|
||||||
|
# distinct(vorname, nachname, fraktion, titel)
|
||||||
}
|
}
|
||||||
|
|
||||||
repair_reden <- function(reden) {
|
repair_reden <- function(reden) {
|
||||||
|
if (nrow(reden) == 0) return(reden)
|
||||||
# TODO: fill with content
|
# TODO: fill with content
|
||||||
reden
|
reden
|
||||||
}
|
}
|
||||||
|
|
||||||
repair_talks <- function(talks) {
|
repair_talks <- function(talks) {
|
||||||
|
if (nrow(talks) == 0) return(talks)
|
||||||
# TODO: fill with content
|
# TODO: fill with content
|
||||||
talks
|
talks
|
||||||
}
|
}
|
||||||
|
|
||||||
# repairs all tables
|
# tries to find the correct redner id given a name
|
||||||
|
# this is sufficient since every prename lastname combination in the bundestag is
|
||||||
|
# unique (luckily :D)
|
||||||
|
# returns a lookup table
|
||||||
|
lookup_redner <- function(comments, redner) {
|
||||||
|
tobereplaced <- "[-–—‑- ]"
|
||||||
|
redner %>%
|
||||||
|
unite(name, vorname, nachname, sep=".*") %>%
|
||||||
|
mutate(name = str_replace_all(name, tobereplaced, ".*")) ->
|
||||||
|
rs
|
||||||
|
find_match <- function(komm) {
|
||||||
|
if (komm == "") return (NA_character_)
|
||||||
|
# I tried with agrep (levensthein distance) but results are better that way
|
||||||
|
matches <- str_which(komm, rs$name)
|
||||||
|
if (length(matches) == 0) return(NA_character_)
|
||||||
|
rs[head(matches, 1), ]$id
|
||||||
|
}
|
||||||
|
comments %>%
|
||||||
|
distinct(kommentator) %>%
|
||||||
|
mutate(redner = Vectorize(find_match)(str_replace_all(kommentator, tobereplaced, "")))
|
||||||
|
}
|
||||||
|
|
||||||
|
repair_comments <- function(comments, redner) {
|
||||||
|
# try to find a redner id for each actual comment
|
||||||
|
comments %>%
|
||||||
|
filter(!is.na(kommentator)) %>%
|
||||||
|
lookup_redner(redner) %>%
|
||||||
|
left_join(comments, ., by="kommentator") %>%
|
||||||
|
select(-kommentator)
|
||||||
|
}
|
||||||
|
|
||||||
|
#' Repair parsed tables
|
||||||
|
#'
|
||||||
|
#' @export
|
||||||
repair <- function(parse_output) {
|
repair <- function(parse_output) {
|
||||||
list(redner = repair_redner(parse_output$redner),
|
list(redner = repair_redner(parse_output$redner),
|
||||||
reden = repair_reden(parse_output$reden),
|
reden = repair_reden(parse_output$reden),
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/fetch.R
|
||||||
|
\name{fetch_all}
|
||||||
|
\alias{fetch_all}
|
||||||
|
\title{Download available records}
|
||||||
|
\usage{
|
||||||
|
fetch_all(download_dir = "records/", create = FALSE)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{download_dir}{character}
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
This fetches all available records of the 19th legislative period of the german Bundestag.
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/parse.R
|
||||||
|
\name{read_all}
|
||||||
|
\alias{read_all}
|
||||||
|
\title{Parse xml records}
|
||||||
|
\usage{
|
||||||
|
read_all(path = "records/")
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{path}{character}
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Creates a list of tibbles containing relevant information from all records
|
||||||
|
stored in the input directory.
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/repair.R
|
||||||
|
\name{repair}
|
||||||
|
\alias{repair}
|
||||||
|
\title{Repair parsed tables}
|
||||||
|
\usage{
|
||||||
|
repair(parse_output)
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Repair parsed tables
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,47 @@
|
|||||||
|
\documentclass{article}
|
||||||
|
\usepackage[top=2.5cm, bottom=2.5cm]{geometry}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\section*{Was wurde bisher gemacht?}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Website scrapen
|
||||||
|
\item Protokolle fetchen
|
||||||
|
\item Protokolle parsen
|
||||||
|
\begin{itemize}
|
||||||
|
\item Redner ermitteln
|
||||||
|
\item Redebeiträge extrahieren
|
||||||
|
\item Ordnungskommentare filtern
|
||||||
|
\item Kommentare extrahieren
|
||||||
|
\item Fehler in Redner Tabelle bereinigen
|
||||||
|
\end{itemize}
|
||||||
|
\end{itemize}
|
||||||
|
\section*{Wie ist der Zustand aktuell?}
|
||||||
|
Protokolle sind heruntergeladen und geparsed in einer großen Tabelle.
|
||||||
|
Es gibt noch ein paar Issues, aber das meiste was wir haben funktioniert auch soweit.
|
||||||
|
\section*{Was muss noch gemacht werden?}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Parsen verbessern (muss nicht alles gemacht werden, aber wäre vielleicht schön)
|
||||||
|
\begin{itemize}
|
||||||
|
\item Kommentare in Kategorien einteilen, z.B. Kategorie Beifall mit Liste der applaudierenden Parteien
|
||||||
|
\item Metadaten vom Anfang extrahieren
|
||||||
|
\item Fehler weiter bereinigen (in talks, reden)
|
||||||
|
\end{itemize}
|
||||||
|
\item Error Handling beim Fetchen
|
||||||
|
\item Daten auf bestimmte Fragestellungen untersuchen
|
||||||
|
\begin{itemize}
|
||||||
|
\item Wer redet am häufigsten / längsten?
|
||||||
|
\item Was ist typisches Vokabular für einzelne Fraktionen?
|
||||||
|
\item Welche Fraktion gibt / bekommt den meisten Beifall / die meisten Zwischenrufe?
|
||||||
|
\item Ab wann wird Pandemie-Vokabular (Virus, Corona, Maske, $\dots$ ) genutzt?
|
||||||
|
\item Hat die Pandemie andere Themen wie Klimawandel verdrängt?
|
||||||
|
\end{itemize}
|
||||||
|
\item Ergebnisse visualisieren
|
||||||
|
\end{itemize}
|
||||||
|
\section*{Wie sieht der Plan für die nächsten Wochen aus?}
|
||||||
|
\begin{itemize}
|
||||||
|
\item[-24.07.] Klausurenphase
|
||||||
|
\item[25.07.-31.07.] Datenanalyse
|
||||||
|
\item[01.08.-07.08.] Visualisierung, Bugfixes und Improvements
|
||||||
|
\item[08.08.-11.08.] Präsentation machen
|
||||||
|
\end{itemize}
|
||||||
|
\end{document}
|
||||||
@@ -14,23 +14,36 @@ knitr::opts_chunk$set(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```{r setup}
|
||||||
|
library(hateimparlament)
|
||||||
|
library(dplyr)
|
||||||
|
library(ggplot2)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Preparation of data
|
||||||
|
|
||||||
|
First, you need to download all records of the current legislative period.
|
||||||
```r
|
```r
|
||||||
read_all() %>% repair() -> res
|
fetch_all("../records/") # path to directory where records should be stored
|
||||||
|
```
|
||||||
|
Second, those `.xml` files, need to be parsed into `R` `tibbles`. This is accomplished by:
|
||||||
|
```{r}
|
||||||
|
read_all("../records/") %>% repair() -> res
|
||||||
|
|
||||||
reden <- res$reden
|
reden <- res$reden
|
||||||
redner <- res$redner
|
redner <- res$redner
|
||||||
talks <- res$talks
|
talks <- res$talks
|
||||||
|
```
|
||||||
|
We also used `repair` to fix a bunch of formatting issues in the records and unpacked
|
||||||
|
the result into more descriptive variables.
|
||||||
|
|
||||||
# first tries
|
## Analysis
|
||||||
|
|
||||||
|
Now we can start analysing our parsed dataset, e.g. find out which party gives the most talks:
|
||||||
|
```{r}
|
||||||
left_join(reden, redner, by=c("redner" = "id")) %>%
|
left_join(reden, redner, by=c("redner" = "id")) %>%
|
||||||
group_by(fraktion) %>%
|
group_by(fraktion) %>%
|
||||||
summarize(n = n()) %>%
|
summarize(n = n()) %>%
|
||||||
ggplot(aes(x = fraktion, y = n)) +
|
ggplot(aes(x = fraktion, y = n)) +
|
||||||
geom_bar(stat = "identity")
|
geom_bar(stat = "identity")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
```{r setup}
|
|
||||||
library(hateimparlament)
|
|
||||||
```
|
|
||||||
|
|||||||
Reference in New Issue
Block a user