#######################################################
## Open Data Kooperation: univie & Parlament ##########
## Showcase 8: Mehrfachbesetzungen von Ausschüssen ####
## code by Laurenz Ennser-Jedenastik & Daniel Bliem ###
### Kontakt: laurenz.ennser@univie.ac.at ##############
#######################################################
# Leeren der Arbeitsumgebung
rm(list = ls())
# Laden der erforderlichen Pakete. Falls nicht installiert, mit 'install.packages("Name des Pakets") installieren
library(httr)
library(jsonlite)
library(RJSONIO)
library(RCurl)
library(httr2)
library(purrr)
library(tibble)
library(rjson)
library(tidyverse)
library(gridExtra)
library(stringr)
# Definieren des Arbeitsverzeichnisses
setwd("Pfad/Zu/Ihrem/Arbeitsverzeichnis")
### Herunterladen des ersten Datensatzes: aktuelle NR-Abgeordnete
# Anmerkung: Durch die Verwendung des Datensatzes für aktuelle NR-Abgeordnete aktualisieren sich die Daten automatisch mit erneutem Benutzen des Codes.
# Die Ergebnisse in den Grafiken werden somit andere sein als die im Showcase dargestellten. Für den Showcase wurde der Stichtag 01.06.2024 gewählt.
# Besonders nach der Nationalratswahl im Herbst 2024 könnte es zu größeren Änderungen der Ergebnisse kommen.
# Die Teile des Codes, die bei Wiederverwendung geändert werden müssen, sind mit weiteren Anmerkungen versehen
# Definieren der URL für die POST-Anfrage
req <- request("https://www.parlament.gv.at/Filter/api/json/post?jsMode=EVAL&FBEZ=WFW_002&listeId=undefined&showAll=true&export=true")
# Senden der POST-Anfrage mit definiertem Body - nur aktuelle GP
t1 <-
req %>%
req_body_raw('{
"STEP": [
"1000"
],
"NRBR": [
"NR"
],
"GP": [
"AKT"
],
"R_WF": [
"FR"
],
"R_PBW": [
"WK"
],
"M": [
"M"
],
"W": [
"W"
]
}
') %>%
req_perform()
# Laden der Antwort in einen Datenframe
df1 <- t1 %>% resp_body_json()
# Benötigte Variablen extrahieren
name_list <- lapply(df1$rows, function(x) x[[9]])
pad_list <- lapply(df1$rows, function(x) x[[8]])
party_list <- lapply(df1$rows, function(x) x[[10]])
# Erstellen eines Datenrahmens aus den extrahierten Informationen
df01 <- data.frame(
Name = unlist(name_list),
pad_id = unlist(pad_list),
fraktion = unlist(party_list)
)
# Umformen der pad_id Variable
df01$pad_id <- as.numeric(str_extract(df01$pad_id, "\\d+"))
# Speichern des Dataframes
save(df01, file = "Ihr_Dateiname.RData")
### Herunterladen des 2. Datensatzes: Ausschussmitgliedschaften
# Liste von allen benötigten Personen-IDs
pad_id_list <- unique(df01$pad_id)
# Festlegen des Speicherorts für die JSON Files
setwd("Pfad/Zu/Ihrem/Speicherort")
# 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) {
# Speichern des Inhalts der Antwort (JSON-Daten) in einer Datei
content <- content(response, as = "text")
write(content, file = paste0(pad_intern, ".json"))
}}
# Iterieren dieser Funktion für jede PAD_INTERN-Nummer
for (pad_intern in pad_id_list) {
fetch_data(pad_intern)
}
# Erstellen des leeren Dataframes
df02 <- data.frame(
pad_id = character(),
GP = character(),
position = character(),
ausschuss = character(),
NR = character(),
start_date = character(),
end_date = character(),
stringsAsFactors = FALSE
)
# Pfad zu den JSON Files festlegen
json_files <- list.files(path = "Pfad/Zu/Ihrem/Speicherort", pattern = "\\.json$", full.names = TRUE)
# Daten mit Loop extrahieren und in den Dataframe überspielen
for (file in json_files) {
# Laden der JSON-Daten
json_data <- jsonlite::fromJSON(file)
if (!is.null(json_data$rows) && length(json_data$rows) > 0) {
rows_matrix <- json_data$rows
# Durchlaufen jeder Zeile der Matrix
for (i in 1:nrow(rows_matrix)) {
# Extrahieren der spezifischen Werte aus der aktuellen Zeile der Matrix
row <- rows_matrix[i, ]
pad_id <- 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 <- "01.06.2024" # Enddatum für den Fall, in dem end_date nicht angegeben ist (Stichtag des Showcases) - Anm.: Bei Wiederverwendung des Codes auf das aktuelle Datum ändern
}
# Hinzufügen der extrahierten Werte als neue Zeile
new_row <- data.frame(pad_id, 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: 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 weitere (Obfrau, Schriftführer, ...) dazukommt)
df02 <- df02 %>%
filter(position == "Mitglied")
# Format der Datumvariablen ändern
df02$start_date <- as.Date(df02$start_date, format = "%d.%m.%Y")
df02$end_date <- as.Date(df02$end_date, format = "%d.%m.%Y")
# Nur aktuelle GP und laufende Mitgliedschaften berücksichtigen - Anm.: Bei Wiederverwendung des Codes auf die aktuelle GP und das aktuelle Datum ändern
df02 <- df02 %>%
filter(GP == "XXVII" & end_date == "2024-06-01")
# Speichern des Dataframes
save(df02, file = "Ihr_Dateiname.RData")
# Kombinieren der Datensätze
df03 <- merge(df02, df01, by = "pad_id")
# Erstellen eines benutzerdefinierten Themes für die Grafiken
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)
)
}
# Festlegen der Reihenfolge der Fraktionen für die Grafiken - Anm.: Bei Wiederverwendung des Codes auf die aktuell im Nationalrat vertretenen Fraktionen anpassen
fraktion_order <- c("ÖVP", "SPÖ", "FPÖ", "GRÜNE", "NEOS", "OK")
# Festlegen des Speicherorts für die Grafiken
setwd("Pfad/Zu/Ihrem/Speicherort")
### 1. Grafik: Anzahl an Ausschussmitgliedschaften pro Abgeordneter
# Zusammenfassen der Anzahl der AUsschussmitgliedschaften pro NR-Abg.
df03_sum <- df03 %>%
group_by(pad_id, fraktion) %>%
summarise(num_observations = n())
# Ergänzen des Dataframes um Philippa Beck, die in keinem Ausschuss Mitglied ist - Anm.: Bei Wiederverwendung des Codes nicht benutzen
beck <- data.frame(
pad_id = "44127",
num_observations = 0,
fraktion = "OK"
)
df03_sum <- rbind(df03_sum, beck)
# Zusammenfassen der Abgeordneten mit der gleichen Anzahl an Ausschussmitgliedschaften
df03_plot1 <- df03_sum %>%
group_by(num_observations) %>%
summarise(num_pad_id = n())
# Berechnen der Gesamtanzahl der Ausschussmandate
gesamt_anzahl_mandate <- sum(df03_plot1$num_observations * df03_plot1$num_pad_id)
# Erstellen der ersten Grafik
grafik01 <- ggplot(df03_plot1, aes(x = num_observations, y = num_pad_id, fill = "#132843")) +
geom_bar(stat = "identity") +
geom_text(aes(label = num_pad_id), vjust = -0.5, size = 4) +
labs(x = "Anzahl an Ausschussmitgliedschaften", y = "Anzahl NR-Abgeordneter",
title = "Nationalratsabgeordnete nach der Anzahl ihrer Ausschussmitgliedschaften\nam 1. Juni 2024",
subtitle = paste("Gesamtanzahl der Ausschussmitgliedschaften:", gesamt_anzahl_mandate),
caption = "Quelle: parlament.gv.at") +
scale_x_continuous(breaks = seq(min(df03_sum$num_observations), max(df03_sum$num_observations), by = 1)) +
scale_fill_identity() +
custom_theme()
# Speichern der Grafik
ggsave("SC08_Grafik01.jpg", grafik01, width = 10, height = 7.5, units = "in", dpi = 300)
### 2. Grafik: Verteilung der Ausschussmitgliedschaften innerhalb der Klubs
# Zusammenfassen der Abgeordneten nach Fraktion und Anzahl an Ausschussmitgliedschaften
df03_plot2 <- df03_sum %>%
group_by(fraktion, num_observations) %>%
summarise(count = n()) %>%
ungroup()
# Zusammenfassen der niedrigen und hohen Ausschusszahlen
df03_plot2$num_observations <- ifelse(df03_plot2$num_observations %in% 0:2,
paste0("1-2"),
ifelse(df03_plot2$num_observations %in% 6:8,
paste0("6-8"),
as.character(df03_plot2$num_observations)))
# Prozentuale Berechnung der Balken pro Fraktion
df03_plot2 <- df03_plot2 %>%
group_by(fraktion, num_observations) %>%
summarize(count = sum(count)) %>%
group_by(fraktion) %>%
mutate(percentage = count / sum(count) * 100) %>%
ungroup()
# Herausfiltern der Abgeordneten ohne Klubzugehörigkeit
df03_plot2 <- df03_plot2 %>%
filter(fraktion != "OK")
# Manuelle Anpassung der Prozente für spezifische Fälle (damit die Werte in der Grafik gerundet und zusammengezählt 100% ergeben)
df03_plot2$percentage <- ifelse(df03_plot2$fraktion_obs == "FPÖ4", df03_plot2$percentage + 0.5, df03_plot2$percentage)
df03_plot2$percentage <- ifelse(df03_plot2$fraktion_obs == "GRÜNE2", df03_plot2$percentage + 0.5, df03_plot2$percentage)
# Farbskalen für jede Partei definieren und zuweisen - Anm.: Bei Wiederverwendung des Codes an die aktuell im Nationalrat vertretenen Parteien anpassen
colors_OEVP <- c("#c6f0f6", "#9ddae2", "#62c3d0", "#34a1af", "#0b707e")
colors_SPOE <- c("#ff9e9e", "#ff6666", "#fe0000", "#bc0001", "#7b0100")
colors_FPÖ <- c("#8fb3ff", "#5a8efc", "#0053fb", "#0136a6", "#002164")
colors_Grüne <- c("#bfe7a1", "#96cc6c", "#6ab12f", "#4c8d17", "#35620d")
colors_NEOS <- c("#ff99c8", "#fa6eab", "#e3257b", "#b10b57", "#8a003e")
# Reihenfolge der Balkenabschnitte festlegen
df03_plot2$num_observations=rep(c("1-2", "3", "4", "5", "6-8"),5)
# Neue Variable Fraktion * 1 bis 5 - Anm.: Bei Wiederverwendung des Codes an die Anzahl der aktuell im Nationalrat vertretenen Parteien anpassen
df03_plot2$fraktion_obs <- paste0(df03_plot2$fraktion, 1:5)
# Farben für die Balken und Legende festlegen - Anm.: Bei Wiederverwendung des Codes an die aktuell im Nationalrat vertretenen Parteien anpassen
bar_colors <- c("SPÖ1" = colors_SPOE[1], "SPÖ2" = colors_SPOE[2], "SPÖ3" = colors_SPOE[3], "SPÖ4" = colors_SPOE[4], "SPÖ5" = colors_SPOE[5],
"ÖVP1" = colors_OEVP[1], "ÖVP2" = colors_OEVP[2], "ÖVP3" = colors_OEVP[3], "ÖVP4" = colors_OEVP[4], "ÖVP5" = colors_OEVP[5],
"FPÖ1" = colors_FPÖ[1], "FPÖ2" = colors_FPÖ[2], "FPÖ3" = colors_FPÖ[3], "FPÖ4" = colors_FPÖ[4], "FPÖ5" = colors_FPÖ[5],
"GRÜNE1" = colors_Grüne[1], "GRÜNE2" = colors_Grüne[2], "GRÜNE3" = colors_Grüne[3], "GRÜNE4" = colors_Grüne[4], "GRÜNE5" = colors_Grüne[5],
"NEOS1" = colors_NEOS[1], "NEOS2" = colors_NEOS[2], "NEOS3" = colors_NEOS[3], "NEOS4" = colors_NEOS[4], "NEOS5" = colors_NEOS[5])
legend_colors <- c("#dedede", "#c0c0c0", "#999999", "#727272", "#454545")
# Erstellen der Grafik
plot2 <- ggplot(df03_plot2, aes(x = factor(fraktion, levels = rev(fraktion_order)), y = percentage, fill = fraktion_obs, group = rev(num_observations))) +
geom_bar(stat = "identity", color = "black") +
geom_text(aes(label = ifelse(percentage > 3, paste0(round(percentage), "%"), "")),
position = position_stack(vjust = 0.5),
size = 4,
color = ifelse(df03_plot2$num_observations %in% c("5", "6-8") | df03_plot2$num_observations == "4" & df03_plot2$fraktion == "FPÖ", "white", "black")) +
labs(x = "", y = "",
title = "Verteilung der Anzahl an Ausschussmitgliedschaften\npro Abgeordneten nach Klub",
subtitle = "Stand: 01. Jun. 2024",
caption = "Quelle: parlament.gv.at",
fill = "Anzahl der Ausschussmitgliedschaften") +
coord_flip() +
scale_y_continuous(labels = scales::percent_format(scale = 1)) +
scale_fill_manual(values = bar_colors, breaks = c("SPÖ1", "SPÖ2", "SPÖ3", "SPÖ4", "SPÖ5"), labels = c("1-2", "3", "4", "5", "6-8")) +
custom_theme() +
theme(
legend.position = "bottom",
legend.title = element_text(face = "bold", size = 12))
# Legendenfarben hinzufügen
grafik02 <- plot2 + guides(fill = guide_legend(override.aes = list(fill = legend_colors)))
# Speichern der Grafik
ggsave("SC08_Grafik02.jpg", grafik02, width = 10, height = 7.5, units = "in", dpi = 300)
### 3. Grafik: Kombinationen von bestimmten Ausschussmitgliedschaften
# Filtern von Personen mit mehr als einem Ausschuss
df03_filtered <- df03 %>%
group_by(pad_id) %>%
filter(n_distinct(ausschuss) > 1)
# Zusammenfassen aller Ausschusskombinationen
df03_combinations <- df03_filtered %>%
group_by(pad_id) %>%
summarise(ausschuss_combinations = list(combn(unique(ausschuss), 2, simplify = FALSE))) %>%
unnest(ausschuss_combinations) %>%
mutate(ausschuss_combinations = map(ausschuss_combinations, ~ sort(.x))) %>%
mutate(ausschuss_combinations = map_chr(ausschuss_combinations, ~ paste(.x, collapse = " &\n")))
# Zählen der Anzahl jeder Kombination
df03_plot3 <- df03_combinations %>%
group_by(ausschuss_combinations) %>%
summarise(count = n()) %>%
arrange(desc(count))
# Filtern auf die Ausschusskombinationen, die häufiger als siebenmal vorkommen
top_combinations <- df03_plot3 %>%
filter(count >= 8)
# Erstellen der Grafik
grafik03 <- ggplot(top_combinations, aes(x = reorder(ausschuss_combinations, count), y = count)) +
geom_bar(stat = "identity", fill = "#132843") +
geom_text(aes(label = count), hjust = ifelse(top_combinations$count >= 10, 1.5, 2), size = 4, color = "white") +
labs(x = "", y = "Anzahl der Kombinationen",
title = "Die häufigsten Ausschusskombinationen unter Nationalratsabgeordneten",
subtitle = "Stand: 01. Jun. 2024",
caption = "Quelle: parlament.gv.at") +
custom_theme() +
coord_flip()
# Speichern der Grafik
ggsave("SC08_Grafik03.jpg", grafik03, width = 10, height = 7.5, units = "in", dpi = 300)