23 Commits
Author SHA1 Message Date
christian a2663b2e90 explain where vignettes are available 2021-08-11 23:40:32 +02:00
christian ab0fa33172 fix typo in readme 2021-08-11 23:36:40 +02:00
christian 83cdcc279b fix formatting in readme 2021-08-11 23:33:02 +02:00
christian 1e9c9ba651 fix documentation and improve readme 2021-08-11 23:29:37 +02:00
JosuaKugler efddf043e3 Merge branch 'master' into alternative-vignettes 2021-08-11 18:16:27 +02:00
JosuaKugler c374e8cd8e add meine beteiligung as input 2021-08-11 17:11:56 +02:00
JosuaKugler 412b349007 Merge branch 'master' of https://git.flavigny.de/christian/hateimparlament 2021-08-11 17:03:55 +02:00
JosuaKugler 534b34d02e improve abschlussbericht 2021-08-11 16:48:31 +02:00
Leon Burgard 1f68306fbd update abschlussbericht 2021-08-11 16:42:07 +02:00
JosuaKugler b7166d1578 add documentation for read_from_csv_or_fetch 2021-08-11 16:04:56 +02:00
christian 896ba1b3b0 update readme for new vignette building workflow 2021-08-11 09:18:17 +02:00
christian ecb5677703 add bare read_from_csv_or_fetch 2021-08-11 09:15:26 +02:00
christian 9d456bfa60 Merge pull request 'add masterdata from bundestag.de and use this for genderequality' (#16) from genderequality-alternative into master 2021-08-11 08:30:27 +02:00
christian 62fe9d497d Merge branch 'master' into genderequality-alternative 2021-08-10 23:28:25 +02:00
christian e31ccabf18 change title in genderequality 2021-08-10 22:46:41 +02:00
christian 622fd4db07 Merge branch 'master' into genderequality-alternative 2021-08-10 22:03:37 +02:00
christian 605e5e976a Merge branch 'master' into genderequality-alternative 2021-08-10 21:27:10 +02:00
christian 489254dadf Merge branch 'master' into genderequality-alternative 2021-08-10 20:19:02 +02:00
christian b09742815a Merge branch 'master' into genderequality-alternative 2021-08-10 17:54:04 +02:00
christian 7daf9e553c Merge branch 'master' into genderequality-alternative 2021-08-10 17:34:29 +02:00
christian d657ca3fbe Merge branch 'master' into genderequality-alternative 2021-08-10 17:26:49 +02:00
christian c53d842a1e add missing function to genderequality 2021-08-10 17:26:05 +02:00
christian f753920d34 add masterdata from bundestag.de and use this for genderequality 2021-08-10 17:04:43 +02:00
12 changed files with 109106 additions and 76 deletions
+1
View File
@@ -7,6 +7,7 @@ export(join_speaker)
export(party_colors) export(party_colors)
export(read_all) export(read_all)
export(read_from_csv) export(read_from_csv)
export(read_from_csv_or_fetch)
export(repair) export(repair)
export(word_usage_by_date) export(word_usage_by_date)
export(write_to_csv) export(write_to_csv)
+20
View File
@@ -271,3 +271,23 @@ read_from_csv <- function(path="inst/csv/") {
is_valid_res(res) is_valid_res(res)
res res
} }
#' Read records from csv or fetch
#'
#' @param path base directory where csv files are expected under path/csv
#' and possibly records fetched and stored under path/records
#'
#' @export
read_from_csv_or_fetch <- function(path="inst/") {
path <- make_directory_path(path)
res <- tryCatch(read_from_csv(str_c(path, "csv/")),
error = function(c) NULL)
if (!is.null(res)) return(res)
fetch_all(str_c(path, "records/"), create=T)
read_all(str_c(path, "records/")) %>%
repair() ->
res
write_to_csv(res, str_c(path, "csv/"), create=T)
res
}
+15 -7
View File
@@ -9,26 +9,34 @@ Using the `remotes` package, this is easily installed via:
```r ```r
remotes::install_url("https://git.flavigny.de/christian/hateimparlament/archive/master.zip") remotes::install_url("https://git.flavigny.de/christian/hateimparlament/archive/master.zip")
``` ```
Since the fetching and reading is very slow and depends on an internet connection, all vignettes If you want to build the vignettes, pass `build_vignettes = TRUE`. This takes a long time and
use `read_from_csv` to read already parsed tibbles from `.csv` files. fails sometimes, if bundestag.de times out, since
in the beginning the necessary records are neither fetched nor parsed.
That's why, if you want to build the vignettes yourself, you need to ## Install with vignettes
download the source code, e.g. on Linux
An alternative for building
the vignettes is to clone the repository and build the vignettes manually, e.g. on Linux
``` ```
git clone https://git.flavigny.de/christian/hateimparlament git clone https://git.flavigny.de/christian/hateimparlament
cd hateimparlament cd hateimparlament
``` ```
then start `R` and do Then open a `R` shell and do
```r
devtools::load_all() # load package
devtools::wd() # set working directory
```
Then fetch all records, read them and write the parsed tibbles to csv files.
```r ```r
devtools::load_all()
fetch_all(create = TRUE) fetch_all(create = TRUE)
read_all() %>% repair() -> res read_all() %>% repair() -> res
write_to_csv(res, create = TRUE) write_to_csv(res, create = TRUE)
``` ```
Then finally, do: Now you can install the package with vignettes by using
```r ```r
devtools::install(build_vignettes = TRUE) devtools::install(build_vignettes = TRUE)
``` ```
This makes all vignettes available via `browseVignettes()`.
# Features # Features
+108989
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+21 -9
View File
@@ -1,16 +1,28 @@
\documentclass{article} \documentclass{article}
\usepackage[ngerman]{babel}
\usepackage[top=2.5cm, bottom=2.5cm]{geometry} \usepackage[top=2.5cm, bottom=2.5cm]{geometry}
\title{Abschlussbericht}
\author{Leon Burgard, Josua Kugler, Christian Merten}
\begin{document} \begin{document}
\maketitle
\section*{Projektbeschreibung} \section*{Projektbeschreibung}
Wir haben zunächst die Plenarprotokolle der 19. Wahlperiode von der Website automatisiert herunterladen lassen. Unser Projekt \glqq Plenarprotokolle \grqq stellt mittels dem Paket \verb|hateimparlament| Funktionen zur Analyse der Plenarprotokolle der 19. Wahlperiode des deutschen Bundestages zur Verfügung. Diese Funktionen können in vier Bereiche unterteilt werden:
Als nächstes haben wir die Daten in ein für die Analyse sinnvolles Format gebracht, d.h. 5 Tibbles und Fehler ausgebessert. \begin{enumerate}
Daraufhin konnten wir mit der Analyse beginnen. \item Herunterladen der Protokolle
Insbesondere \item Konvertierung der XML-Dateien in Tibbles
\section*{Werkzeuge aus der Vorlesung} \item Reparieren von Fehlern
Wir haben, da es hauptsächlich um Datenanalyse ging, sehr viel mit tidyverse gearbeitet. \item Analyse
Ganz zu Beginn haben wir fürs fetchen der Protokolle rvest verwendet. \end{enumerate}
Für die Visualisierung haben wir ggplot2 sowie vignettes genutzt. Das Herunterladen der Protokolle gelingt über die Funktion
\verb|fetch_all()|, welche auf die Website des deutschen Bundestages zugreift und die XML-Dateien einzeln herunterlädt. Hierzu haben wir das Paket rvest verwendet, welches wir bereits in der Vorlesung kennengelernt haben.
Durch \verb|read_all()| werden diese heruntergeladenen XML-Dateien in eine benannte Liste mit fünf Tibbles (speaker, speeches, talks, comments und applause) geschrieben. Allerdings benötigt man diese Tibbles immer wieder und es ist ziemlich zeitaufwändig die XML-Dateien immer wieder neu in Tibbles einzulesen, deshalb haben wir zusätzlich eine Funkion \verb|write_to_csv()| geschrieben, die die fertigen Tibbles als CSV-Dateien speichert. Diese können dann sehr schnell durch \verb|read_from_csv()| eingelesen werden, wodurch viel Zeit gesparrt wird.
Da diese Protokolle kleine Fehler enthalten, müssen diese noch im nächsten Schritt bereinigt werden, was mit \verb|repair()| funktioniert. Hierbei wird das Paket tidyverse viel benutzt, welches insgesamt sehr viel in unserem Projekt beansprucht wird, da wir uns mit der Datenanalyse beschäftigen.
In \verb|analyse.R| stellen wir noch einige Hilfsfunktionen bereit, die es dem Nutzer vereinfachen die Daten auszuwerten. Beispielsweise steht schon eine Funktion zur Verfügung, die ein Balkendiagramm erstellt, bei dem jede Partei des Bundestages sperat ausgewertet wird. Hierbei wird das Paket \verb|ggplot2| verwendet.
Im letzten Schritt unseres Projekts haben wir Fragestellungen festgelegt, die wir mithilfe von unserem Paket beantworten wollten. Die Daten und unsere Ergebnisse visualisierten wir mithilfe von \verb|ggplot2| und \verb|tidyverse| in Vignetten.
\section*{Organisation des Teams} \section*{Organisation des Teams}
Während der ersten Projektphase wurden hauptsächlich die Funktionen zum Herunterladen der Dateien und Konvertieren und Reparieren der Tibbles geschrieben. Dies geschah größtenteils in Einzelarbeit, wobei hierbei die gegenseitige Kontrolle und Nachfragen die Funktionen optimiert haben. Zwischendurch wurde immer mal wieder zu einer HeiConf-Konferenz einberufen, um sich selbst den Zwischenstand klar zu machen und die Herausforderungen für die nächsten Wochen zu besprechen.
In der zweiten Hälfte des Projekts kümmerten wir uns dann um die Analyse der Daten und stellten unsere Ergebnisse in Vignetten da und erzeugten Dokumentationen für alle Funktionen, die für den Nutzer wichtig sind.
\newpage
\section*{Meine Beteiligung} \section*{Meine Beteiligung}
\input{meine_beteiligung.tex}
\end{document} \end{document}
+15
View File
@@ -0,0 +1,15 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/parse.R
\name{read_from_csv_or_fetch}
\alias{read_from_csv_or_fetch}
\title{Read records from csv or fetch}
\usage{
read_from_csv_or_fetch(path = "inst/")
}
\arguments{
\item{path}{base directory where csv files are expected under path/csv
and possibly records fetched and stored under path/records}
}
\description{
Read records from csv or fetch
}
+3 -2
View File
@@ -34,9 +34,10 @@ read_all("../inst/records/") %>% repair() -> res
``` ```
We also used `repair` to fix a bunch of formatting issues in the records. We also used `repair` to fix a bunch of formatting issues in the records.
For development purposes, we load the tables from csv files. For development purposes, we only fetch records if they are not already
stored as csv files:
```{r} ```{r}
res <- read_from_csv('../inst/csv/') res <- read_from_csv_or_fetch('../inst/')
``` ```
## Analysis ## Analysis
+32 -51
View File
@@ -1,8 +1,8 @@
--- ---
title: "genderequality" title: "Differences in gender"
output: rmarkdown::html_vignette output: rmarkdown::html_vignette
vignette: > vignette: >
%\VignetteIndexEntry{genderequality} %\VignetteIndexEntry{Differences in gender}
%\VignetteEngine{knitr::rmarkdown} %\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8} %\VignetteEncoding{UTF-8}
--- ---
@@ -20,7 +20,7 @@ library(dplyr)
library(ggplot2) library(ggplot2)
library(stringr) library(stringr)
library(tidyr) library(tidyr)
library(rvest) library(xml2)
``` ```
## Preparation of data ## Preparation of data
@@ -33,13 +33,15 @@ Second, those `.xml` files, need to be parsed into `R` `tibbles`. This is accomp
```r ```r
read_all("../records/") %>% repair() -> res read_all("../records/") %>% repair() -> res
``` ```
We also used `repair` to fix a bunch of formatting issues in the records and unpacked We also used `repair` to fix a bunch of formatting issues in the records.
the result into more descriptive variables.
For development purposes, we load the tables from csv files. For development purposes, we only fetch records if they are not already
stored as csv files:
```{r} ```{r}
res <- read_from_csv('../inst/csv/') res <- read_from_csv_or_fetch('../inst/')
``` ```
and unpack our tibbles and unpack our tibbles
```{r} ```{r}
comments <- res$comments comments <- res$comments
@@ -48,53 +50,33 @@ speaker <- res$speaker
talks <- res$talks talks <- res$talks
``` ```
Bevor we can do our analysis, we have to assign a gender to our politicans. Bevor we can do our analysis, we have to assign a gender to our politicans. We do this
by reading the gender from the master data of all members of parliament, which is
fetched from bundestag.de.
```{r} ```{r}
extract_href <- function(sel, html) { xml_get <- function(node, name) {
html %>% res <- xml_text(xml_find_all(node, name))
html_node(sel) %>% if (length(res) == 0) NA_character_
html_attr("href") else res
} }
first_content_p_text <- function(url) { x <- read_xml("../inst/masterdata.xml")
res <- NA mdbs <- xml_find_all(x, "MDB")
i <- 1
while(is.na(res)) { ids <- c()
read_html(url) %>% genders <- c()
html_node(str_glue("#mw-content-text > div.mw-parser-output > p:nth-child({i})")) %>% for (mdb in mdbs) {
html_text() -> res xml_get(mdb, "ID") -> mdb_id
i <- i + 1 xml_find_first(mdb, "BIOGRAFISCHE_ANGABEN") %>%
} xml_get("GESCHLECHT") ->
res mdb_gender
ids <- c(ids, mdb_id)
genders <- c(genders, if (mdb_gender == "männlich") "male" else "female")
} }
abgeordneten_list_html <- read_html( gender <- tibble(id = ids, gender = genders)
"https://de.wikipedia.org/wiki/Liste_der_Mitglieder_des_Deutschen_Bundestages_(19._Wahlperiode)") speaker_with_gender <- left_join(res$speaker, gender)
selectors <- str_glue("#mw-content-text > div.mw-parser-output > table:nth-child(20) > tbody > tr:nth-child({2:709}) > td:nth-child(2) > a")
link_part2 <- sapply(selectors, extract_href, abgeordneten_list_html)
link <- str_c("https://de.wikipedia.org", link_part2)
text <- sapply(link, first_content_p_text)
text %>%
str_extract(" ist ein.") %>%
str_replace(" ist eine", "female") %>%
str_replace(" ist ein ", "male") ->
gender
text %>%
str_extract("^([:upper:]?[:lower:]+[\\s\\-]?)*") %>%
str_trim() ->
names
gender <- tibble(speaker = names,
gender = gender)
speaker %>%
unite("speaker", vorname, nachname, sep = " ") %>%
right_join(gender, by = "speaker") ->
speaker_with_gender
``` ```
## Analyse ## Analyse
@@ -179,9 +161,8 @@ speeches %>%
summarize(n = n()) %>% summarize(n = n()) %>%
ungroup() %>% ungroup() %>%
arrange(-n) %>% arrange(-n) %>%
left_join(speaker, by=c("speaker" = "id")) %>% join_speaker(res) %>%
unite(name, vorname, nachname, sep = " ") %>% left_join(gender, by=c("speaker"="id")) %>%
inner_join(gender, by=c("name"= "speaker")) %>%
group_by(gender) %>% group_by(gender) %>%
summarise(absolute=sum(n)) %>% summarise(absolute=sum(n)) %>%
filter(gender %in% c("female", "male")) %>% filter(gender %in% c("female", "male")) %>%
+3 -2
View File
@@ -34,9 +34,10 @@ read_all("../inst/records/") %>% repair() -> res
``` ```
We also used `repair` to fix a bunch of formatting issues in the records. We also used `repair` to fix a bunch of formatting issues in the records.
For development purposes, we load the tables from csv files. For development purposes, we only fetch records if they are not already
stored as csv files:
```{r} ```{r}
res <- read_from_csv('../inst/csv/') res <- read_from_csv_or_fetch('../inst/')
``` ```
## Analysis ## Analysis
+3 -2
View File
@@ -38,9 +38,10 @@ talks <- res$talks
We also used `repair` to fix a bunch of formatting issues in the records and unpacked We also used `repair` to fix a bunch of formatting issues in the records and unpacked
the result into more descriptive variables. the result into more descriptive variables.
For development purposes, we load the tables from csv files. For development purposes, we only fetch records if they are not already
stored as csv files:
```{r} ```{r}
tables <- read_from_csv('../inst/csv/') tables <- read_from_csv_or_fetch('../inst/')
comments <- tables$comments comments <- tables$comments
speeches <- tables$speeches speeches <- tables$speeches
+3 -2
View File
@@ -34,9 +34,10 @@ read_all("../inst/records/") %>% repair() -> res
``` ```
We also used `repair` to fix a bunch of formatting issues in the records. We also used `repair` to fix a bunch of formatting issues in the records.
For development purposes, we load the tables from csv files. For development purposes, we only fetch records if they are not already
stored as csv files:
```{r} ```{r}
res <- read_from_csv('../inst/csv/') res <- read_from_csv_or_fetch('../inst/')
``` ```
## Analysis ## Analysis