########################################################
## Open Data Kooperation: univie & Parlament ##########
## Showcase 6: Anfragen: Ausschüse & Geschlecht #######
## code by Laurenz Ennser-Jedenastik & Daniel Bliem ###
### Kontakt: laurenz.ennser@univie.ac.at ###############
########################################################
# Leere die Arbeitsumgebung
rm(list = ls())
# Installieren und Laden der erforderlichen Pakete.
necessary.packages <- c("httr",
"jsonlite",
"RJSONIO",
"RCurl",
"httr2",
"purrr",
"tibble",
"rjson",
"tidyverse",
"gridExtra",
"officer",
"flextable",
"openxlsx",
"extrafont",
"lubridate",
"grid",
"stringr",
"scales",
"forcats",
"stringdist",
"progress")
new.packages <- necessary.packages[!(necessary.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)
#load packages
lapply(necessary.packages, library, character.only = TRUE)
# Herunterladen des 1. Datensatzes: Parlamentarische Anfragen
# Definieren der URL für die POST-Anfrage
req <- request("https://www.parlament.gv.at/Filter/api/filter/data/101?js=eval&showAll=true")
# Senden der POST-Anfrage mit definiertem Body
t1 <-
req %>%
req_body_raw('{
"NRBR": [
"NR"
],
"GP_CODE": [
"XXVII",
"XXVI",
"XXV",
"XXIV",
"XXIII",
"XXII",
"XXI",
"XX",
"XIX"
],
"VHG": [
"J_JPR_M"
],
"DOKTYP": [
"J"
]
}
') %>%
req_perform()
# Die Antwort in einen Datenframe laden
df1 <- t1 %>% resp_body_json()
# Eine Schleife erstellen, um herunterladbare URLs aus den relativen Links der JSON-Antwort zu erhalten
nrows1 <- length(df1$rows)
vorne <- "https://www.parlament.gv.at"
hinten <- "?json=true"
all.urls <- rep(NA, nrows1)
all.num <- rep(NA, nrows1)
all.type <- rep(NA, nrows1)
all.GP <- rep(NA,nrows1)
# Definieren des Arbeitsverzeichnisses, aus dem JSON Files gezogen werden
setwd("Pfad/zu/Ihrem/Arbeitsverzeichnis")
# Ladebalken erstellen
pb <- progress_bar$new(
format = " Downloading [:bar] :percent :elapsed",
total = nrows1, clear = FALSE, width = 60
)
# Iterieren durch die Reihen, um aus den Links herunterladbare URLs zu machen
for (i in 1:nrows1) {
all.urls[i] <- paste0(vorne, df1[["rows"]][[i]][[15]], hinten)
all.num[i] <- df1[["rows"]][[i]][[3]]
all.type[i] <- df1[["rows"]][[i]][[6]]
all.GP[i] <- df1[["rows"]][[i]][[1]]
suppressMessages( # Ausgabe während dem Download unterdrücken
download.file(all.urls[i], destfile = paste0(all.GP[i], "_", all.num[i], "_", all.type[i], ".json"), quiet = TRUE)
)
pb$tick() # Fortschrittsbalken aktualisieren
}
# Erstellen der leeren Variablen für den Dataframe
files.in.dir <- list.files(getwd())
files.in.dir <- files.in.dir[grep(".json", files.in.dir)] # Sicherstellen, dass nur JSON-Files in der Liste sind
df01 <- data.frame(name = rep(NA, length(files.in.dir))) # leeren Dataframe erzeugen
count.files <- length(files.in.dir)
# Funktion zur Ermittlung des Labels
get_label <- function(bubble) {
if (!is.null(bubble[["label"]])) {
return(bubble[["label"]])
} else {
return(NA)
}
}
# Iterieren durch alle Dateien im Verzeichnis und extrahieren der relevante Informationen für jedes Mitglied, die dann den erstellten leeren Variablen zugeordnet werden
for (i in 1:count.files) {
# Einlesen der JSON-Datei für jedes Mitglied
getfile <- fromJSON(file = files.in.dir[i])
# Extrahieren der Daten der JSON-Datei für jede Variable und speichern dieser im Dataframe
df01$name[i] <- getfile[["content"]][["names"]][[1]][["name"]]
df01$fraktion[i] <- getfile[["content"]][["names"]][[1]][["frak_code"]]
df01$person_url[i] <- getfile[["content"]][["names"]][[1]][["url"]]
topics <- vector("list", length = 5)
if (!is.null(getfile[["content"]][["topics"]]) && !is.null(getfile[["content"]][["topics"]][["data"]][["bubbles"]])) {
for (j in 1:length(getfile[["content"]][["topics"]][["data"]][["bubbles"]])) {
topics[[j]] <- get_label(getfile[["content"]][["topics"]][["data"]][["bubbles"]][[j]])
}
}
headwords <- vector("list", length = 5)
if (!is.null(getfile[["content"]][["headwords"]]) && !is.null(getfile[["content"]][["headwords"]][["data"]][["bubbles"]])) {
for (j in 1:length(getfile[["content"]][["headwords"]][["data"]][["bubbles"]])) {
headwords[[j]] <- get_label(getfile[["content"]][["headwords"]][["data"]][["bubbles"]][[j]])
}
}
df01$topic[i] <- if (!is.null(topics[[1]])) topics[[1]] else NA
df01$topic_2[i] <- if (length(topics) >= 2 && !is.null(topics[[2]])) topics[[2]] else NA
df01$topic_3[i] <- if (length(topics) >= 3 && !is.null(topics[[3]])) topics[[3]] else NA
df01$topic_4[i] <- if (length(topics) >= 4 && !is.null(topics[[4]])) topics[[4]] else NA
df01$topic_5[i] <- if (length(topics) >= 5 && !is.null(topics[[5]])) topics[[5]] else NA
df01$headword[i] <- if (!is.null(headwords[[1]])) headwords[[1]] else NA
df01$headword_2[i] <- if (length(headwords) >= 2 && !is.null(headwords[[2]])) headwords[[2]] else NA
df01$headword_3[i] <- if (length(headwords) >= 3 && !is.null(headwords[[3]])) headwords[[3]] else NA
df01$headword_4[i] <- if (length(headwords) >= 4 && !is.null(headwords[[4]])) headwords[[4]] else NA
df01$headword_5[i] <- if (length(headwords) >= 5 && !is.null(headwords[[5]])) headwords[[5]] else NA
if (!is.null(getfile) && !is.null(getfile[["content"]]) && !is.null(getfile[["content"]][["eurovoc"]]) &&
!is.null(getfile[["content"]][["eurovoc"]][["data"]]) && !is.null(getfile[["content"]][["eurovoc"]][["data"]][["bubbles"]][[1]])) {
df01$EuroVoc[i] <- getfile[["content"]][["eurovoc"]][["data"]][["bubbles"]][[1]][["label"]]
} else {
df01$EuroVoc[i] <- NA
}
if(!is.null(getfile[["content"]][["stages"]][[1]][["date"]])){
df01$einlangen[i] <- getfile[["content"]][["stages"]][[1]][["date"]]
} else{
df01$einlangen[i] <- getfile[["content"]][["phase"]][[1]][["stages"]][[1]][["date"]]
}
df01$titel[i] <- getfile[["content"]][["title"]]
df01$citation[i] <- getfile[["content"]][["zitation"]]
df01$GP[i] <- getfile[["content"]][["gp_code"]]
eingebracht_an_index <- NULL
if (!is.null(getfile[["content"]][["names"]])) {
for (j in 1:length(getfile[["content"]][["names"]])){
if (!is.null(getfile[["content"]][["names"]][[j]][["funktext"]]) &&
getfile[["content"]][["names"]][[j]][["funktext"]] == "Eingebracht an") {
eingebracht_an_index <- j
break
}
}
}
if (!is.null(eingebracht_an_index)) {
if (!is.null(getfile[["content"]][["names"]][[eingebracht_an_index]][["frak_code"]])) {
df01$person_2[i] <- getfile[["content"]][["names"]][[eingebracht_an_index]][["name"]]
df01$person_url_2[i] <- getfile[["content"]][["names"]][[eingebracht_an_index]][["url"]]
df01$frak_2[i] <- getfile[["content"]][["names"]][[eingebracht_an_index]][["frak_code"]]
} else {
df01$person_2[i] <- getfile[["content"]][["names"]][[eingebracht_an_index]][["name"]]
df01$person_url_2[i] <- getfile[["content"]][["names"]][[eingebracht_an_index]][["url"]]
df01$frak_2[i] <- NA
}
} else {
df01$person_2[i] <- NA
df01$person_url_2[i] <- NA
df01$frak_2[i] <- NA
}
}
# Speichern des erstellten Dataframes
save(df01, file = "Ihr_Dateiname.RData")
# falls Laden der Daten notwendig ist: load("Pfad/zu/Ihrer/Datei.RData")
# Hinzufügen einer zusätzliche Jahresvariable, indem das Jahr aus dem "einlangen"-Datum extrahiert wird
df01$year <- format(as.Date(df01$einlangen, format = "%d.%m.%Y"), "%Y")
df01$year <- as.numeric(df01$year)
# Filtern des Untersuchungszeitraums: Bis zur Sommerpause 2023 (10.07.)
df01 <- df01 %>%
filter(as.Date(einlangen, format = "%d.%m.%Y") <= as.Date("2023-07-10"))
### Erstellen von 4 neuen Themen aus den Schlagwörtern, die das Thema "Inneres und Recht" aufteilen, da dieses zu umfangreich ist
# Weise den 4 neuen Kategorien die passenden Schlagwörter zu (aus allen Schlagwörtern, die im Thema "Inneres und Recht" vorkommen)
assign_IuR_category <- function(headwords) {
categories <- character(length(headwords))
for (i in seq_along(headwords)) {
if (headwords[i] %in% c("Bundesgesetzblatt", "Bundesländer", "Bundespräsident:in", "Bundesregierung III. Sonstiges", "Verwaltungsorganisation", "Verwaltungsreform", "Verwaltungsverfahren", "Volksanwaltschaft", "Vereinbarungen", "Öffentlicher Dienst")) {
categories[i] <- "Amtsführung und Verwaltung"
} else if (headwords[i] %in% c("Zivilrecht", "Völkerrecht", "Vereins- und Versammlungsrecht", "Rechtsanwälte und Notare", "Rechtsbereinigung", "Rechtspflege", "Personenstandsrecht", "Vermögenssicherung", "Verfassungs- und Verwaltungsgerichtsbarkeit", "Politische Parteien", "Bundesverfassung", "Strafrecht")) {
categories[i] <- "Justiz"
} else if (headwords[i] %in% c("Zivilschutz", "Sicherheitswesen", "Opferfürsorge und Opferschutz")) {
categories[i] <- "Sicherheitswesen"
} else if (headwords[i] %in% c("Ausländer:in", "Flüchtlinge", "Grenzen", "Menschenrechte", "Staatsbürger:in", "Volksgruppen", "Pässe und Ausweise")) {
categories[i] <- "Migration"
} else {
categories[i] <- NA
}
}
return(categories)
}
# Zuweisen der Kategorien zu den neuen Topic_IuR-Variablen
num_headword_cols <- 5
for (i in 1:num_headword_cols) {
headword_col <- ifelse(i == 1, "headword", paste("headword_", i, sep = ""))
new_topic_col <- paste("topic_IuR_", i, sep = "")
df01[new_topic_col] <- sapply(df01[headword_col], assign_IuR_category)
}
### Filtern der Anfragen auf nur solche Anfragen, welche an die Bundesregierung gerichtet wurden
# 1. Identifizieren durch Art des Dokuments: Anfragen, die nicht Dokumenttyp "J" haben
alle_doktyp_J <- all(substr(df01$citation, nchar(df01$citation), nchar(df01$citation)) == "J")
# Ergebnis
if (alle_doktyp_J) {
cat("Alle Doktyps sind J")
} else {
cat("Nicht alle Doktyps sind J")
}
# 2. Filtern der Anfragen, die an den Rechnungshof gerichtet sind (haben Wert NA als Rezipient:in)
df01 <- df01[!is.na(df01$person_2), ]
# Erneutes Speichern des Dataframes
save(df01, file = "Ihr_Dateiname.RData")
### Herunterladen des 2. Datensatzes: Ausschussmitgliedschaften
# Datensatz für Ausschussmitgliedschaften nach Person: Neue Variable, die nur Personen-ID zeigt, zum Herunterladen der entsprechenden JSON Files
df01 <- df01 %>%
mutate(person_id = str_extract(person_url, "\\d+"))
# Definieren des Arbeitsverzeichnisses, aus dem JSON Files gezogen werden
setwd("Pfad/zu/Ihrem/Arbeitsverzeichnis2")
# Liste von allen benötigten Personen-IDs (ohne XIX GP, da es für diese GP keine Ausschussdaten gibt)
pad_intern_list <- unique(df01$person_id[df01$GP != "XIX"])
# Herunterladen der JSON Files für jede Person
fetch_data <- function(pad_intern) {
base_url <- "https://www.parlament.gv.at/Filter/api/filter/data/250?js=eval&showAll=true&export=true"
post_body <- list(PAD_INTERN = list(pad_intern))
response <- POST(url = base_url, body = post_body, encode = "json")
if (status_code(response) == 200) {
# Speichere den Inhalt der Antwort (JSON-Daten) in einer Datei
content <- content(response, as = "text")
write(content, file = paste0(pad_intern, ".json"))
cat("JSON-Datei für PAD_INTERN", pad_intern, "heruntergeladen.\n")
} else {
cat("Fehler beim Herunterladen der Daten für PAD_INTERN", pad_intern, "\n")
}
}
# Iterieren dieser Funktion für jede PAD_INTERN-Nummer
for (pad_intern in pad_intern_list) {
fetch_data(pad_intern)
}
# Erstellen des leeren Dataframes
df02 <- data.frame(
person_pad = character(),
GP = character(),
position = character(),
ausschuss = character(),
NR = character(),
start_date = character(),
end_date = character(),
stringsAsFactors = FALSE # Strings als Zeichenfolgen, keine Faktoren
)
# Pfad zu den JSON Files festlegen
json_files_aus <- list.files(path = "Pfad/zu/Ihren/JSON/Dateien2", pattern = "\\.json$", full.names = TRUE)
# Daten mit Loop extrahieren und in Dataframe spielen
for (file in json_files_aus) {
# Lade JSON-Daten
json_data <- jsonlite::fromJSON(file)
if (!is.null(json_data$rows) && length(json_data$rows) > 0) {
rows_matrix <- json_data$rows
# Durchlaufe jede Zeile der Matrix
for (i in 1:nrow(rows_matrix)) {
# Extrahiere die spezifischen Werte aus der aktuellen Zeile der Matrix
row <- rows_matrix[i, ]
person_pad <- row[7]
GP <- row[1]
position <- row[3]
ausschuss <- gsub("\\s*\\([^)]+\\)", "", row[4])
NR <- row[5]
date_info <- row[4]
# Beim Enddatum müssen laufende Ausschüsse berücksichtigt werden
if (grepl("\\s+-\\s+", date_info)) {
start_date <- gsub(".*\\((.*?)\\s*-\\s*.*", "\\1", date_info)
end_date <- gsub(".*-\\s*(.*?)\\)", "\\1", date_info)
} else {
start_date <- gsub(".*\\((.*?)\\).*", "\\1", date_info)
end_date <- "10.07.2023" # Enddatum für den Fall, in dem end_date nicht angegeben ist
}
# Hinzufügen der extrahierten Werte als neue Zeile
new_row <- data.frame(person_pad, GP, position, ausschuss, NR, start_date, end_date, stringsAsFactors = FALSE)
df02 <- rbind(df02, new_row)
}
} else {
cat("Keine Daten in 'rows' für Datei:", file, "\n")
}
}
# Filtern der Ausschüsse: Nur klassische Ausschüsse (kein U-Ausschuss, Unterausschuss, besonderer Ausschuss, Ausschuss im Bundesrat, ...)
df02 <- df02 %>%
filter(NR == "NR") %>%
filter(!grepl("unterausschuss|ständiger|unterausschuß|untersuchungsausschuss|besonderer|enquete", ausschuss, ignore.case = TRUE))
# Filtern der Rollen: Nur Mitglieder (da diese Funktion bestehen bleibt auch wenn eine andere dazukommt)
df02 <- df02 %>%
filter(position == "Mitglied")
# Auf neue Rechtschreibung korrigieren
df02$ausschuss <- gsub("(A|a)usschuß", "\\1usschuss", df02$ausschuss)
# Ausschüsse zusammenfassen, die die gleichen Materien behandeln
df02$ausschuss[df02$ausschuss == "Ausschuss für Wissenschaft und Forschung"] <- "Wissenschaftsausschuss"
df02$ausschuss[df02$ausschuss %in% c("Industrieausschuss", "Wirtschaftsausschuss", "Ausschuss für Wirtschaft und Industrie")] <- "Ausschuss für Wirtschaft, Industrie und Energie"
df02$ausschuss[df02$ausschuss == "Ausschuss für Forschung, Innovation und Technologie"] <- "Ausschuss für Forschung, Innovation und Digitalisierung"
df02$ausschuss[df02$ausschuss == "Ausschuss für Sportangelegenheiten"] <- "Sportausschuss"
df02$ausschuss[df02$ausschuss == "Bautenausschuss"] <- "Ausschuss für Bauten und Wohnen"
df02$ausschuss[df02$ausschuss == "Familienausschuss"] <- "Ausschuss für Familie und Jugend"
# Einschränken auf Untersuchungszeitraum (bis 10.07.2023)
df02$start_date <- as.Date(df02$start_date, format = "%d.%m.%Y")
df02 <- df02 %>%
filter(start_date <= "2023-07-10")
# Speichern des Dataframes
save(df02, file = "Ihr_Dateiname.RData")
### Fusionieren der Ausschussdaten von df02 zu df01
# Initialisieren von leeren Spalten für jeden Ausschuss im df01
for (committee_name in unique(df02$ausschuss)) {
df01[[committee_name]] <- "Nein"
}
# Erhöhen der Anzahl maximal angezeigter Spalten auf 60
rstudioapi::writeRStudioPreference("data_viewer_max_columns", 60L)
# Umformen der anderen Datumvariablen für Einheitlichkeit
df01$einlangen <- as.Date(df01$einlangen, format = "%d.%m.%Y")
df02$end_date <- as.Date(df02$end_date, format = "%d.%m.%Y")
# Loop über jede Zeile in df01, um Ausschussmitgliedschaften zu jedem Zeitpunkt der Abgeordneten zu überprüfen
for (i in 1:nrow(df01)) {
person <- df01$person_id[i]
time <- df01$einlangen[i]
for (j in 1:nrow(df02)) {
if (person == df02$person_pad[j] && time >= df02$start_date[j] && time <= df02$end_date[j]) {
committee_name <- df02$ausschuss[j]
df01[i, committee_name] <- "Ja"
}
}
}
### Herunterladen des 3. Datensatzes: für Personen (Geschlechtsvariable)
# Definieren der URL für die POST-Anfrage
reqpers <- request("https://www.parlament.gv.at/Filter/api/filter/data/10400?js=eval&showAll=true&export=true")
# Senden der POST-Anfrage mit definiertem Body
t3 <-
reqpers %>%
req_body_raw('{
"PERSART": [
"NR"
]
}
') %>%
req_perform()
# Laden der Antwort in einen Datenframe
df3 <- t3 %>% resp_body_json()
# Benötigte Variablen extrahieren
name_list <- lapply(df3$rows, function(x) x[[10]])
pad_list <- lapply(df3$rows, function(x) x[[3]])
pad_url_list <- lapply(df3$rows, function(x) x[[5]])
gender_list <- lapply(df3$rows, function(x) x[[6]])
# Erstellen eines Datenrahmens aus den extrahierten Informationen
df03 <- data.frame(
Name = unlist(name_list),
Geschlecht = unlist(gender_list),
pad_id = unlist(pad_list),
pad_url = unlist(pad_url_list)
)
# Neue Variable "Geschlecht" im df01 Dataframe erstellen und mit NA initialisieren
df01$Geschlecht <- NA
# Überspielen der Geschlechtsvariable auf df01
for (i in 1:nrow(df03)) {
current_pad_url <- df03$pad_url[i]
# Überprüfen, ob pad_url in df03 im df01 als person_url vorhanden ist
match_row <- which(df01$person_url == current_pad_url)
# Wenn ein entsprechender Eintrag gefunden wurde
if (length(match_row) > 0) {
# Übertrage das Geschlecht von df03 nach df01
df01$Geschlecht[match_row] <- df03$Geschlecht[i]
}
}
# Überprüfen, ob Abgeordnete ausgelassen wurden
na_rows_sex <- df01 %>% filter(is.na(Geschlecht))
# Fehlende ausbessern
names_to_change_W <- "Mag. Karin Miklautsch"
names_to_change_M <- c("Dr. Nikolaus Michalek", "Dr. Magnus Brunner, LL.M.", "Dr. Martin Polaschek")
df01$Geschlecht[df01$name %in% names_to_change_W] <- "W"
df01$Geschlecht[df01$name %in% names_to_change_M] <- "M"
# Ausschüsse entfernen, die keine Gesetzesinitiativen behandeln und somit nicht berücksichtigt werden
df01 <- df01[,-c(37, 44, 48, 49, 52, 53, 56)]
# Speichern von df03 und dem aktualisierten df01
save(df03, file = "Ihr_Dateiname.RData")
save(df01, file = "Ihr_Dateiname.RData")
####################
### AUSWERTUNGEN ###
####################
### Erstellung eines benutzerdefinierten Themes für die Grafiken
# Laden der Schriftart Lato (stellen Sie zuerst sicher, dass die Schriftart auf dem PC installiert ist)
font_import(paths = "Pfad/zu/Ihrer/Schriftart")
loadfonts(device = "win")
# Erstellen des Themes
custom_theme <- function() {
theme_minimal() +
theme(
plot.background = element_rect(fill = "white", color = NA),
panel.grid.major = element_line(color = alpha("gray", 0.25)),
panel.grid.minor = element_line(color = "white"),
panel.border = element_blank(),
plot.title = element_text(color = "#132843", size = 18, face = "bold", family = "Lato", margin = margin(b = 5), hjust = 0),
plot.subtitle = element_text(color = "#132843", size = 14, family = "Lato", margin = margin(b = 20), hjust = 0),
axis.title.x = element_text(face = "bold", family = "Lato", size = 15, margin = margin(t = 15)),
axis.title.y = element_text(face = "bold", family = "Lato", size = 15, margin = margin(r = 15)),
axis.text = element_text(family = "Lato", size = 12),
legend.text = element_text(family = "Lato", face = "bold", size = 12),
plot.margin = margin(1.2, 0.7, 0.7, 0.7, "cm"),
plot.title.position = "plot",
plot.caption.position = "plot",
plot.caption = element_text(size = 11)
)
}
# Erneutes definieren des Arbeitsverzeichnisses
setwd("Pfad/zu/Ihrem/Arbeitsverzeichnis")
### Analyse 1: Wie ändert sich die Häufigkeit der Themen von Anfragen nach Geschlecht?
# Filtern der NA-Werte aus der "topic" Variable und einschränken der Daten auf Untersuchungszeitraum
df01_filtered <- df01[!is.na(df01$topic), ]
df01_filtered <- df01_filtered %>%
filter(GP %in% c("XXV", "XXVI", "XXVII"))
# Zusammenfassen aller Themenvariablen in einen Wert
all_topics_combined <- c(
df01_filtered$topic,
df01_filtered$topic_2,
df01_filtered$topic_3,
df01_filtered$topic_4,
df01_filtered$topic_5,
df01_filtered$topic_IuR_1,
df01_filtered$topic_IuR_2,
df01_filtered$topic_IuR_3,
df01_filtered$topic_IuR_4,
df01_filtered$topic_IuR_5
)
# Erstellen eines Dataframes mit den relevanten Variablen (Topic, Geschlecht, GP)
df01_topics_mw <- data.frame(Topic = all_topics_combined, Geschlecht = df01_filtered$Geschlecht, GP = df01_filtered$GP)
# Filtern der NA-Werte und dem aufgeteilten "Inneres und Recht" - Thema
df01_topics_mw <- na.omit(df01_topics_mw)
df01_topics_mw <- df01_topics_mw %>%
filter(Topic != "Inneres und Recht")
# Gruppieren nach Thema und Geschlecht und Berechnen des Anteils an Anfragen weiblicher Abgeordneter pro Thema
df01_topics_mw_grouped <- df01_topics_mw %>%
group_by(Topic, Geschlecht) %>%
summarise(Anzahl = n()) %>%
mutate(Prozent = Anzahl / sum(Anzahl) * 100) %>%
arrange(desc(Geschlecht))
# Berechnen des Gesamtanteils Anfragen weiblicher Abgeordneter in Prozent
total_female_prop <- sum(df01_topics_mw_grouped$Anzahl[df01_topics_mw_grouped$Geschlecht == "W"]) / sum(df01_topics_mw_grouped$Anzahl) * 100
# Filtern und Berechnen der Daten nur für weibliche Anfragen für die Sortierung der Themen in der Grafik
df01_female_prop <- df01_topics_mw_grouped %>%
filter(Geschlecht == "W") %>%
group_by(Topic) %>%
summarise(avg_female_prop = mean(Prozent, na.rm = TRUE)) %>%
arrange(desc(avg_female_prop))
# Themen nach dem Durchschnitt des Frauenanteils sortieren
sorted_topics_f <- df01_female_prop$Topic
df01_topics_mw_grouped$Topic <- factor(df01_topics_mw_grouped$Topic, levels = rev(sorted_topics_f))
# Säulendiagramm erstellen
grafik01 <- ggplot(df01_topics_mw_grouped, aes(x = Topic, y = Prozent, fill = Geschlecht)) +
geom_bar(stat = "identity") +
labs(title = "Themen schriftlicher Anfragen nach Geschlecht",
subtitle = "Okt. 2013 – Jul. 2023",
x = "",
y = "",
caption = "Quelle: parlament.gv.at") +
scale_fill_manual(values = c("M" = "#132843", "W" = "#b8a552"),
breaks = c("W", "M"),
labels = c("Anfragen weiblicher NR-Abgeordneter", "Anfragen männlicher NR-Abgeordneter")) +
geom_hline(yintercept = total_female_prop, linetype = "dashed", color = "#f3efe3") + # Horizontale Linie für Gesamtanteil weiblicher Abgeordneter
annotate("text", x = 1, y = total_female_prop + 1, label = paste("Gesamtanteil Anfragen weibl. Abg.: ", round(total_female_prop, 0), "%"), color = "#f3efe3") +
custom_theme() +
theme(
legend.title = element_blank(),
legend.position = "bottom",
legend.box.margin = margin(l = -60, t = -20),
axis.text.y = element_text(vjust = 0.5, hjust = 1)
) +
coord_flip() +
scale_y_continuous(labels = function(x) paste0(x, "%"))
# Speichern der Grafik
ggsave("SC06_Grafik01.jpg", grafik01, width = 10, height = 7.5, units = "in", dpi = 300)
### Analyse 2: Wie ist die Geschlechterverteilung in den Ausschüssen?
# Geschlechtsvariable in df02 basierend auf df01 hinzufügen
match_indices_id <- match(df02$person_pad, df01$person_id)
df02$Geschlecht <- df01$Geschlecht[match_indices_id]
# Filtere Daten für die drei Zeitpunkte nach den Regierungsbildungen (jeweils 2 Monate danach)
df02$start_date <- as.Date(df02$start_date, format = "%d.%m.%Y")
df02$end_date <- as.Date(df02$end_date, format = "%d.%m.%Y")
selected_dates <- as.Date(c('16.02.2014', '18.02.2018', '07.03.2020'), format = "%d.%m.%Y")
# Erstelle eine neue Variable, die angibt, zu welchem der 3 Zeitpunkte die Ausschussmitgliedschaft war
df02$selected_timepoint <- apply(df02, 1, function(row) {
selected_idx <- which(row['start_date'] <= selected_dates & selected_dates <= row['end_date'])
if (length(selected_idx) > 0) {
return(selected_idx[1])
} else {
return(NA)
}
})
# Filtere Zeilen mit NA-Werten in der selected_timepoint Variable
df02_dates <- df02[complete.cases(df02$selected_timepoint), ]
# Gruppierung der Daten nach Ausschüssen, Geschlecht und ausgewähltem Zeitpunkt, Berechnung der Anzahl der Mitglieder
df02_grouped <- df02_dates %>%
group_by(ausschuss, Geschlecht, selected_timepoint) %>%
summarise(count = n()) %>%
ungroup() %>%
spread(Geschlecht, count, fill = 0)
# Berechnung des Verhältnisses männlicher zu weiblicher Mitglieder für die Sortierung
df02_grouped <- df02_grouped %>%
mutate(total = M + W) %>%
mutate(percent_M = (M / total) * 100,
percent_W = (W / total) * 100) %>%
group_by(ausschuss, selected_timepoint) %>%
summarise(avg_percent_W = mean(percent_W, na.rm = ),
avg_percent_M = mean(percent_M, na.rm = TRUE))
# Berechnung der Mittelwerte der drei Zeitpunkte
df02_grouped <- df02_grouped %>%
group_by(ausschuss) %>%
summarise(avg_percent_W_overall = mean(avg_percent_W, na.rm = TRUE),
avg_percent_M_overall = mean(avg_percent_M, na.rm = TRUE)) %>%
arrange(desc(avg_percent_M_overall))
# Erstellung des Datenrahmens für das Säulendiagramm
df02_plot <- rbind(
transform(df02_grouped, Geschlecht = "Männer"),
transform(df02_grouped, Geschlecht = "Frauen")
)
# Ausschüsse entfernen, die keine Gesetzesinitiativen behandeln und somit nicht berücksichtigt werden
df02_plot <- df02_plot %>%
filter(!(ausschuss %in% c("Geschäftsordnungsausschuss", "Immunitätsausschuss", "Unvereinbarkeitsausschuss", "Hauptausschuss", "Rechnungshofausschuss", "Volksanwaltschaftsausschuss", "Ausschuss für Petitionen und Bürgerinitiativen")))
# Berechnung des Durchschnitts der Frauenanteile für die Anzeige
durchschnitt_frauen <- mean(df02_plot$avg_percent_W_overall)
# Grafik erstellen
grafik02 <- ggplot(df02_plot, aes(x = reorder(ausschuss, -avg_percent_M_overall), y = ifelse(Geschlecht == "Männer", avg_percent_M_overall, avg_percent_W_overall), fill = fct_rev(Geschlecht))) +
geom_bar(stat = "identity", position = "stack") +
scale_fill_manual(values = c("#132843","#b8a552"), name = "Geschlecht", labels = c("Männliche NR-Abgeordnete", "Weibliche NR-Abgeordnete")) +
geom_hline(yintercept = durchschnitt_frauen, linetype = "dashed", color = "#f3efe3") +
annotate("text", x = 1, y = durchschnitt_frauen + 1, label = paste("Durchschn. Anteil an weibl. Abg.:", round(durchschnitt_frauen, 0), "%"), color = "#f3efe3") +
labs(title = "Geschlechterverteilung in Ausschüssen",
subtitle = "Mittelwert Feb. 2014, Feb. 2018, Mär. 2020",
x = "",
y = "",
caption = "Quelle: parlament.gv.at") +
custom_theme() +
theme(
legend.title = element_blank(),
legend.position = "bottom",
legend.box.margin = margin(l = -20, t = -20),
axis.text.y = element_text(vjust = 0.5, hjust = 1)
) +
coord_flip() +
scale_y_continuous(labels = function(x) paste0(x, "%")) +
guides(fill = guide_legend(reverse = TRUE))
# Speichern der Grafik
ggsave("SC06_Grafik02.jpg", grafik02, width = 10, height = 7.5, units = "in", dpi = 300)
### Analyse 3: Themenhäufigkeit bestimmter Themen über alle Ausschüsse darstellen
# Auswählen der Themen
themen_g3 <- c("Sicherheitswesen", "Soziales")
# Erstellen eine leeren Liste, um die Daten für jedes Thema zu speichern
plot_data_list <- list()
# Iterieren durch die ausgewählten Themen
for (thema in themen_g3) {
# Filtern des DataFrames auf das aktuelle Thema und auf nur die Anfragen, bei denen der Anfragesteller im Ausschuss war
df01_plot3 <- df01_filtered %>%
pivot_longer(cols = grep("Ausschuss", names(.), ignore.case = TRUE), names_to = "Ausschuss", values_to = "Mitgliedschaft") %>%
filter((topic == thema | topic_2 == thema | topic_3 == thema | topic_4 == thema | topic_5 == thema |
topic_IuR_1 == thema | topic_IuR_2 == thema | topic_IuR_3 == thema | topic_IuR_4 == thema | topic_IuR_5 == thema) &
Mitgliedschaft == "Ja")
# Zählen der Anzahl der Anfragen pro Ausschuss
anzahl_anfragen <- df01_plot3 %>%
group_by(Ausschuss) %>%
summarise(Anzahl = n())
# Speichern die Daten in der Liste
plot_data_list[[thema]] <- anzahl_anfragen
}
# Die Daten der beiden Themen in einen gemeinsamen Dataframe geben
df01_combined <- bind_rows(plot_data_list, .id = "Thema")
# Erstellen des Balkendiagramms
grafik03 <- ggplot(df01_combined, aes(x = fct_rev(Ausschuss), y = Anzahl, fill = Thema)) +
geom_bar(stat = "identity", position = "dodge") +
labs(title = "Anzahl der Anfragen nach Ausschussmitgliedschaft\nfür die Themen Sicherheitswesen und Soziales",
subtitle = "Okt. 2013 – Jul. 2023",
x = "",
y = "",
caption = "Quelle: parlament.gv.at") +
custom_theme() +
coord_flip() +
scale_fill_manual(values = c("Sicherheitswesen" = "#3c5e62", "Soziales" = "#d9652e")) +
facet_grid(~Thema, scales = "free_x", space = "free_x", switch = "x",
labeller = labeller(Thema = c("Sicherheitswesen" = "Thema: Sicherheitswesen", "Soziales" = "Thema: Soziales"))) +
scale_y_continuous(breaks = seq(0, max(df01_combined$Anzahl), 500)) +
theme(
legend.title = element_blank(),
legend.position = "",
plot.title = element_text(lineheight = 1.2),
axis.text.y = element_text(vjust = 0.5, hjust = 1),
strip.text = element_text(size = 12),
strip.placement = "outside"
)
# Speichern der Grafik
ggsave("SC06_Grafik03.jpg", grafik03, width = 10, height = 7.5, units = "in", dpi = 300)
### Analyse 4/5: Gender Gap vs. Ausschuss Gap im Anfrageverhalten
# Auswählen der Themen und Zuordnen der dazugehörigen relevanten Ausschüsse
ausgewaehlte_themen <- c(
"Justiz", "Sicherheitswesen", "Gesundheit und Ernährung", "Soziales", "Wirtschaft", "Migration", "Klima, Umwelt und Energie",
"Verkehr und Infrastruktur", "Außenpolitik", "Bildung", "Arbeit", "Land- und Forstwirtschaft", "Familie und Generationen",
"Landesverteidigung", "Kultur", "Frauen und Gleichbehandlung", "Sport"
)
relevante_ausschuesse <- list(
"Justiz" = "Justizausschuss",
"Sicherheitswesen" = "Ausschuss für innere Angelegenheiten",
"Gesundheit und Ernährung" = "Gesundheitsausschuss",
"Soziales" = "Ausschuss für Arbeit und Soziales",
"Wirtschaft" = "Ausschuss für Wirtschaft, Industrie und Energie",
"Migration" = "Ausschuss für innere Angelegenheiten",
"Klima, Umwelt und Energie" = "Umweltausschuss",
"Verkehr und Infrastruktur" = "Verkehrsausschuss",
"Außenpolitik" = "Außenpolitischer Ausschuss",
"Bildung" = "Unterrichtsausschuss",
"Arbeit" = "Ausschuss für Arbeit und Soziales",
"Land- und Forstwirtschaft" = "Ausschuss für Land- und Forstwirtschaft",
"Familie und Generationen" = "Ausschuss für Familie und Jugend",
"Landesverteidigung" = "Landesverteidigungsausschuss",
"Kultur" = "Kulturausschuss",
"Frauen und Gleichbehandlung" = "Gleichbehandlungsausschuss",
"Sport" = "Sportausschuss"
)
# Funktion zur Erstellung der Balkengrafik für ausgewählte Themen
# 2 Listen von ausgewählten Themen erstellen (eine für "Musterthemen" und eine für "abweichende" Themen)
ausgewaehlte_themen_1 <- c(
"Justiz", "Land- und Forstwirtschaft", "Sicherheitswesen", "Bildung"
)
ausgewaehlte_themen_2 <- c(
"Soziales", "Familie und Generationen", "Landesverteidigung", "Frauen und Gleichbehandlung"
)
# Liste zum Speichern der Daten
plot5_data_list <- list()
# Neuer Dataframe, um den alten nicht zu überschreiben
df01_neu <- df01_filtered
# Loop zum Erstellen eines Datenframes mit den prozentuellen Themennennungen nach Geschlecht und Ausschuss in Anfragen für ausgewählte Themen
for (thema in ausgewaehlte_themen) {
df01_neu[thema] <- apply(df01_neu[, c("topic", "topic_2", "topic_3", "topic_4", "topic_5",
"topic_IuR_1", "topic_IuR_2", "topic_IuR_3", "topic_IuR_4", "topic_IuR_5")],
1, function(row) any(grepl(thema, row, ignore.case = TRUE)))
ausschuss_name <- relevante_ausschuesse[[thema]]
grouped_data <- df01_neu %>%
group_by(Geschlecht, Mitgliedschaft = get(ausschuss_name), Ausschuss = !!ausschuss_name) %>%
summarise(Anzahl = n(),
Anzahl_Thema = sum(get(thema), na.rm = TRUE),
Prozent = mean(get(thema), na.rm = TRUE) * 100)
plot5_data_list[[thema]] <- grouped_data
}
# Die Dataframes der verschiedenen Themen zu einem zusammenfügen
df01_combined5 <- bind_rows(plot5_data_list, .id = "Thema")
# Neue Variable, die Geschlecht und Ausschussmitgliedschaft kombiniert
df01_combined5 <- df01_combined5 %>%
mutate(Geschlecht_Mitgliedschaft = paste(Geschlecht, Mitgliedschaft, sep = "-"))
# Nach den davor ausgewählten Themen filtern
df01_plot4 <- df01_combined5 %>%
filter(Thema%in%ausgewaehlte_themen_1)
df01_plot5 <- df01_combined5 %>%
filter(Thema%in%ausgewaehlte_themen_2)
# Funktion, um "Thema:" vor die Facettentitel hinzuzufügen
custom_labeller <- function(variable, value) {
return(paste("Thema:", value))
}
# Erstellen der Übersichtsgrafik mit allen Themen
ggplot(df01_combined5, aes(x = Geschlecht, y = Prozent, fill = Mitgliedschaft)) +
geom_bar(stat = "identity", position = "dodge") +
facet_wrap(~Thema, scales = "free_x") +
labs(title = "Prozentsatz aller Anfragen zu Themen\nnach Geschlecht und Ausschussmitgliedschaft",
x = "",
y = "Prozentanteil an allen Anfragen dieser Gruppe",
caption = "Quelle: parlament.gv.at") +
custom_theme() +
scale_fill_manual(values = c("Ja" = "#132843", "Nein" = "#b8a552"),
labels = c("Im Ausschuss", "Nicht im Ausschuss")) +
scale_x_discrete(labels = c("M" = "Männlich", "W" = "Weiblich")) +
scale_y_continuous(labels = scales::percent_format(scale = 1, accuracy = 1)) +
theme(legend.position = "bottom",
legend.title = element_blank(),
legend.box.margin = margin(t = -20),
axis.text.x = element_text(size = 9),
axis.text.y = element_text(size = 10))
# Neue Variable zur grammatikalisch korrekten Beschriftung der Grafiken
df01_combined5 <- df01_combined5 %>%
mutate(Beschriftung = ifelse(str_detect(Ausschuss, "Ausschuss"),
str_replace(Ausschuss, "Ausschuss", "Ausschusses"),
ifelse(str_detect(Ausschuss, "ausschuss"),
str_replace(Ausschuss, "ausschuss", "ausschusses"),
Ausschuss)))
### Erstellen der Grafiken 4 und 5 mit den ausgewählten Themen
# Funktion zum Erstellen eines Plots für ein bestimmtes Thema
create_theme_plot <- function(df01_combined5, theme_name) {
theme_data <- subset(df01_combined5, Thema == theme_name)
max_percent <- 30
plot <- ggplot(theme_data, aes(x = fct_rev(Geschlecht_Mitgliedschaft), y = Prozent, fill = Geschlecht)) +
geom_bar(stat = "identity", position = "dodge") +
labs(title = paste("Thema:", theme_name),
x = "",
y = "Anteil des Themas an den Anfragen dieser Gruppe") +
custom_theme() +
scale_fill_manual(values = c("M" = "#132843", "W" = "#b8a552")) +
scale_x_discrete(labels = c(
"W-Nein" = "Andere weibliche NR-Abgeordnete",
"M-Nein" = "Andere männliche NR-Abgeordnete",
"W-Ja" = paste("Weibliche Mitglieder des\n", unique(theme_data$Beschriftung)),
"M-Ja" = paste("Männliche Mitglieder des\n", unique(theme_data$Beschriftung))
)) +
scale_y_continuous(labels = scales::percent_format(scale = 1, accuracy = 1), limits = c(0, max_percent)) +
theme(plot.margin = margin(1, 0.7, 0.7, 0, "cm"),
legend.position = "",
legend.title = element_blank(),
axis.text.x = element_text(size = 10),
axis.text.y = element_text(size = 10),
axis.title.x = element_text(size = 10, hjust = 1, margin = margin(t = 5)),
plot.title = element_text(size = 11, hjust = 0.5, margin = margin(t = 5, b = 5))) +
coord_flip()
return(plot)
}
# Erstellen der Einzelplots für jedes Thema
theme_plots_4 <- lapply(ausgewaehlte_themen_1, function(theme) {
create_theme_plot(df01_combined5, theme)
})
theme_plots_5 <- lapply(ausgewaehlte_themen_2, function(theme) {
create_theme_plot(df01_combined5, theme)
})
# Titel, Untertitel und Caption für die zusammengefassten Grafiken definieren
overall_title_4 <- textGrob("Prozentsatz aller Anfragen zu Themen\nnach Geschlecht und Ausschussmitgliedschaft: Ausschuss-Gap", x = 0.03, y = -0.15, hjust = 0, gp = gpar(fontsize = 18, fontface = "bold", col = "#132843"))
overall_title_5 <- textGrob("Prozentsatz aller Anfragen zu Themen\nnach Geschlecht und Ausschussmitgliedschaft: Gender-Ausschuss-Gap", x = 0.03, y = -0.15, hjust = 0, gp = gpar(fontsize = 18, fontface = "bold", col = "#132843"))
subtitle <- textGrob("Okt. 2013 – Jul. 2023", x = 0.03, y = 0.2, hjust = 0, gp = gpar(fontsize = 14, col = "#132843"))
subtitle_height <- unit(3.5, "lines")
caption <- textGrob("Quelle: parlament.gv.at", x = 0.97, hjust = 1, y = 1.5, gp = gpar(fontsize = 11))
# Grafiken zusammenführen
grob_plot_4 <- grid.arrange(grobs = theme_plots_4)
grob_plot_5 <- grid.arrange(grobs = theme_plots_5)
# Grafiken mit zuvor definiertem Titel, etc. zusammenführen
grafik04 <- grid.arrange(top = overall_title_4,
subtitle,
grob_plot_4,
bottom = caption,
heights = unit.c(subtitle_height, unit(1, "null")))
grafik05 <- grid.arrange(top = overall_title_5,
subtitle,
grob_plot_5,
bottom = caption,
heights = unit.c(subtitle_height, unit(1, "null")))
# Speichern der Grafiken
ggsave("SC06_Grafik04.jpg", grafik04, width = 10, height = 7.5, units = "in", dpi = 300)
ggsave("SC06_Grafik05.jpg", grafik05, width = 10, height = 7.5, units = "in", dpi = 300)