---
title: "Tutorial 8"
format: html
editor: visual
---

## Setup - Pakete laden

```{r}
library(pacman)
p_load(ggplot2, data.table, dplyr)
```

## Daten simulieren um Aufgaben zu bearbeiten

```{r}
# Seed setzen um die Ergebnisse reproduzieren zu können
set.seed(12345)

# Anzahl der Datenpunkte festlegen
n <- 1000 

# Simulieren der Variable `effort`
effort <- 5  + rnorm(n, mean = 0, sd = 2)
# Einheit der Variable ist irrelevant
# (z. B. durchschnittliche produktive Stunden am Tag)

# Simulaieren der Variable `education` (Confounder), als Funktion unserer Variable `effort`
education <- 2 * effort + rnorm(n, mean = 0, sd = 2)
# Einheit der Variable ist irrelevant
# (z. B. Jahre an Schulbildung)

# Simulieren der Variable `wage`, welche durch effort beeinflusst wird, und dementsprechend auch mit education korreliert sein sollte (obwohl beide keine direkte Kausalität haben)
wage <- 10  +  2 * effort + rnorm(n, mean = 0, sd = 5)
# Einheit der Variable ist irrelevant
# (z. B. Euro pro Stunde)

# Dataframe erstellen für unsere Daten
data <- data.frame(education, effort, wage)

# Summary unserer simulierten Daten ansehen
summary(data)

# Scatterplot ansehen, um die Korrelationen zu visualisieren
pairs(data, main = "Scatterplot Matrix of Simulated Data")
```

Wir haben unsere Daten erfolgreich simuliert und können sie betrachten. Wir haben drei Variablen: `effort`, `education` und `wage`, wpbei `effort` die anderen beiden Variable beeinflusst.

## Confounding

Definition (aus der Vorlesung):

*"Ein Confounder ist eine Variable, die sowohl mit der unabhängigen als auch der abhängigen Variable korreliert ist. Confounder können die Ergebnisse stark verzerren und sollten daher in der Analyse berücksichtigt werden."*

```{r}
# Lineares Modell, wo wir den Confounder (effort) nicht beachten:
model_no_confounder <- lm(wage ~ education, data = data)
summary(model_no_confounder)

# Lineares Modell, wo wir den Confounder (effort) miteinbeziehen:
model_with_confounder <- lm(wage ~ education + effort, data = data)
summary(model_with_confounder)
```

Zudem können wir unsere Daten auch in einer .csv-Datei abspeichern für weitere Verwendung.

```{r}
# Speichern der Daten für weitere Verwendung
write.csv(data, "../output/data.csv")
```

Wenn wir unsere Summaries betrachten können wir sehen, dass im ersten Modell der Variable `educaction` sehr hohe Signifikanz zugeschrieben wird, obwohl sie eigentlich nicht direkt mit `wage` zusammenhängt. Erst wenn wir den Confounder `effort` miteinbeziehen, sehen wir, dass `education` nicht mehr signifikant ist.
Jetzt simulieren wir noch einmal neue Daten, mit dem einem neuen Confouder. Es ist zu beachten, dass es sich hier um künstlich erzeugte Daten ohne reale Grundlage handelt, sodass wir über die tatsächliche Kausalität keine Aussage treffen können und wollen. Es geht lediglich darum, dass wir die Konzepte verstehen.

```{r}
# Seed setzen um die Ergebnisse reproduzieren zu können
set.seed(56789)

# Anzahl der Datenpunkte festlegen
n <- 1000 

# Simulieren der Variable `education_new`
education_new <- 5  + rnorm(n, mean = 0, sd = 2)

# Simulaieren der Variable `effort_new` (Confounder), als Funktion unserer Variable `effort`
effort_new <- 2 * education_new + rnorm(n, mean = 0, sd = 2)

# Simulieren der Variable `wage`, welche durch effort beeinflusst wird, und dementsprechend auch mit education korreliert sein sollte (obwohl beide keine direkte Kausalität haben)
wage_new <- 10  +  2 * education_new + rnorm(n, mean = 0, sd = 5)

# Dataframe erstellen für unsere Daten
data_new <- data.frame(education_new, effort_new, wage_new)

# Summary unserer simulierten Daten ansehen
summary(data_new)

# Scatterplot ansehen, um die Korrelationen zu visualisieren
pairs(data_new, main = "Scatterplot Matrix of Adjusted Data")

# Lineares Modell, wo wir den Confounder (education) nicht beachten:
model_no_confounder_new <- lm(wage_new ~ effort_new, data = data_new)
summary(model_no_confounder_new)

# Lineares Modell, wo wir den Confounder (education) miteinbeziehen:
model_with_confounder_new <- lm(wage_new ~ effort_new + education_new, data = data_new)
summary(model_with_confounder_new)
```

