8 Übung 1 Lösung
9 Teil I: Datenmanipulation
- Lade das Übungsblatt und die Daten herunter und speichere sie in einem neuen (auffindbaren) Ordner
- Öffne R und erstelle ein R-projekt, dass sich in selben Ordner befindet. Erstelle zudem ein neues R-Script oder R-Markdown und speichere es ebenfalls in diesem Ordner ab
- Du arbeitest nun im Dateipfad in welchem dein R-Projekt abgespeichert ist. Mit der Funktion, welche dem entsprechenden Datentyp zugeordnet ist (bspw. read_csv oder read.table) kannst du den Datensatz für die Übung nun mit Angabe des Namens einfach einlesen.
- Wiederhole diese Schritte bei jedem neuen Übungsblatt
- Achte darauf, dass du immer zuerst das R-Script öffnest, wenn du beim nächsten Mal am Übungsblatt weiterarbeiten möchtest
Die Dateien f.txt und m.txt enthalten Informationen zur Bildschirmzeit (d.h. Anzahl Sekunden pro Tag am Mobiltelefon) und Nähe zu einer populistischen Partei für Frauen (f.txt) und Männer (m.txt). Lese diese mit untenstehendem Code in R ein und betrachte jeweils die ersten drei Beobachtungen. Beachte auch untenstehende Hinweise zum Einlesen von Daten in R.
9.1 Pakete zusammen laden
# install.packages(c("sjPlot", "texreg", "haven", "readr", "readxl", "fixest", "MASS",
# "glm.predict", "scales", "tidyverse"))# install.packages("pacman")# Laden aller Hauptpakete auf einmal
pacman::p_load("sjPlot", "texreg", "haven", "readr", "readxl", "fixest", "MASS",
"glm.predict", "scales", "tidyverse")(.packages()) # Befehl zur Ausgabe der geladenen packages#| message: true
# Package Kollektion tidyverse laden
library(tidyverse)
# Daten einlesen
df_female <- read.table("f.txt", sep = ";") # Trennzeichen spezifizieren, standard ist Leerzeichen
df_male <- read.table("m.txt", sep = ";")
# Betrachte erste 3 Beobachtungen
head(df_female, n = 3)
head(df_male, n = 3)9.2 Aufgabe 1.1
- Wähle für die ersten drei weiblichen Individuen nur die Spalten
ScreenTimeundClosenessPopulistPartyaus. Tipp: Nutze die Funktionenhead()undselect()und eine pipe (%>%)
neu <- df_female %>%
head(n = 3) %>%
select(ScreenTime, ClosenessPopulistParty)- Wähle für die ersten drei weiblichen Individuen alle Spalten ausser
IDaus. Benutze dazu wederScreenTimenochClosenessPopulistParty. Erhältst du denselben Dataframe wie bei Frage 1?
df_female %>%
head(n = 3) %>%
select(-ID)Ja, wir erhalten den gleichen Dataframe.
9.3 Aufgabe 1.2
Füge mithilfe der Funktion mutate() zum Datensatz mit den weiblichen Individuen eine neue Variable z_ScreenTime hinzu, welche den \(z\)-Score der Variable ScreenTime darstellt. Der z-score für einen Wert errechnet sich gemäss folgender Formel:
\[ z = \frac{x - \mu}{\sigma} \] wobei \(x\) der Wert ist, der standardisiert werden soll, \(\mu\) den Mittelwert der Variable und \(\sigma\) die Standardabweichung der Variable darstellt.
Berechne anschliessend den Mittelwert und die Standardabweichung der neuen Variable z_ScreenTime. Wenn du alles richtig gemacht hast, sollte die Standardabweichung in etwa 1 und der Mittelwert in etwa 0 betragen. Entferne z_ScreenTime danach wieder aus dem Dataframe.
# Variable hinzufügen
df_female <- df_female %>%
mutate(z_ScreenTime = (ScreenTime - mean(ScreenTime)) / sd(ScreenTime))
# Mittelwert und Standardabweichung berechnen
mean(df_female$z_ScreenTime)
sd(df_female$z_ScreenTime)
# Wissenschaftliche Notation -> dezimale Notation
format(5.077372e-16, scientific = FALSE)
# Variable wieder entfernen
df_female <- df_female %>%
select(-z_ScreenTime)Der Mittelwert ist mit ca. \(5.078\times10^{-16}\) nahe bei 0, während die Standardabweichung von z_ScreenTime einem Wert von 1 entspricht.
9.4 Aufgabe 1.3
- Was ist der Anteil weiblicher Individuen, für welche die Nähe zu einer populistischen Partei grösser als 7, jedoch kleiner als 9 ist? Verwende für die Lösung die
filter()-Funktion
df_female %>%
filter(ClosenessPopulistParty > 7 & ClosenessPopulistParty < 9) %>%
nrow() / nrow(df_female) * 100Der Anteil beträgt ca. 35.7 %.
- Was ist der Anteil weiblicher Individuen, für welche die Nähe zu einer populistischen Partei zwischen 7 und 9 liegt (die Grenzen wiederum nicht eingeschlossen) und deren Bildschirmzeit grösser oder gleich 10’000 Sekunden pro Tag ist?
df_female %>%
filter(
ClosenessPopulistParty > 7 & ClosenessPopulistParty < 9
& ScreenTime >= 10000
) %>%
nrow() / nrow(df_female) * 100Der Anteil beträgt ca. 4.5 %.
9.5 Aufgabe 1.4
Nehme an, dass du an Individuen mit extremen Werten für die Bildschirmzeit interessiert bist.
- Berechne die Schwellenwerte für das 10. und das 90. Perzentil der Bildschirmzeit bei männlichen Individuen. Nutze hierfür die Funktion
quantile. Interpretiere die erhaltenen Werte.
# 10% Perzentil
perz10 <- quantile(df_male$ScreenTime, probs = 0.1)
perz10
# 90% Perzentil
perz90 <- quantile(df_male$ScreenTime, probs = 0.9)
perz90Wir sehen, dass 10% der Männer in unseren Daten eine Bildschirmzeit von 3333 oder weniger haben. Das 90%-Perzentil liegt bei 12431, d.h. 90% der Männer haben eine Bildschirmzeit von höchstens 12431, während die obersten 10% mehr als 12431 aufweisen.
- Was ist der Anteil männlicher Individuen, deren Bildschirmzeit das 10. Perzentil unter- bzw. das 90. Perzentil überschreitet? Was würdest du theoretisch erwarten? Überprüfe deine Antwort mithilfe der Resultate aus 1.4a.
Der Anteil sollte etwas weniger als 20 % betragen. Dies können wir mit Hilfe von R leicht überprüfen.
df_male %>%
filter(ScreenTime < perz10 | ScreenTime > perz90) %>%
nrow()/nrow(df_male) *1009.6 Aufgabe 1.5
Datensätze weisen oft Ungereimtheiten wie wiederholte Beobachtungen auf. Mithilfe der Funktion distinct() kannst du diese entfernen. Wie viele Beobachtungen im Datensatz mit den männlichen Individuen verbleiben, wenn du alle duplizierten IDs (gespeichert in der Variable ID) entfernst?
nrow(df_male) # Ursprüngliche Anzahl Observationen
# Duplikate entfernen
df_male1 <- df_male %>%
distinct(ID) # Problem: Datensatz ist bereinigt, aber hier bleibt nur die ID-Spalte übrig
df_male <- df_male %>%
distinct(ID, .keep_all = TRUE) # Lösung: keep_all = T
nrow(df_male)
Wir sehen, dass im Vergleich zum ursprünglichen Dataframe, eine Beobachtung entfernt wurde.
nrow(df_female)
df_female <- df_female %>%
distinct(ID, .keep_all = T)
nrow(df_female)Im Datensatz mit den weiblichen Personen verbleiben hingegen alle Reihen, was darauf hindeutet, dass es keine duplizierten Fälle gab.
9.7 Aufgabe 1.6
Verwende die Funktionen head und arrange, um die drei männlichen Individuen mit den höchsten bzw. tiefsten Werten für die Nähe zu einer populistischen Partei zu finden.
# Höchste Werte
df_male %>%
arrange(desc(ClosenessPopulistParty)) %>%
head(n = 3)
# Tiefste Werte (ohne desc!)
df_male %>%
arrange(ClosenessPopulistParty) %>%
head(n = 3)10 Teil II: Erste Analysen
10.1 Aufgabe 2.1
Füge den beiden in Teil I importierten Datensätzen jeweils eine neue Variable Gender hinzu, welche das jeweilige Geschlecht der Individuen erfasst. Erstelle anschliessend einen neuen Datensatz, welcher sämtliche männlichen und weiblichen Individuen enthält. Nutze für diese Aufgabe eine der bind-Funktionen, welche im dplyr-Package enthalten sind.
Wir können bind_rows verwenden. Nach dem mergen, kannst du noch die Zeilennamen resetten (vgl. unten), damit diese besser aussehen. Funktional ist dies jedoch nicht zwingend notwendig.
# Neue Variable für das Geschlecht
# Mutate
df_female <- df_female %>%
mutate(Gender = "female")
df_male <- df_male %>%
mutate(Gender = "male")
# Base-r: $ kann verwendet werden, um auf Variablen zuzugreifen
df_female$Gender <- "female"
df_male$Gender <- "male"
# Datensätze zusammenkleben
df_joined <- df_female %>%
bind_rows(df_male)
# Zeilennamen resetten
rownames(df_joined) <- NULL10.2 Aufgabe 2.2
Kommen wir nun zur Aggregration von Daten. Berechne die durchschnittliche Nähe zu einer populistischen Partei jeweils für weibliche und für männliche Individuen. Stelle die beiden Mittelwerte anschliessend in einem Balkendiagramm mit ggplot dar. Verwende dazu den zusammengeführten Datensatz und die Funktionen group_by und summarize.
df_joined %>%
group_by(Gender) %>%
summarize(mu = mean(ClosenessPopulistParty)) %>%
ggplot(aes(y = Gender, x = mu)) +
geom_col(width = .2, fill = "#0028A5") +
theme_bw() +
labs(y = "Geschlecht", x = "Durchschnittliche Nähe zu pop. Partei")
df_joined2 <- df_joined |>
group_by(Gender) |>
summarise(mu = mean(ClosenessPopulistParty))10.3 Aufgabe 2.3
Unterscheidet sich die durchschnittliche Bildschirmzeit von Frauen statistisch signifikant von der von Männern? Verwende zur Beantwortung dieser Frage einen Zweistichproben-t-Test.
t.test(ScreenTime ~ Gender, data = df_joined)Mit Blick auf den p-Wert (welcher kleiner als 0.05 ausfällt) können wir dem Zweistichproben-t-Test entnehmen, dass die durchschnittliche Bildschirmzeit von Männern statistisch signifikant höher ist als jene von Frauen.
10.4 Aufgabe 2.4
Sind die Bildschirmzeit und die Nähe zu einer populistischen Partei korreliert? Falls ja, ist die Korrelation positiv oder negativ? Welche Richtung würdest du theoretisch erwarten? Verwende anschliessend Pearson’s \(r\) (Pearsons Korrelationskoeffizient), um deine Vermutung zu überprüfen.
cor.test(df_joined$ClosenessPopulistParty, df_joined$ScreenTime, method = "pearson")Wir sehen, dass die Nähe zu einer populistischen Partei und die Bildschirmzeit negativ korreliert sind. Diese Korrelation unterscheidet sich statistisch signifikant von 0. Die Richtung des Zusammenhangs widerspricht unseren intuitiv formulierten Erwartungen.
10.5 Aufgabe 2.5
Hängt die Korrelation zwischen der Bildschirmzeit und der Nähe zu einer populistischen Partei vom Geschlecht ab? Verwende zur Beantwortung dieser Frage wiederum Pearson’s \(r\) (Pearsons Korrelationskoeffizient)
cor.test(df_female$ClosenessPopulistParty, df_female$ScreenTime, method = "pearson")cor.test(df_male$ClosenessPopulistParty, df_male$ScreenTime, method = "pearson")Die Korrelation ist für beide Geschlechter negativ und unterscheidet sich statistisch signifikant von 0. Bei Frauen fällt die Korrelation stärker aus als bei Männern.
10.6 Aufgabe 2.6
Erstelle mithilfe der Funktionen ggplot() und geom_point() ein Streudiagramm, welches den Zusammenhang zwischen der Bildschirmzeit (x-Achse) und der Nähe zu einer populistischen Partei (y-Achse) darstellt. In der Grafik sollte nach Geschlecht unterschieden werden (z.B. mit Hilfe von unterschiedlichen Farben).
df_joined %>%
ggplot(aes(x = ScreenTime, y = ClosenessPopulistParty, color = Gender)) +
geom_point() +
scale_color_manual(values = c("male" = "blue4", "female" = "red4"), # Benutzerdefinierte Farben, siehe bspw. https://sape.inf.usi.ch/quick-reference/ggplot2/colour
labels = c("weiblich", "männlich")) +
theme_bw() +
labs(x = "Bildschirmzeit", y = "Nähe zu pop. Partei", color = "Geschlecht")Das Streudiagramm verdeutlicht die Wichtigkeit von deskriptiven Analysen und dem Arbeiten mit Grafiken. Grafiken zeigen auf einen Blick Muster und Zusammenhänge, welche in Korrelationskoeffizienten oder anderen Zusammenhangsmassen nicht ersichtlich sind. Es empfiehlt sich deshalb immer, sich zunächst einen grafischen Überblick über neue Daten zu verschaffen, bevor man mit statistischen Analysen loslegt. Und es ist wichtig, kritisch mit den eigenen Resultaten umzugehen, besonders dann, wenn diese theoretischen Erwartungen und der eigenen Intuition diametral widersprechen.