########################################################
### Open Data Kooperation: univie & Parlament ##########
### Showcase 3: Redezeit nach Geschlecht ###############
### code by Laurenz Ennser-Jedenastik & Isabel Kiani ###
### August 2024 ########################################
########################################################
# empty environment
rm(list = ls())
# Installieren und Laden der erforderlichen Pakete.
necessary.packages <- c("httr",
"jsonlite",
"RJSONIO",
"RCurl",
"httr2",
"purrr",
"tidyr",
"dplyr",
"tibble",
"rjson",
"stringi",
"stringr",
"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)
# ACHTUNG: Script ist so aufgebaut, dass es Daten zu Sitzungen und Daten zu Mandatar:innen aus verschiedenen Ordnern ausliest, die jeweils keine Unterordner haben dürfen!
# Arbeitsumgebung für das Script und Speicherung von Ergebnissen des API-Calls
setwd("Pfad/zu/Ihrem/Arbeitsverzeichnis")
###################
## XX bis XXVII ##
##################
# Definition Body des API-Calls für alle GP
gp_values <- c("XX", "XXI", "XXII", "XXIII", "XXIV", "XXV", "XXVI", "XXVII")
df1 <- list()
req <- request("https://www.parlament.gv.at/Filter/api/json/post?jsMode=EVAL&FBEZ=WFP_007&listeId=11070&showAll=true")
for (gp in gp_values) {
t1 <-
req %>%
req_body_raw(paste0('{"MODUS":["PLENAR"],"NRBRBV":["NR"], "GP":["',gp,'"]}')) %>%
req_perform()
response_data <- t1 %>% resp_body_json()
rows <- response_data$rows
df1 <- c(df1, rows)
}
# Loop zur Umwandlung von relativen Links aus den Ergebnislisten des API-Calls (Filter) zu absoluten Links, sowie get JSON-Content von Geschichtsseiten der Sitzungen
nrows1 <- length(df1)
vorne <- "https://www.parlament.gv.at"
hinten <- "?json=true"
all.urls <- rep(NA, nrows1)
all.GPs <- rep(NA, nrows1)
all.numbers <- rep(NA, nrows1)
all.VHG <- rep(NA, nrows1)
# Ladebalken erstellen
pb <- progress_bar$new(
format = " Downloading [:bar] :percent :elapsed",
total = nrows1, clear = FALSE, width = 60
)
for (i in 1:nrows1) {
all.urls[i] <- paste0(vorne, df1[[i]][[9]], hinten)
all.GPs[i] <- df1[[i]][[4]]
all.numbers[i] <- df1[[i]][[6]]
all.VHG[i] <- df1[[i]][[5]]
suppressMessages( # Ausgabe während dem Download unterdrücken
download.file(all.urls[i], destfile = paste0(all.VHG[i], "_", all.GPs[i], "_", all.numbers[i],".json"), quiet = TRUE)
)
pb$tick() # Fortschrittsbalken aktualisieren
}
#################
#Personenabfrage#
#################
# Definiere WorkingDirectory für Personendaten (darf aufgrund des Aufbaus des Scripts keine Unterordner haben und darf ausschließlich Personendaten enthalten)
setwd("Pfad/zu/Ihrem/Arbeitsverzeichnis")
# Definiere API-URI und Body des API-Calls (beim Filter/API "Parlamentarier:innen ab 1918 ist Abfrage über alle GP mit GP="ALLE" möglich)
req_sc1 <- request("https://www.parlament.gv.at/Filter/api/json/post?jsMode=EVAL&FBEZ=WFW_008&listeId=10008&pageNumber=-1")
t1 <- req_sc1 %>%
req_body_json(list(NRBR="NR", R_WF="FR", M="M", W="W", GP="ALLE"), auto_unbox = FALSE) %>% # Body API Call
req_perform()
df2 <- t1 %>% resp_body_json()
# Loop zur Umwandlung von relativen Links aus den Ergebnislisten des API-Calls (Filter) zu absoluten Links, sowie get JSON-Content von Biografieseiten der Abgeordneten
nrows1 <- length(df2$rows)
vorne <- "https://www.parlament.gv.at"
hinten <- "?json=true"
all.urls <- rep("", nrows1)
all.pads <- rep(NA, nrows1)
# Ladebalken erstellen
pb <- progress_bar$new(
format = " Downloading [:bar] :percent :elapsed",
total = nrows1, clear = FALSE, width = 60
)
for (i in 1:nrows1) {
all.urls[i] <- paste0(vorne, df2[["rows"]][[i]][[9]], hinten)
all.pads[i] <- df2[["rows"]][[i]][[1]]
suppressMessages( # Ausgabe während dem Download unterdrücken
download.file(all.urls[i], destfile = paste0("person_", all.pads[i], ".json"), quiet = TRUE)
)
pb$tick() # Fortschrittsbalken aktualisieren
}
#############################
# END OF DATA COLLECTION #
#############################
#-------------------------------------
#############################
# START OF DATA ANALYSIS #
#############################
# Environment leeren
rm(list = ls())
# Arbeitsverzeichnis setzen, in dem die Geschichtsseiten der Sitzungen gespeichert wurden
setwd("Pfad/zu/Ihrem/Arbeitsverzeichnis")
# Liste aller Files im Arbeitsverzeichnis erstellen
files.in.dir <- list.files(getwd())
nfiles <- length(files.in.dir)
# Loop zum Erzeugen eines Dataframes: Sitzung x Debatte x Rede
df.reden <- data.frame()
for (h in 1:nfiles) {
file <- fromJSON(file = files.in.dir[h]) # JSON-File einlesen
for (i in 1:length(file$content[[2]]$past_debates)) {
df.debatte <- data.frame(gp = rep(file$content[[1]]$gp_code, length(file$content[[2]]$past_debates[[i]]$speeches)))
df.debatte$titel <- rep(file$content[[2]]$past_debates[[i]]$text, length(file$content[[2]]$past_debates[[i]]$speeches)) # Bezeichnung der Rede
df.debatte$sitzungsnr <- rep(file$content[[1]]$inr, length(file$content[[2]]$past_debates[[i]]$speeches)) # Sitzungsnummer
df.debatte$deb.id <- rep(file$content[[2]]$past_debates[[i]]$id, length(file$content[[2]]$past_debates[[i]]$speeches)) # ID der Debatte
df.debatte$deb.typ <- rep(file$content[[2]]$past_debates[[i]]$type, length(file$content[[2]]$past_debates[[i]]$speeches)) # Typ der Debatte (z.B. Dringliche Anfrage, Kurzdebatte, Normaldebatte etc.)
if (nrow(df.debatte) > 0) {
for (j in 1:nrow(df.debatte)) {
df.debatte$redenr[j] <- file$content[[2]]$past_debates[[i]]$speeches[[j]][[1]] # Nummer der Rede in Debatte
df.debatte$parlid[j] <- file$content[[2]]$past_debates[[i]]$speeches[[j]][[4]] # ID von Redner:in
df.debatte$name[j] <- file$content[[2]]$past_debates[[i]]$speeches[[j]][[3]] # Name von Redner:in
df.debatte$rolle[j] <- file$content[[2]]$past_debates[[i]]$speeches[[j]][[6]] # Rolle von Redner:in
df.debatte$startzeit[j] <- file$content[[2]]$past_debates[[i]]$starttime # Startzeit
if (!is.null(file$content[[2]]$past_debates[[i]]$speeches[[j]][8][[1]])) {
m <- file$content[[2]]$past_debates[[i]]$speeches[[j]][8][[1]] # Wenn vorhanden, auf Daten der spezifischen Rede zugreifen
} else {
m <- "00:00" # Wenn keine Daten vorhanden, dann als "00:00" bezeichnen
}
df.debatte$redezeit[j] <- (as.numeric(strsplit(m, ":")[[1]])[1]*60 + as.numeric(strsplit(m, ":")[[1]])[2]) / 60 # Redezeit in Rückgriff auf im vorherigen Schritt definiertes "m" berechnen
}
df.reden <- rbind(df.reden, df.debatte) # Beide Dataframes in einen übergreifenden zusammenfügen
}
}
}
# Ergänzung um div. Variablen
df.reden$fraktion <- str_sub(df.reden$name, -2, -2) # Erzeuge Fraktionsvariable aus Namen
df.reden$gp_sitzung <- paste(as.numeric(as.roman(df.reden$gp)), df.reden$sitzungsnr, sep="_") # Erzeuge GP- + Sitzung-Variable
df.reden$datum <- as.Date(substr(df.reden$startzeit, 1, 10), "%Y-%m-%d") # Erzeuge Datumsvariable
# Daten zu Abgeordneten laden & verarbeiten. Arbeitsverzeichnis definieren (i.e. wo alle JSON Files der Abgeordneten abgelegt sind)
setwd("Pfad/zu/Ihrem/Arbeitsverzeichnis")
# Liste aller Files im Arbeitsverzeichnis erstellen
bio.files.in.dir <- list.files(getwd())
# Dataframe df01 erstellen (1 Zeile pro Person)
df01 <- as.data.frame(rep(NA, length(bio.files.in.dir)))
# Loop zum Zählen der Mandate pro Person (1 Mandat = 1 Periode in irgendeinem öffentlichen Amt zB. Abgeordnete:r, Minister:in ...)
names(df01)[1] <- "nofm"
for (i in 1:length(bio.files.in.dir)) {
file <- fromJSON(file = bio.files.in.dir[i]) # JSON-File einlesen
df01$nofm[i] <- length(file$content$biografie$mandatefunktionen$mandate) # Anzahl der Mandate anhand der Länge der Mandatsvariable einlesen
}
# Loop zum Erstellen von IDs & Namen
df01$id <- NA
df01$name <- NA
for (i in which(df01$nofm >= 1)) {
file <- fromJSON(file = bio.files.in.dir[i])
df01$id[i] <- file$content$personInfo$pad_intern # ID von Nationalratsabgeordnetem/r
df01$name[i] <- file$meta$title # Name von Nationalratsabgeordnetem/r
}
# Weitere Dataframes erstellen
dfs <- replicate(14, df01, simplify = FALSE)
list2env(setNames(dfs, paste0("df", sprintf("%02d", 2:15))), envir = .GlobalEnv)
# Liste von Dataframes erstellen
dflist <- list(df01, df02, df03, df04, df05, df06, df07, df08, df09, df10, df11, df12, df13, df14)
# Doppelter Loop: über Dataframes (j) & Zeilen in den Dataframes (i), zur Ermittlung von Mandaten, Zeitspanne, Startdatum, Enddatum, Klub, Klubzugehörigkeit
for (j in 1:length(dflist)) {
dflist[[j]]$mandate <- NA # leere Mandatsvariable erstellen
dflist[[j]]$timespan <- NA # leere Zeitspannenvariable erstellen
for (i in which(dflist[[j]]$nofm >= j)) {
file <- fromJSON(file = bio.files.in.dir[i])
dflist[[j]]$mandate[i] <- file$content$biografie$mandatefunktionen$mandate[[j]]$bez # Mandatsvariable befüllen
dflist[[j]]$timespan[i] <- file$content$biografie$mandatefunktionen$mandate[[j]]$zeitraum # Zeitspannenvariable befüllen
}
dflist[[j]]$start <- as.Date(substr(dflist[[j]]$timespan, 1, 10), "%d.%m.%Y") # Startdatum
dflist[[j]]$ende <- as.Date(substr(dflist[[j]]$timespan, 12, 21), "%d.%m.%Y") # Enddatum
dflist[[j]]$comma.pos <- regexpr(",", dflist[[j]]$mandate) # Ermittlung der Kommastelle zur Identifikation der Fraktionsbezeichnung
dflist[[j]]$klub <- substr(dflist[[j]]$mandate, dflist[[j]]$comma.pos+2, nchar(dflist[[j]]$mandate)) # Klubzugehörigkeit durch Einspielen der Fraktionsbezeichnung aus dem vorhergehenden Schritt
dflist[[j]] <- dflist[[j]][, -which(names(dflist[[j]])=="comma.pos")] # Hilfsvariable für Kommastellenermittlung aus finalem Dataframe wieder entfernen
}
# Dataframes aus dflist in einen übergreifenden Dataframe zusammenfassen
df.abg <- rbind(dflist[[1]], dflist[[2]], dflist[[3]], dflist[[4]], dflist[[5]], dflist[[6]], dflist[[7]],
dflist[[8]], dflist[[9]], dflist[[10]], dflist[[11]], dflist[[12]], dflist[[13]], dflist[[14]])
# Alle Zeilen in df.abg ohne Mandatinformation entfernen
df.abg <- df.abg[!is.na(df.abg$mandate), ]
# Alle Zeilen in df.abg entfernen, in denen das Mandat kein Nationalratsmandat ist
df.abg$is.nrabg <- ifelse(regexpr("Abgeordnet", df.abg$mandate)==-1, 0, 1) # Wenn der String "Abgeordner" nicht in der Mandatsvariable enthalten ist, dann mit 0 kodieren, wenn schon dann mit 1
df.abg <- df.abg[df.abg$is.nrabg==1, ] # Nur Personen, die im vorhergehenden Schritt mit 1 kodiert werden (= NR-Abg.) im Dataframe inkludieren
df.abg <- df.abg[, -which(names(df.abg)=="is.nrabg")] # Hilfsvariable für Ermittlung der Nationalratsabgeordneten aus finalem Datatframe wieder entfernen
# Alle Zeilen in df.abg mit Startdatum vor 19.12.1945 entfernen (= Start der V. Legislaturperiode)
df.abg <- df.abg[df.abg$start >= as.Date("19.12.1945", "%d.%m.%Y"), ]
# NA im Enddatum von derzeit aktiven Mitgliedern durch heutiges Datum ersetzen
df.abg$ende[is.na(df.abg$ende)] <- format(Sys.Date(), "%Y-%m-%d")
# Abgeordnete, die nur einen Tag im Amt sind, verwerfen
df.abg$oneday <- 1
df.abg$oneday[grep("-", df.abg$timespan)] <- 0 # Beobachtungen ohne "-" in der Zeitspannen-Variable finden (i.e. Abgeordnete für nur 1 Tag)
df.abg <- df.abg[df.abg$oneday==0, ] # nur Abgeordnete, die mehr als nur einen Tag im Amt waren, im Dataframe inkludieren
df.abg <- df.abg[, -which(names(df.abg)=="oneday")] # Hilfsvariable oneday aus finalem Datatframe wieder entfernen
# Manuelle Korrektur: Mandatsperiode für 2 FP-Abgeordnete (IDs: 1803, 2866) um 1 Tag verkürzen (sind analog wie im vorherigen Schritt zu behandeln):
df.abg$ende[df.abg$id==1803 & substr(df.abg$ende, 1, 4)=="1996"] <- df.abg$ende[df.abg$id==1803 & substr(df.abg$ende, 1, 4)=="1996"] - 1
df.abg$ende[df.abg$id==2866 & substr(df.abg$ende, 1, 4)=="1996"] <- df.abg$ende[df.abg$id==2866 & substr(df.abg$ende, 1, 4)=="1996"] - 1
# Zweifach gezählte Abgeordnete verwerfen (KP-Abg. die ebenso mit "LB" als Klubzugehörigkeit gelistet werden)
df.abg <- df.abg[df.abg$klub!="LB", ]
# df.abg nach ID und Mandatnummer sortieren
df.abg <- df.abg[order(df.abg$id, df.abg$start), ]
# Klub Variable aggregieren:
df.abg <- df.abg %>%
mutate(klub.agg = case_when(
klub == "SPÖ" ~ "SP",
klub == "ÖVP" ~ "VP",
klub == "GRÜNE" ~ "GR",
klub %in% c("BZÖ", "F-BZÖ") ~ "BZ",
klub %in% c("F", "FPÖ", "WdU") ~ "FP",
klub %in% c("VO", "LB", "KuL", "KPÖ") ~ "KP",
klub %in% c("NEOS-LIF", "NEOS") ~ "NEOS",
klub %in% c("JETZT", "PILZ") ~ "PILZ",
klub == "STRONACH" ~ "STRONACH",
klub == "L" ~ "LF",
klub == "ohne Klubzugehörigkeit" ~ "ohne",
TRUE ~ NA_character_ # Falls es Werte gibt, die nicht abgedeckt sind
))
# Geschlechtsvariable an df.reden matchen:
df.abg$geschlecht[substr(df.abg$mandate, 1, 12)=="Abgeordneter"] <- "m"
df.abg$geschlecht[substr(df.abg$mandate, 1, 12)=="Abgeordnete "] <- "w"
df.reden$geschlecht <- df.abg$geschlecht[match(df.reden$parlid, df.abg$id)] # Geschlechtsinformation an Reden-Dataframe matchen
# NB: Einige Personen im df.reden-Dataframe haben fehlende Werte bei df.reden$geschlecht, weil sie keine NR-Abg. sind (und daher in df.abg nicht als weiblich oder männlich klassifiziert werden)
# Diese Personen sind für die Analyse allerdings irrelevant (weil eben keine NR-Abg.)
# Erzeuge Vektor zu Tagungen (Tagung = Sitzungsperiode von September bis Juli, d.h. vom Ende einer bis zum Beginn der nächsten Sommerpause)
tagung <- paste(1996:2021, "/", substr(1997:2022, 3, 4), sep="")
tagung.start.ende <- as.Date(c("19.09.1996", "11.07.1997", "18.09.1997", "17.07.1998", "17.09.1998", "16.07.1999", "29.10.1999", "07.07.2000",
"05.09.2000", "06.07.2001", "26.09.2001", "11.07.2002", "19.09.2002", "10.07.2003", "02.09.2003", "09.07.2004",
"22.09.2004", "08.07.2005", "21.09.2005", "14.07.2006", "12.09.2006", "06.07.2007", "27.09.2007", "10.07.2008",
"12.09.2008", "10.07.2009", "01.09.2009", "09.07.2010", "22.09.2010", "08.07.2011", "13.09.2011", "06.07.2012",
"19.09.2012", "06.07.2013", "17.09.2013", "10.07.2014", "02.09.2014", "17.07.2015", "01.09.2015", "08.07.2016",
"13.09.2016", "13.07.2017", "20.09.2017", "05.07.2018", "07.09.2018", "03.07.2019", "19.09.2019", "09.07.2020",
"14.09.2020", "19.07.2021"), "%d.%m.%Y") # nicht enthalten: 2021/22 mit Daten 22.09.2021 bis 08.07.2022
start.tagung <- tagung.start.ende[seq(1, 49, 2)] # Startdaten der Tagungen in eigenes Objekt einlesen
ende.tagung <- tagung.start.ende[seq(2, 50, 2)] # Enddaten der Tagungen in eigenes Objekt einlesen
# Tagungsvariable im Dataframe erzeugen, die Tagung des Rededatums ausweist
df.reden$tagung <- NA
for (i in 1:length(tagung)) {
df.reden$tagung[start.tagung[i] <= df.reden$datum & ende.tagung[i] >= df.reden$datum] <- tagung[i]
}
# Subset des Dataframes wählen (z.B. nur Normaldebatten ==> df.reden$type=="ND")
df.reden.sub <- df.reden[df.reden$rolle!="er" & df.reden$rolle!="rb" & df.reden$rolle!="rs" & df.reden$rolle!="rf" & df.reden$rolle!="rv", ]
df.reden.sub <- df.reden.sub[!is.na(df.reden.sub$geschlecht), ]
# df.reden.sub <- df.reden.sub[df.reden.sub$deb.typ=="ND", ] # nur Normaldebatten
# Vektor mit Monatsersten erzeugen
years <- rep(1996:2022, 12) # Jahre ab 1996 wiedergeben
years <- years[order(years)]
months <- rep(c("01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"), length(1996:2022)) # Monate für die Länge der Jahre wiedergeben
firsts <- as.Date(paste("01.", months, ".", years, sep=""), "%d.%m.%Y") # Ersten Tag des jeweiligen Monats im Jahr wiedergeben
# Dataframe mit Monatsersten & Anzahl weiblicher & männlicher Abg. zu diesem Stichtag erzeugen
df.firsts <- data.frame(datum = firsts)
for (i in 1:length(firsts)) {
df.firsts$anzahl.m[i] <- table(df.abg$geschlecht[df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[1] # Anzahl an männlichen Abgeordneten insgesamt für Monatsersten des jeweiligen Jahres
df.firsts$anzahl.w[i] <- table(df.abg$geschlecht[df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[2] # Anzahl an weiblichen Abgeordneten insgesamt für Monatsersten des jeweiligen Jahres
df.firsts$anzahl.mSP[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="SP" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[1] # Anzahl an männlichen Abgeordneten einer konkreten Fraktion (in diesem Fall SPÖ) für Monatsersten des jeweiligen Jahres
df.firsts$anzahl.wSP[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="SP" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[2] # Anzahl an weiblichen Abgeordneten einer konkreten Fraktion (in diesem Fall SPÖ) für Monatsersten des jeweiligen Jahres
df.firsts$anzahl.mVP[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="VP" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[1]
df.firsts$anzahl.wVP[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="VP" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[2]
df.firsts$anzahl.mFP[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="FP" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[1]
df.firsts$anzahl.wFP[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="FP" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[2]
df.firsts$anzahl.mGR[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="GR" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[1]
df.firsts$anzahl.wGR[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="GR" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[2]
df.firsts$anzahl.mBZ[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="BZ" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[1]
df.firsts$anzahl.wBZ[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="BZ" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[2]
df.firsts$anzahl.mNE[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="NEOS" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[1]
df.firsts$anzahl.wNE[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="NEOS" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[2]
df.firsts$anzahl.mLF[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="LF" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[1]
df.firsts$anzahl.wLF[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="LF" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[2]
df.firsts$anzahl.mTS[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="STRONACH" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[1]
df.firsts$anzahl.wTS[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="STRONACH" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[2]
df.firsts$anzahl.mPI[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="PILZ" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[1]
df.firsts$anzahl.wPI[i] <- table(df.abg$geschlecht[df.abg$klub.agg=="PILZ" & df.abg$start <= firsts[i] & df.abg$ende >= firsts[i]])[2]
}
# Frauenanteile am Stichtag (gesamt und nach Fraktionen)
df.firsts <- df.firsts %>%
mutate(
anteil.w = anzahl.w / (anzahl.m + anzahl.w),
anteil.wSP = anzahl.wSP / (anzahl.mSP + anzahl.wSP),
anteil.wVP = anzahl.wVP / (anzahl.mVP + anzahl.wVP),
anteil.wFP = anzahl.wFP / (anzahl.mFP + anzahl.wFP),
anteil.wGR = anzahl.wGR / (anzahl.mGR + anzahl.wGR),
anteil.wBZ = anzahl.wBZ / (anzahl.mBZ + anzahl.wBZ),
anteil.wNE = anzahl.wNE / (anzahl.mNE + anzahl.wNE),
anteil.wLF = anzahl.wLF / (anzahl.mLF + anzahl.wLF),
anteil.wTS = anzahl.wTS / (anzahl.mTS + anzahl.wTS),
anteil.wPI = anzahl.wPI / (anzahl.mPI + anzahl.wPI)
)
# Tagungsvariable hinzu:
for (i in 1:length(tagung)) {
df.firsts$tagung[start.tagung[i] <= df.firsts$datum & ende.tagung[i] >= df.firsts$datum] <- tagung[i]
}
# Anteile der weiblichen/männlichen Abgeordneten pro Fraktion
anteile.w <- colMeans(df.firsts[which(names(df.firsts)=="anteil.w"):which(names(df.firsts)=="anteil.wPI")], na.rm=T)
anteile.m <- 1 - anteile.w
# Tagungs-Dataframe mit Redezeiten und Geschlechterverteilung über die Zeit
df.tagung <- data.frame(redezeit.gesamt = tapply(df.reden.sub$redezeit, df.reden.sub$tagung, sum)) / 60
df.tagung$redezeit.m <- tapply(df.reden.sub$redezeit[df.reden.sub$geschlecht=="m"], df.reden.sub$tagung[df.reden.sub$geschlecht=="m"], sum) / 60 # Redezeit männlicher Abgeordneter insgesamt
df.tagung$redezeit.w <- tapply(df.reden.sub$redezeit[df.reden.sub$geschlecht=="w"], df.reden.sub$tagung[df.reden.sub$geschlecht=="w"], sum) / 60 # Redezeit weiblicher Abgeordneter insgesamt
df.tagung$redezeit.SP <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="S"], df.reden.sub$tagung[df.reden.sub$fraktion=="S"], sum) / 60 # Insgesamte Redezeit für konkrete Fraktion (in diesem Fall SPÖ)
df.tagung$redezeit.SP.m <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="S" & df.reden.sub$geschlecht=="m"], df.reden.sub$tagung[df.reden.sub$fraktion=="S" & df.reden.sub$geschlecht=="m"], sum) / 60 # Redezeit männlicher Abgeordneter für konkrete Fraktion (in diesem Fall SPÖ)
df.tagung$redezeit.SP.w <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="S" & df.reden.sub$geschlecht=="w"], df.reden.sub$tagung[df.reden.sub$fraktion=="S" & df.reden.sub$geschlecht=="w"], sum) / 60 # Redezeit weiblicher Abgeordneter für konkrete Fraktion (in diesem Fall SPÖ)
df.tagung$redezeit.VP <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="V"], df.reden.sub$tagung[df.reden.sub$fraktion=="V"], sum) / 60
df.tagung$redezeit.VP.m <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="V" & df.reden.sub$geschlecht=="m"], df.reden.sub$tagung[df.reden.sub$fraktion=="V" & df.reden.sub$geschlecht=="m"], sum) / 60
df.tagung$redezeit.VP.w <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="V" & df.reden.sub$geschlecht=="w"], df.reden.sub$tagung[df.reden.sub$fraktion=="V" & df.reden.sub$geschlecht=="w"], sum) / 60
df.tagung$redezeit.FP <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="F"], df.reden.sub$tagung[df.reden.sub$fraktion=="F"], sum) / 60
df.tagung$redezeit.FP.m <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="F" & df.reden.sub$geschlecht=="m"], df.reden.sub$tagung[df.reden.sub$fraktion=="F" & df.reden.sub$geschlecht=="m"], sum) / 60
df.tagung$redezeit.FP.w <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="F" & df.reden.sub$geschlecht=="w"], df.reden.sub$tagung[df.reden.sub$fraktion=="F" & df.reden.sub$geschlecht=="w"], sum) / 60
df.tagung$redezeit.GR <- NA
df.tagung$redezeit.GR.m <- NA
df.tagung$redezeit.GR.w <- NA
df.tagung$redezeit.GR[-which(row.names(df.tagung)=="2018/19")] <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="G"], df.reden.sub$tagung[df.reden.sub$fraktion=="G"], sum) / 60
df.tagung$redezeit.GR.m[-which(row.names(df.tagung)=="2018/19")] <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="G" & df.reden.sub$geschlecht=="m"], df.reden.sub$tagung[df.reden.sub$fraktion=="G" & df.reden.sub$geschlecht=="m"], sum) / 60
df.tagung$redezeit.GR.w[-which(row.names(df.tagung)=="2018/19")] <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="G" & df.reden.sub$geschlecht=="w"], df.reden.sub$tagung[df.reden.sub$fraktion=="G" & df.reden.sub$geschlecht=="w"], sum) / 60
df.tagung$redezeit.BZ <- NA
df.tagung$redezeit.BZ.m <- NA
df.tagung$redezeit.BZ.w <- NA
df.tagung$redezeit.BZ[11:18] <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="B"], df.reden.sub$tagung[df.reden.sub$fraktion=="B"], sum) / 60
df.tagung$redezeit.BZ.m[11:18] <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="B" & df.reden.sub$geschlecht=="m"], df.reden.sub$tagung[df.reden.sub$fraktion=="B" & df.reden.sub$geschlecht=="m"], sum) / 60
df.tagung$redezeit.BZ.w[11:18] <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="B" & df.reden.sub$geschlecht=="w"], df.reden.sub$tagung[df.reden.sub$fraktion=="B" & df.reden.sub$geschlecht=="w"], sum) / 60
df.tagung$redezeit.NE[18:25] <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="N"], df.reden.sub$tagung[df.reden.sub$fraktion=="N"], sum) / 60
df.tagung$redezeit.NE.m[18:25] <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="N" & df.reden.sub$geschlecht=="m"], df.reden.sub$tagung[df.reden.sub$fraktion=="N" & df.reden.sub$geschlecht=="m"], sum) / 60
df.tagung$redezeit.NE.w[18:25] <- tapply(df.reden.sub$redezeit[df.reden.sub$fraktion=="N" & df.reden.sub$geschlecht=="w"], df.reden.sub$tagung[df.reden.sub$fraktion=="N" & df.reden.sub$geschlecht=="w"], sum) / 60
df.tagung$redezeit.gesamt.pc <- df.tagung$redezeit.w / df.tagung$redezeit.gesamt # Anteil Redezeit weiblicher Abgeordneter an Redezeit insgesamt
df.tagung$redezeit.SP.pc <- df.tagung$redezeit.SP.w / df.tagung$redezeit.SP # Anteil weiblicher Abgeordneter an Redezeit ihrer Fraktion (SPÖ)
df.tagung$redezeit.VP.pc <- df.tagung$redezeit.VP.w / df.tagung$redezeit.VP # Anteil weiblicher Abgeordneter an Redezeit ihrer Fraktion (ÖVP)
df.tagung$redezeit.FP.pc <- df.tagung$redezeit.FP.w / df.tagung$redezeit.FP # Anteil weiblicher Abgeordneter an Redezeit ihrer Fraktion (FPÖ)
df.tagung$redezeit.GR.pc <- df.tagung$redezeit.GR.w / df.tagung$redezeit.GR # Anteil weiblicher Abgeordneter an Redezeit ihrer Fraktion (Grüne)
df.tagung$redezeit.BZ.pc <- df.tagung$redezeit.BZ.w / df.tagung$redezeit.BZ # Anteil weiblicher Abgeordneter an Redezeit ihrer Fraktion (BZÖ)
df.tagung$redezeit.NE.pc <- df.tagung$redezeit.NE.w / df.tagung$redezeit.NE # Anteil weiblicher Abgeordneter an Redezeit ihrer Fraktion (Neos)
df.tagung$frauenanteilNR <- tapply(df.firsts$anteil.w, df.firsts$tagung, mean) # Durchschnittlicher Anteil weiblicher NR-Abg. insgesamt pro Tagung
df.tagung$frauenanteilSP <- tapply(df.firsts$anteil.wSP, df.firsts$tagung, mean) # Durchschnittlicher Anteil weiblicher NR-Abg. im SPÖ-Klub pro Tagung
df.tagung$frauenanteilVP <- tapply(df.firsts$anteil.wVP, df.firsts$tagung, mean) # Durchschnittlicher Anteil weiblicher NR-Abg. im ÖVP-Klub pro Tagung
df.tagung$frauenanteilFP <- tapply(df.firsts$anteil.wFP, df.firsts$tagung, mean) # Durchschnittlicher Anteil weiblicher NR-Abg. im FPÖ-Klub pro Tagung
df.tagung$frauenanteilGR <- tapply(df.firsts$anteil.wGR, df.firsts$tagung, mean) # Durchschnittlicher Anteil weiblicher NR-Abg. im Grünen Klub pro Tagung
df.tagung$frauenanteilBZ <- tapply(df.firsts$anteil.wBZ, df.firsts$tagung, mean) # Durchschnittlicher Anteil weiblicher NR-Abg. im BZÖ-Klub pro Tagung
df.tagung$frauenanteilNE <- tapply(df.firsts$anteil.wNE, df.firsts$tagung, mean) # Durchschnittlicher Anteil weiblicher NR-Abg. im Neos-Klub pro Tagung
df.tagung$frauenanteilTS <- tapply(df.firsts$anteil.wTS, df.firsts$tagung, mean) # Durchschnittlicher Anteil weiblicher NR-Abg. im Neos-Klub pro Tagung
###################
### DATENEXPORT ###
###################
# WorkinDirectory definieren, in der man die Auswertungen und beispielhaften Visualisierungen haben möchte
setwd("Pfad/zu/Ihrem/Arbeitsverzeichnis")
# Liste Pilz und Jetzt zusammenfassen
df.reden.sub <- df.reden.sub %>%
mutate(fraktion2 = recode(fraktion, "J" = "P"))
# Redezeit und Geschlechterverteilung pro Fraktion:
rede.frak.m <- tapply(df.reden.sub$redezeit[df.reden.sub$geschlecht=="m"], df.reden.sub$fraktion2[df.reden.sub$geschlecht=="m"], sum) / tapply(df.reden.sub$redezeit, df.reden.sub$fraktion2, sum) # Anteil Redezeit männlicher Abgeordneter aufgeschlüsselt nach Fraktionen
frak.names <- c("SP", "VP", "FP", "GR", "BZ", "Neos", "LF", "Team Stronach", "Pilz/Jetzt")
df.fraktion <- data.frame(abgeordnete.frauenanteil = anteile.w[-1], row.names = frak.names)
df.fraktion$abgeordnete.maenneranteil <- 1 - df.fraktion$abgeordnete.frauenanteil
df.fraktion$redezeit.frauenanteil <- 1 - rede.frak.m[c(8, 10, 3, 4, 2, 6, 5, 9, 7)]
df.fraktion$redezeit.maenneranteil <- 1 - df.fraktion$redezeit.frauenanteil
write.table(df.fraktion, file = "redezeit_geschlecht_fraktion_datenexport.csv", sep=";", col.names = NA)
# Frauenanteil an Abgeordneten und Redezeit pro Tagung (= im Zeitverlauf):
df.tagung.exp <- df.tagung[c(which(names(df.tagung)=="redezeit.gesamt.pc"),
which(names(df.tagung)=="frauenanteilNR"))]
names(df.tagung.exp) <- c("redezeit.frauenanteil", "abgeordnete.frauenanteil")
write.table(df.tagung.exp, file = "redezeit_geschlecht_tagung_datenexport.csv", sep=";", col.names = NA)
####################
### AUSWERTUNGEN ###
####################
m1 <- matrix(NA, 2, 2) # Matrix für barplot-Grafik
m1[, 1] <- c(anteile.m[1], anteile.w[1]) # Anteil männlicher, dann weiblicher Abgeordneter
m1[, 2] <- tapply(df.reden.sub$redezeit, df.reden.sub$geschlecht, sum) / sum(df.reden.sub$redezeit, na.rm=T) # Anteil der Redezeit aufgeschlüsselt nach Geschlecht
m2 <- matrix(NA, 2, 2 * (length(anteile.w)-1)) # Matrix für barplot-Grafik1
m2[1, seq(1, 18, 2)] <- anteile.m[-1]
m2[2, seq(1, 18, 2)] <- anteile.w[-1]
m2[1, seq(2, 18, 2)] <- rede.frak.m[c(8, 10, 3, 4, 2, 6, 5, 9, 7)]
m2[2, seq(2, 18, 2)] <- 1 - rede.frak.m[c(8, 10, 3, 4, 2, 6, 5, 9, 7)]
# GRAFIK 1: Redezeit vs. Präsenz alle
jpeg("geschlecht_redezeit_grafik1.jpg", height = 12, width = 12, res=600, units = "cm") # Als jpg-Datei speichern
b1 <- barplot(m1, names.arg = c("Anteile an\nNR-Abg.", "Anteile an\nder Redezeit"), las=1, axes=F, # Balken beschriften
col=c("indianred1", "darkseagreen3"), border="white", xlim=c(0, 3.5)) # Befüllungsfarbe der Balken wählen
axis(2, las=1, at=seq(0, 1, 0.2), labels=paste(seq(0, 100, 20), "%", sep="")) # Einheiten der y-Achse definieren und in Prozent darstellen
text(b1, m1[1, ]/2, paste(round(m1[1, ]*100, 0), "%", sep="")) # Prozentsätze aus vorher definierter Matrix im Balkendiagramm anzeigen
text(b1, m1[1, ] + m1[2, ]/2, paste(round(m1[2, ]*100, 0), "%", sep=""))
legend(b1[2] + 0.5, 0.5, c("Frauen", "Männer"), fill=c("darkseagreen3", "indianred1"), bty="n", border=NA) # Legende definieren
dev.off()
# GRAFIK 2: Redezeit vs. Präsenz pro Fraktion
jpeg("geschlecht_redezeit_grafik2.jpg", height = 12, width = 24, res=600, units = "cm")
par(mar=c(6, 4, 1, 5))
b2 <- barplot(m2, axes=F, col=rep(c("indianred1", "darkseagreen3"), 8), border="white", space=c(0.8, 0.1), # Visuelle Aspekte des Balkendiagramms definieren
names.arg=rep(c("NR-Abg.", "Redezeit"), 9), las=2, cex.names = 0.7, xlim=c(0, 29)) # Beschriftungs-Subkategorien der Balken festlegen
axis(2, las=1, at=seq(0, 1, 0.2), labels=paste(seq(0, 100, 20), "%", sep="")) # Einheiten der y-Achse definieren und in Prozent darstellen
axis(1, at=tapply(b2, rep(1:9, 2)[order(rep(1:9, 2))], mean), labels=c("SPÖ", "ÖVP", "FPÖ", "Grüne", "BZÖ", "Neos", "LF", "TS", "Pilz"), lwd=0, line=3) # Balken beschriften
text(b2, m2[1, ]/2, paste(round(m2[1, ]*100, 0), "%", sep=""), cex=0.7) # Prozentsätze aus vorher definierter Matrix im Balkendiagramm anzeigen
text(b2, m2[1, ] + m2[2, ]/2, paste(round(m2[2, ]*100, 0), "%", sep=""), cex=0.7) # Prozentsätze aus vorher definierter Matrix im Balkendiagramm anzeigen
legend(b2[18] + 0.5, 0.5, c("Frauen", "Männer"), fill=c("darkseagreen3", "indianred1"), bty="n", border=NA) # Legende definieren
dev.off()
# GRAFIK 3: Redezeit und Frauenanteil im Zeitverlauf
jpeg("geschlecht_redezeit_grafik3.jpg", height = 12, width = 20, res=600, units = "cm")
par(mar=c(6, 4, 1, 5))
plot(NA, NA, xlim=c(1, nrow(df.tagung)), ylim=c(0, 0.4), axes=F, xlab="Tagung (September bis Juli)", ylab="") # Format für Liniendiagramm fixieren
abline(h=seq(0, 0.4, 0.1), lty=3, col="grey") # Horizontale Hilfslinien
points(df.tagung$frauenanteilNR, type="l", col="blue", lwd=2) # Frauenanteil im Nationalrat zeichnen
points(df.tagung$redezeit.gesamt.pc, type="l", col="red", lwd=2) # Redezeitanteil von weibl. NR-Abg.
axis(2, las=1, at=seq(0, 0.4, 0.1), labels = paste0(seq(0, 40, 10), "%")) # y-Achse
axis(1, lwd=0, at=1:nrow(df.tagung), labels = substr(row.names(df.tagung), 3, 8), las=2, line=-1) # x-Achse
text(16, min(df.tagung$redezeit.gesamt.pc), "Redezeitanteil\n(weibl. NR-Abg.)", cex=0.8, col="red", pos=1) # Beschriftung
text(15, 0.30, "Frauenanteil\nim NR", cex=0.8, col="blue", pos=3) # Beschriftung
dev.off()