Wir sehen also, dass wir den Confounder auch anders aufbauen können. Wichtig ist, dass wir genau hinschauen, wie korrelierte Konstrukte zusammenhängen und wie wir sie in unseren Modellen berücksichtigen. Es gilt die Phrase: *"Correlation does not imply causation*. (zu Deutsch: *"Korrelation impliziert keine Kausalität"*).


## Kausale Effekte

```{r}
# Kausale Effekte an Hand von Beispieldaten anschauen
cities_df <- data.frame(
  city = c("Bielefeld", "Berlin", "Budapest", "Barcelona", "Bologna", "Bremen", "Bordeaux", "Brüssel"),
  unemployment_no_intervention = c(5.2, 6.3, 4.3, 8.1, 5.2, 4, 7.5, 3.4),
  unemployment_intervention = c(4.2, 5.3, 3.3, 7.1, 4.2, 3, 6.5, 2.4)
)

# Neue Spalte für den kausalen Effekt hinzufügen
cities_df$causal_effect <- cities_df$unemployment_intervention - cities_df$unemployment_no_intervention

# Mittelwert davon berechnen 
mean_causal_effect <- mean(cities_df$causal_effect)

# Test: Wert sollte exakt -1 sein
print(mean_causal_effect)
```

Wir sehen, dass der kausale Effekt, in unserem künstlichen Beispiel, exakt -1 beträgt. Das bedeutet, dass die Intervention in den Städten genau einen Prozentpunkt weniger Arbeitslosigkeit verursacht hat.

```{r}
# Seed setzen für Replizierbarkeit
set.seed(12345)
# mit set.seed(8) werden tatsächlich 8 NAs generiert, was dazu führt, dass wir gar kein Treatment-Effekt berechnen können. Gerne ausprobieren!

# Zufällige Anzahl an Treatments generieren
sample_amount <- sample(1:8 , 1)
nas_to_assign <- sample(1:8, sample_amount)

# NAs (Treatment vorhanden oder nicht) zuweisen
cities_df$unemployment_intervention[nas_to_assign] <- NA
cities_df$unemployment_no_intervention[!(1:8 %in% nas_to_assign)] <- NA

# Basierend darauf möchten wir jetzt erneut den kausalen Effekt berechnen
ate <- mean(cities_df$unemployment_intervention, na.rm = TRUE) - mean(cities_df$unemployment_no_intervention, na.rm = TRUE)
print(ate)
```

In diesem zufälligen Beispiel an Zuweisungen erhalten wir einen kausalen Effekt, der nicht exakt -1 ist. Das liegt daran, dass wir die NAs zufällig zugewiesen haben. In der Realität ist es natürlich nicht möglich, dass die Zuweisung von Interventionen zufällig erfolgt. In der Regel wird dies durch ein Experiment oder eine gezielte Zuweisung durchgeführt.
Mit einer anderen Anzahl an NAs und einer anderen Zuweisung von diesen, erhalten wir immer wieder andere Ergebnisse, dementsprechend sind diese immer mit Vorsicht zu genießen. Zudem sehen wir, dass der kausale Effekt in meinem Beispiel mehr als doppelt so stark geschätzt wird, als er tatsächlich ist (da wir ihn im Vorfeld selbst definiert haben). Dies liegt nicht zuletzt an der sehr kleinen Stichprobe.

*Durch `set.seed(8)` werden sogar exakt 8 NAs generiert, was dazu führt, dass wir gar kein Treatment beobachten können. Gerne selbst einmal ausprobieren!*


```{r}
# Wir erstellen noch einmal unseren Dataframe, da wir ihn zuvor verändert habe
cities_df <- data.frame(
  city = c("Bielefeld", "Berlin", "Budapest", "Barcelona", "Bologna", "Bremen", "Bordeaux", "Brüssel"),
  unemployment_no_intervention = c(5.2, 6.3, 4.3, 8.1, 5.2, 4, 7.5, 3.4),
  unemployment_intervention = c(4.2, 5.3, 3.3, 7.1, 4.2, 3, 6.5, 2.4)
)

# Einträge mit einer Arbeitslosigkeit von mehr als 5%, wo wir als "perfekte Politiker" intervenieren möchten
cities_above_5 <- c(1,2,4,5,7)

# Intervention darauf basierend zuweisen
cities_df$unemployment_no_intervention[cities_above_5] <- NA
cities_df$unemployment_intervention[!(1:8 %in% cities_above_5)] <- NA

# Kausale Effekte, basierend auf dieser Zuordnung, berechnen
ate <- mean(cities_df$unemployment_intervention, na.rm = TRUE) - mean(cities_df$unemployment_no_intervention, na.rm = TRUE)
print(ate)
```

In diesem Beispiel erhalten wir nun einen Effekt von 1,56, also schätzen wir gar einen Anstieg der Arbeitslosigkeit als kausalen Effekt des Treatments. Dies ist nicht übereinstimmend mit der Realität, und lässt uns sehen, dass wir bei der Beurteilung von kausalen Effekten immer sehr vorsichtig sein müssen. Eine mögliche Lösung, um solche Schwierigkeiten zu umgehen, ist der *differences-in-differences*-Ansatz, den wir in der nächsten Übung näher untersuchen werden.


## Weitere Städte, künstliche Erweiterung des Datensatzes

```{r}
# Seed setzen für Replizierbarkeit
set.seed(26)

# Wir generieren mehr Städte, ich nenne sie A bis Z, mit Arbeitslosigkeit gestreut um 5%
additional_cities <- LETTERS[1:26]
additional_cities_df <- data.frame(
  city = additional_cities,
  unemployment_no_intervention = rnorm(26, mean = 5, sd = 1)
)

# Wir ordnen diesen Städten jetzt den Interventionswert -1 zu
additional_cities_df$unemployment_intervention <- additional_cities_df$unemployment_no_intervention - 1

# Und berechnen diesbezüglich wieder den kausalen Effekt, den wir bereits kennen
additional_cities_df$causal_effect <- additional_cities_df$unemployment_intervention - additional_cities_df$unemployment_no_intervention

# Test auf erfolgreiche Zuweisung des Effekts
mean_causal_effect <- mean(additional_cities_df$causal_effect)
print(mean_causal_effect)

# Wir weisen wieder zufällig NAs zu
sample_amount <- sample(1:26 , 1)
nas_to_assign <- sample(1:26, sample_amount)

# Und ordnen diese NAs wieder zu
additional_cities_df$unemployment_intervention[nas_to_assign] <- NA
additional_cities_df$unemployment_no_intervention[!(1:8 %in% nas_to_assign)] <- NA

# Und berechnen anschließend wieder unseren kausalen Effekt
ate <- mean(additional_cities_df$unemployment_intervention, na.rm = TRUE) - mean(additional_cities_df$unemployment_no_intervention, na.rm = TRUE)
print(ate)
```

Hier sehen wir jetzt einen kausalen Effekt von -0.3228017. Dieser ist auch ein ganzes Stück entfernt von unserem wahren Wert, jedoch scheint er, bei einer einmaligen Simulation, schon besser zu passen, als er es in unserer kleineren Stichprobe tat. Dies zeigt, dass größere Stichproben und mehr Daten uns helfen können, bessere Schätzungen zu erhalten.


## Bonus: Spurious Correlations

Wie in der Übung besprochen gibt es hier noch den Link zur Website von Tyler Vigen:
https://tylervigen.com/spurious-correlations
Hier findet ihr viele interessante Korrelationen, vielleicht findet ihr ja auch eine, die euch besonders überrascht, oder einen spannenden Fun-Fact für die nächste Party.
