R Code Zusammenfassung

In diesem Dokument habe ich eine Reihe von R-Codes aufgelistet, die jedem angehenden Data Scientist helfen sollen, gängige Aufgaben in diesem Bereich zu erledigen.

Bevor Sie mit dem Lesen beginnen & um Ihre Zeit nicht zu verschwenden, möchte ich gerne auf einen wichtigen kontextuellen Hinweis bemerken:
Ich habe Volkswirtschaft studiert, daher können die empfohlenen Codes - insbesondere die Modelle - (stark) von der Denk- & Arbeitsweise von Volkswirten beeinflusst sein..

Dennoch hoffe ich, dass Sie finden werden, wonach Sie suchen 🔥

Inhaltsverzeichnis


Grundlagen in R für Data-Science


Arbeitsbereich in R löschen

Folgender Code sollte in JEDES R-Skript eingefügt werden, welches verwendet wird. Dies bereinigt alle Variablen, die in der globalen Umgebung von R gespeichert sind:

rm(list = ls())

Variablen oder Datensätze in R löschen

Wenn einige Variablen und / oder Datensätze nicht mehr benötigt werden, empfiehlt es sich, diese zu löschen:

rm(list= c("dd_1", "dd_2", "var_1", "var_2")) # Datensätze & Variablen, die
# nicht mehr gebraucht werden

Ein Package installieren

install.packages("installr") 

Das Package installr kann durch jegliche Package-Namen ersetzt werden, welche installiert werden sollten.

Mehrere Packages installieren

install.packages(c("ggplot2", "gcookbook", "MASS", "dplyr"))

Update Packages

Option 1:

update.packages() 

Der Nachteil von “Opiton 1” ist, dass R uns - für JEDES einzelne Package - fragt, ob man es aktualisieren will. Das kann sehr lange dauern, besonders wenn viele Packages installiert wurden Aus diesem Grund gibt es “Option 2” (siehe unten).

Option 2:

update.packages(ask = FALSE) # Wenn alle Packages ein update benötigen, ohne 
# dass R nachfragt, dann benutze `ask = FALSE` als Input...

Updates von R

Folgender Code sollte ausgeführt werden:

if(!require(installr)) {
  install.packages("installr"); require(installr)}
updateR() # dies startet den Aktualisierungsprozess der R-Installation

Daten in R einlesen

.csv-Datei lesen

data <- read.csv("datafile.csv")

Alternativ kann auch die Funktion read_csv() verwendet werden (zu beachten ist dabei der Unterstrich anstelle des Punktes!) aus dem readr-Package. Diese Funktion ist deutlich schneller als read.csv()!

Kein Header in der ersten Zeile vorhanden

Daten können ebenfalls geladen werden, wenn die .csv-Datei über keine Kopfzeile in der ersten Zeile verfügt:

data <- read.csv("datafile.csv", header = FALSE)
Laden einer .csv-Datei mit speziellen Trennzeichen

Beim Laden einer “csv”-Datei gibt es verschiedene Möglichkeiten, um R mitzuteilen, dass eine neue Spalte begonnen hat.

Beispiele für Trennzeichen sind:

  • ;
  • Tabulatoren
  • etc…
data <- read.csv("datafile.csv", sep = "\t") #wenn die Daten
# tabulatorgetrennt sind, verwende 'sep = "\t"' --> dies ist ein Trennzeichen
Laden einer .csv-Datei mit einigen Spalten vom Typ string

Kontext: Was ist das Problem, wenn es Spalten gibt, die Strings enthalten?:
Standardmäßig behandelt R Strings automatisch als Faktor-Variablen, was NICHT (immer) das ist, was wir wollen.

Schritt 1:

Mit Hilfe des Inputs stringsAsFactors = FALSE innerhalb der read.csv() Funktion kann Abhilfe zu diesem Problem geschaffen werden (dh strings werden dann effektiv als strings behandelt, und nicht als factor):

data <- read.csv("datafile.csv", stringsAsFactors = FALSE)
Schritt 2 (optional):

Es kann sein, dass wir einige Spalten in “Faktoren” zurückverwandeln müssen.

Ein Beispiel, wenn wir “Schritt 2” anwenden müssen:
Nehmen wir an, eine der Spalten ist “Geschlecht” (mit einem string “Mann” oder “Frau” als angenommenen Wert), dann müssen wir sie (häufigerweise, aufgrund von Analyse-Zwecken) zurück in eine Faktor-Variable umwandeln.

data$Sex <- factor(data$Sex)
str(data)  # überprüfe, ob 'sex' nun eine "factor-variable" ist

Lade eine Excel-Datei

install.packages("readxl") # Nur einmalige Installation ist notwendig...
library(readxl)
data <- read_excel("datafile.xlsx", 1)
  • Hinweis: Es gibt weitere Packages zum Einlesen von Excel-Dateien. Das gdata-Paket hat eine Funktion read.xls() zum Einlesen von .xls-Dateien, und das xlsx-Paket hat eine Funktion read.xlsx() zum Einlesen von .xlsx-Dateien.
Lade Excel-Datei mit einem zweiten Sheet
data <- read_excel("datafile.xls", sheet = 2) # Um den Zugriff auf das 2.te
# Sheet zu erhalten
Lade Excel-Datei mit spezifischen Sheet-Namen
data <- read_excel("datafile.xls", sheet = "Revenues") # Um den Zugang zu
# einem Sheet mit spezifischen Namen zu erhalten.
Lade eine Excel-Datei, die keine Spalten-Namen besitzt
data <- read_excel("datafile.xls", sheet = 2, col_names = FALSE) # verwendet
# die ERSTE Zeile [= Zeile] des Sheets für den Spaltennamen. Wenn die Spalten
# KEINE Namen haben, dann muss der Input 'col_names = FALSE' verwenden
# werden, da die Funktion standardmäßig davon ausgeht, dass die Excel-Datei
# Spaltennamen haben. Wenn du den Typ jeder Spalte angeben willst, kann man 
# dies tun.Aber es ist nicht notwendig, da die Funktion versuchen wird, den
# Typ selbst zu ermitteln...
Spezifische Datentypen (Date-Time Format, numerisches Format usw.) beim Laden von Excel-Daten angeben
data <- read_excel("datafile.xls", col_types = c("blank", "text", "date", "numeric"))

Der obige Code lässt die erste Spalte weg [siehe “blank”] und gibt die Typen der nächsten drei Spalten an.

Lade Stata-Datei

# install.packages("readstata13") 
library(readstata13) # lade data von der STATA-Datei --> dazu braucht es 
# es das library(readstata13) Package!

data <- read.dta13("~/Path/to/your/data/Stata-File.dta")

Lade SPSS-Datei

library(haven) # Man benötigt das Package 'haven' für diese Aufgabe.
data <- read_sav("datafile.sav")

Zu Beachten ist, dass das haven-Package auch über Funktionen verfügt, welche zum Einlesen anderer Datei-Formate nützlich sein kann, beispielsweise:

  • read_sas(): SAS
  • read_dta(): Stata

Hilfe

Wenn Informationen über einen R-Befehl benötigt wird, kann einfach ein beliebiger R-Befehl ausgeführt werden, indem VOR dem Ausdruck ein ? vorangestellt wird:

?write.table

Eine andere Möglichkeit wäre, help() zu verwenden.

Daten bereinigen


Einfache & übersichtliche Datenexploration

Anzahl Beobachtungen im Datensatz herausfinden

dim(sampleUScens2015)

Schneller Überblick der Daten erhalten

summary(data) # Mache eine Summary Statistics von allen Zeilen & Spalten

Nur die eindeutigen Werte aus einer bestimmten Spalte anzeigen und alle sortieren

sort(unique(data$educ))

Variablen-Transformationen

Kontext: Warum ist die Transformation von Variablen so wichtig?
Weil die Daten oft - zum Beispiel für eine Funktion oder für einen “For-Loop” - in einem ganz bestimmten Datentyp vorliegen müssen. Andernfalls funktioniert die Verarbeitung, die auf die Daten angewendet werden sollte, möglicherweise nicht. Deshalb ist es für einen Data Scientisten sehr wichtig, immer über die Datentypen im Projekt Bescheid zu wissen!

String in Faktor umwandeln

Angenommen, eine der Spalten in unserem Datensatz heißt “Geschlecht” und enthält string-Werte (= entweder “männlich” oder “weiblich”), dann müssen wir diese Spalte in eine “Faktor”-Variable umwandeln:

data$Sex <- factor(data$Sex)
str(data)  # überprüfe, ob 'sex' nun eine "factor-variable" ist

Dummy-Variable erstellen

university <- ifelse(sampleUScens2015$educ>=16,1,0) # Erstellt einen Dummy
# mittels der 'ifelse()'-Funcktion

Dummy-Variable anhand mehrerer Spalten erstellen

# Fasse die  "choices" in einer Spalte zusammen, indem alle separaten
# Spalte, welche in Zusammengang mit der "choices"-Variable stehen,
# in einer Spalte zusammengefasst werden:
data_test$choice <- ifelse(data_test$sport_dummy==1 & data_test$sport_dummy_young==1, 1,
                           ifelse(data_test$sport_dummy==1 & data_test$sport_dummy_young==0, 2,
                                  ifelse(data_test$sport_dummy==0 & data_test$sport_dummy_young==1, 3, 4)
                           )
)#das ist eine sogenannte "nested ifelse-function", welche es mir erlaubt,
# die benötigte "choice"-Variable zu konstruieren...

Zähle diejenigen Beobachtungen, die größer / kleiner als ein Schwellenwert sind

library(dplyr) # Die "count()"-function benötit das `dplyr`-package
count(ifelse(data$age>=39, 1,0))

Erstelle eindeutige IDs

Kontext: Warum ist diese Datentransformation wichtig?
Wenn zwei separate Datensätze zu einem großen Datensatz zusammengeführt werden müssen, ist es wichtig, dass beide eine gleiche eindeutige ID-Spalte haben, sonst können die beiden Datensätze nicht zu einem einzigen Datensatz zusammengeführt werden.

data_full <- transform(data_full,id=as.numeric(factor(country))) # erstellt eine "unique ID" für jedes Land --> wird als neue variable im dataset angehenkt
Möglichkeit 2:

Es gibt eine alternative Möglichkeit, eindeutige IDs zu erstellen (die ich bei der Datenbereinigung im Rahmen meiner Masterarbeit verwendet habe):

test_data$ID <- seq.int(nrow(test_data))

Standardisierung einer Variablen

  • Vorsicht: Der folgende Code ist NICHT eine standard-normal Transformation!
data2["standard_score2"] <- scale(data2$totalscor) # wir erstellen die neue 
# Spalte "standard_score2"

Interaktions-Terme erstellen

data["lrain_2"] <- data$lrain*data$lrain # dies erstellt den "interaction
# term"

Spalten

Umbenennen einer Spalte

names(dd5)[14]<- "teens" # cändert den Namen der 14. Spalte in "Teens" um.

Alle Spaltennamen gleichzeitig ändern

Um die neuen Spaltennamen manuell zuzuweisen, kann folgender Code verwendet werden:

names(data) <- c("Column1", "Column2", "Column3")

Auswahl einer Teilmenge von Spalten gemäss ihrer Position im Datensatz

Folgender Code kann verwendet, um einen übersichtlicheren Datensatz zu erstellen, indem spezifische Spalten selektiert werden:

data_test <- data[,c(39,43)] # erstellt einen Datensatz: Es werden jedoch 
# NICHT alle Zeilen ausgewählt, sondern nur diejenigen Spalten von 39 bis 43 werden selektiert.

Auswahl einer Teilmenge von Spalten im Datensatz gemäss deren Spalten-Namen

Nehmen wir an, wir wollen nur einige der Spalten wie “sport” oder “sport_dummy” usw. extrahieren. Dies kann mit folgendem Code erreicht werden:

test_data <- data[,c("type","sport","sport_dummy", "m_sport", "f_sport", "sport_parent", "sport_mother", "sport_father")]#198 missings aufgrund von 
# NAs

Spalten löschen

Das Löschen spezifischer Spalten kann mit dem folgenden Code erreicht werden:

data$male<-NULL # Dies wird die Spalte "male" eliminieren...
Unbenutzte Kategorien in kategorischen Variablen löschen
levels(data$type) # Nicht jede definierte Kategorie wird verwendet, 
# also lassen wir gewisse Kategorien weg
data$type <- droplevels(data$type, exclude = if(anyNA(levels(data$type))) NULL else NA)
levels(data$type) # überprüfe, ob es geklappt hat (es sollten nur 69 # Kategorien übrig bleiben...)

Neue Spalten in einem Datensatz erstellen

Es gilt zu beachten, dass es mehrere Möglichkeiten gibt, neue Spalten in einem Dataset zu erstellen.

Möglichkeit 1:

Wir erstellen eine neue Spalte auf der Basis einer bereits vorhandenen Spalte:

data_NJ$low <- ifelse(data_NJ$wage_st < 5,1,0) # erstellt eine neue Variable # // Spalte "low" für den Datensatz 'data_NJ'

### Alternativer Code:
data["lrain_2"] <- data$lrain*data$lrain #creates the interaction term
Möglichkeit 2:

Neue Spalte an einen bestehenden Datensatz anhängen:

university <- ifelse(sampleUScens2015$educ>=16,1,0) # erzeugt einen Dummy 
# mit der Funktion 'ifelse()'
data <- data.frame(sampleUScens2015,wage,lw,university) # Unter der 
# Verwendung der 'data.frame'-Funktion, bilden wir eine Matrix und fügen 
# den Spalten mit den Variablen-Namen "wage", "lw" und "university" zum
# bereits bereinigten Datensatz "sampleUScens" hinzu.

Ersetze die Werte innerhalb einer Spalte

Hier möchte ich einen Wert aus einer Spalte in eine andere Spalte einfügen, die an dieser Stelle einen “NA”-Wert hat

data_did3$col_na[is.na(data_did3$col_na)] <- data_did3$type[is.na(data_did3$col_na)] # Füge die Werte für das Jahr 2015 
# zu unserer neuen Spalte "Typ13" hinzu.

Missings (= NAs)

Zähle die Anzahl an Missings

length(data$twinno[is.na(data$twinno)])
Möglichkeit 2:
# count number of missings for a variable (here: 'frequency'):
missings <- data[is.na(data$frequency),] # 352 missings

Selektiere alle NA-Werte innerhalb einer Spalte

test_data <- data[is.na(data$type),]

Filtriere alle NA-Warte in einen neuen Datensatz

testo <- subset(test, is.na(corrupt_icrg)==TRUE)

Erstellen eines Datensatzes, welcher ausschliesslich NA-Werten besteht

Kontext; Warum sollten ein Datensatz mit ausschliesslich NA-Werten konstruiert werden?
Dies kann nützlich sein, um zu verstehen, warum es in einem (tabellarischen) Datensatz “NA”-Werte gibt, weil man dadurch alle Zeilen sieht, die irgendwo einen “NA”-Wert haben. Zu beachten ist, dass diese Methode andere Spalten beibehält, d.h. es werden gesamte Zeilen selektiert, bei denen die Spalten nicht notwendigerweise “NA”-Werte enthalten (was gut ist, weil uns dies zeigen kann, warum eine andere Spalte einen “NA”-Wert enthält!).

missings <- data[is.na(data$m_physact),] # selektiert nur diejenigen Zeilen
# mit Missings, sowie jede Spalte.

Korrelation mit Missings

cor(data.long$avehigh, data.long$aveweigh, use='pairwise')

Lösche Zeilen, die Missings enthalten

data_subset <- data.wide[ , c("down_exp")] #Selektiere die Spalten aus, 
# aus denen die NAs entfernt werden sollten
df <- data.wide[complete.cases(data_subset), ] # NAs nach Spalten auslassen

Lösche Spalten, die Missings enthalten

testo <- subset(testo, is.na(corrupt_icrg)==FALSE)

Manuelle “Missing-Imputation”: Ersetze die Missings mit einem neuen Wert

Nehmen wir an, dass wir einen bestimmten Wert in einem Datensatz ersetzen wollen, weil er zum Beispiel einen “NA”-Wert enthält.

data[122,] <- replace(data[122,], "islam1100", 0) #Setze "Islam1100" für 
# das Land Israel gleich 0 (statt 1)
View(data) #überprüfe, ob es geklappt hat?

Zu beachten ist, dass es sich nicht unbedingt um einen Missing handeln muss. Eine andere Möglichkeit (zu Missings) wäre, dass es irgendwo in einer Zeile des Datensatzes einen falschen Wert gab.

Erstellung eines Datensatzes

Erstelle einen neuen Datensatz, welcher aus ausgewählten Spalten besteht

data_sport <- data.frame("sport" = data[,c(22)], "ysport" = data[,c(32)]) 
# Wir müssen die Spaltennamen angeben, wenn wir einen neuen Datensatz
# erstellen, deshalb habe ich "sport" für die Spalte 21 [= 'sport-column'
# in den Daten] & "ysport" für Spalte 32 geschrieben.

Create a new Dataset by Filtering

did_wage <- subset(data, gap>0) # erzeugt eine neue Variable zum Testen
# vom Ausdruck 'gap>0'.

Duplikate in den Daten

Nur eindeutige Werte anzeigen, dh die Duplikate werden ausgeschlossen

Nehmen wir an, unser Ziel ist es, einen Überblick über den Definitionsbereich zu haben, die die Zufallsvariable einer bestimmten Spalte annehmen kann. Dies lässt sich leicht mit dem folgenden Code erreichen:

unique(sort(data$empstat)) # Weil wir "unique" verwenden, wird es keine 
# Duplikate mehr geben...

Filtrierung von Daten

data_new <- subset(data, sample==1) # Beobachtungen mit `sample == 0` werden
# aus dem Datensatz entfernt...
data_NJ <- subset(data, sample ==1 & state==1) # 2 Kriterien

Summary Statistics

Kurze & einfache Zusammenfassung der Daten

summary(data) # Erstellt eine summary statistics von allen Spalten

Berechnung vom Mittelwert

plot <- aggregate(data_int, by=list(data_int$sport), mean) # ZF eines 
# Modells 

Berechnung von Mittelwert, Varianz und Standardabweichung

mean_score <- mean(data2$totalscore, na.rm=TRUE) #ignoriere die NA-Werte und 
# berechne den Mittelwert
variance_score <- sqrt(var(data2$totalscore, na.rm=TRUE))

Zu beachten ist der Input-Parameter na.rm = TRUE innerhalb von mean() und var(), wenn wir die Berechnung des Mittelwertes und der Varianz durchführen.

Datensatz Transformation

Transformiere einen Datensatz ins “Wide”-Format

data.wide <- reshape(data , idvar = "family", timevar = "twinno", direction = "wide") #die `idvar` kennzeichnet die variable eindeutig. Hier: family; die timevar sind die einzelnen twins. Für sie wird jeweils eine eigene Spalte kreiert.
View(data.wide)

Fusion von Datensätzen

Fusion zwei Datensätzen

Hier fusioniere ich 2 Datensätze zusammen, indem ich die beiden über die Variable country-code von den Datensätze 1) “data” und 2) “ccodealp” (diese Spalte ist in beiden Datensätzen vorhanden) zusammenführe. Der “neue” Datensatz heißt “data_1”. Er zeigt nur diejenigen Beobachtungen an, die erfolgreich zusammengeführt wurden.

data_1 <- read.csv("~/Uni/Masterstudium/FS_2019/Policy Analysts/Problem Set/PS3/qog_bas_cs_jan19.csv") #Downloaded data csv file

fulldata <-merge(data, data_1, by.x="countrycode", by.y="ccodealp")

Regressions-Modelle


Simple lineare Regression mit 1 X-Variablen

model <- lm(data$cigs ~ data$educ) # Schätzt ein Regressions-Modell. 
# Beachte: `lm(y ~ x)`

Ausschluss der Konstanten aus einer Regression

model7 <- lm(data$normpolity ~ data$arabconquest+data$muslimmajority+data$lrain+data$lrain_2+data$lrain_3 + data$fuel + data$oceania + data$europe + data$asia + data$americas + data$africa - 1)

Wie zu sehen ist, muss lediglich der Term -1 zur gewöhnlichen Syntax eines Regressionsmodells hinzugefügt werden, um die Konstante in einer Regression auszuschließen.

Zusammenfassung der Modell-Resultate

summary(model) # summary statstics eines Regressions Models

Berechnung der geschätzten Koeffizienten

b_1 <- cov(data$cigs,data$educ)/var(data$educ) # Berechne den geschätzten
# Beta-Koeffizienten mit Hilfe der Formel, die ich auf den 
# Ökonometrie-Folien gefunden habe
b_0 <- mean(data$cigs)-b_1*mean(data$educ) #Berechne den
# Steigungs-Koeffizienten
# auch bekannt als "beta 0" = Intercept

Selektierung eines Koeffizienten

b1 <- reg5$coefficients[1]

Extrahieren der Residuen

regres <- lm(data$female~data$educ + data$age)
res <- data$female - predict(regres) # In "Worten", würde dies bedeuten: 
# `y - y(hat)`

Stargazer

Stargazer ist ein R-Package, das in der Wissenschaft verwendet wird, um schöne Tabellen zu erstellen, wie sie in wissenschaftlichen Journals zu sehen sind.

Erstellen einer Tabelle mit nur 1 Modell

In meinem Arbeitsablauf habe ich - zuerst - schöne stargazer-Tabellen als .html-Tabellen ausgegeben, sie - anschliessend - mit CSS formatiert und dann - per Copy-Paste - in mein Word-Dokument eingefügt.

Mit dem folgenden Code lässt sich der ersten Teil dieses Arbeitsablaufs replizieren, dh es wird eine Tabelle im .html-Format erstellt:

stargazer(model5, title="OLS Regression",align=TRUE,covariate.labels = c("Muslim Majority", "Average Fertility"), type="text",out="~/Documents/Uni/Masterstudium/FS_2019/Policy Analysts/Problem Set/PS3/Table1.html")

Erstellen einer Tabelle mit > 1 Regressionsmodell

stargazer(model1, model2, model3, model2_2, title="Different OLS Regressions",align=TRUE, type="text",out="~/Documents/Uni/Masterstudium/FS_2019/Policy Analysts/Problem Set/PS3/Table1.html")

Erstellen einer Tabelle, aber einige Kovariaten weglassen

Kontext: Warum sollten - bei der Resultat-Präsentation - gewisse Koveriaten-Effekte weggelassen werden?
Bei der Verwendung einer Regression mit “Fixed-Effects” würde ich nicht empfehlen, alle Effektgrößen auszudrucken, da man sonst zu viele Koeffizienten in der Tabelle abbildet (was den Leser nur vom Wesentlichen ablenkt)!

stargazer(model7, model8, title="Standard OLS Regressions",align=TRUE, type="html", omit=c("fuelendowed","europe", "americas", "africa", "asia", "oceania"), out="~/Documents/Uni/Masterstudium/HS 2018/Empirical Methods/PS4/Table1.html")

Methoden


Fixed Effects

Um Fixed Effects in eine Regression einzubeziehen, gibt es 2 Möglichkeiten.

Möglichkeit 1:

Bei dieser Möglichkeit verwenden wir kein spezifisches R-Package, dh wir benutzen nur “native” R:

test <- lm(lifexp ~ log_gdppc + factor(country), data = data) # hier, füge 
# ich ein "country FE" in das Regressions-Modell ein --> es wird hier 
# KEIN Package benötigt
summary(test) # überprüfe, ob es tatsächlich geklappt hat? 

Möglichkeit 2:

Hier wird das R-Package plm verwendet:

library(Formula) #Es werden beide Pacakges benötigt, um FEs einzubinden in 
# eine Regression...
library(plm)

# Bereite den Datensatz vor, um lediglich den "country FE" einzubinden:
data_FE <- pdata.frame(data, index = c("country")) #speichere die Daten 
# in einen speziellen "country FE"-Datensatz ab...

# Nun sind wir bereit, die "country FE"-Regression zu schätzen:
model1 <- plm(lifexp ~ log_gdppc, data=data_FE, model = "within", effect = "individual") 
# Beachte: ersetze den Input `individual` zu `twoways`, wenn du nicht nur 
# "country FE", sondern auch - zum Beispiel - einen "Kohorten-FE" einfügen 
# willst 
summary(model1) # überprüfen, ob es funktioniert hat?

# Nun wolllen wir sowohl "country FEs", wie auch "time FEs" einfügen:
data_country_time <- pdata.frame(data, index = c("year", "country"))

model3 <- plm(lifexp ~ log_gdppc, data=data_country_time, model = "within", effect = "twoways") 
# Der Unterschied hier - mit zwei (statt 1) FE - ist, dass wir die Option 
# `twoways` verwenden müssen...

# Für eine Stargazer-Tabelle, verwende den folgenden Code:
stargazer(model3, title="OLS Regression",align=TRUE,covariate.labels = c("GDP per capita (in log)"), type="text",out="~/Documents/Uni/Masterstudium/FS_2019/Policy Analysts/Problem Set/PS5/Table1.html") # beachte: der Output ist eine 
# Tabelle im `.html`-Format!

IV-Regression

#lade die Packages zunächst in die R-Konsole:
library(ivpack)

## IV-Regressionen werden mit folgender Funktion geschätzt
lmiv<- ivreg(lnearn~highqua+age+agesq | age+agesq+twihigh , data = data)

## Nun wieder eine IV-Regression, allerdings mit "robuster"
# Standardabweichungen
lmiv6<- ivreg(normpolity~arabconquest+fuelendowed+oceania+europe+asia+americas+africa-1 | fuelendowed+oceania+europe+asia+americas+africa+mecca+lrain-1 , data = data_muslim) #es spielt keine Rolle wo man die IV hinsetzt on the RHS im Term der Addition
summary(lmiv6) #überprüfe, ob es geklappt hat?
lmiv6<-robust.se(lmiv6)#für "robuste" Standardabweichungen, verwende folgende
# Funktion...

Clustering your Standard Errors

model4 <- coeftest(model4, vcov=vcovHC(model4,type="HC0",cluster="time")) #
geclusterte Standardabweichungen...

Synthetic Control für Difference-in-Differences (DiD) Analyse

Der folgende Code erzeugt eine synthetische Kontrollgruppe in meinem DiD-Modell.

# Download Package:
library(Synth) #Es wird dieses Package benötigt, da ansonsten keine 
# "Synthetic Control"-Methode verwendet werden kann.

# Verwende den folgenden Code, um die Daten vorzubereiten:
data.out <- dataprep(
  foo = data_full, #plug in your dataset
  predictors = c("reform_cap", "GINIp", "GINIc"), # Regressoren des 
  # Datensatzes, den man verwenden möchte
  predictors.op = "mean", # in DiD, vergleicht man Mittelwerte
  time.predictors.prior = 1960:1976, # Perioden VOR dem "Treatment"
  dependent="IGEincome",
  unit.variable = "id",
  unit.names.variable = "country",
  time.variable = "year.x",
  treatment.identifier = 97,# schlage nach, welche ID der Schweiz gehört
  # (= Treated Gruppe)
  controls.identifier = c(2:96, 98:109), # Kontroll-Gruppe
  time.optimize.ssr = 1960:1976,
  time.plot = 1955:1997)
  
# Zu guter Letzt, generiere die Graphik:
synth.out <- synth(data.prep.obj = data.out, method = "BFGS")

Discrete Choice Modellierung

Vorbereiten der Y-Variable für die Modellierung mehrerer “Choices”

# Zusammenfassung der Variable "choices", indem die Werte verschiedener 
# Spalten in eine einzige Spalte transformiert wird:
data_test$choice <- ifelse(data_test$sport_dummy==1 & data_test$sport_dummy_young==1, 1,
                           ifelse(data_test$sport_dummy==1 & data_test$sport_dummy_young==0, 2,
                                  ifelse(data_test$sport_dummy==0 & data_test$sport_dummy_young==1, 3, 4)
                           )
) # das ist eine verschachtelte 'ifelse'-Funktion, welche es mir ermöglicht
# meine "choice"-Variable zu erstellen  (= y-Variable)

str(data)# überprüfe, ob die "choice"-Variable tatsächlich eine kategorische 
# Variable ist --> falls nein, muss dies unbedingt noch erledigt werden, 
# für spätere Schritte...

Die “choice”-Variable in kategorischer Variable umwandeln

data$choiceF <- factor(data$choice)# erstelle eine neue Variable, welche 
# eine kategorische Version der "choice"-Variable darstellt...

# damit ein Multinomiales Logit Modell geschätzt werden kann, wird eine 
# "Referenz-Kategorie" innerhalb der neu kreierten Variable "choiceF" 
# benötigt:
data$choices <- relevel(data$choiceF, ref = "1")# unsere Referenz-Kategorie
# wird hier Nummer "1" sein, welcher der Kategorie "Leute haben Sport in 
# ihrer Kindheit getrieben, sowie auch im erwachsenen Alter" entspricht.

Erstellen eines Multinomial-Logit-Modells (MNL)

library(nnet)# Wir benötigen dieses package für eine Multinomiale Logit
# Regression

model1 <- multinom(data$choices ~ data$m_sport + data$f_educ)# das ist 
# ein Test-Modell: ich möchte herausfinden, ob ich dieselben geschätzten
# Koeffizienten erhalte, wie das Musterbeispiel MNL-Modell, welches ich 
# von meinem Professor erhalten habe? 
summary(model1) # --> Ja, die geschätzten Koeffizienten sind (beinahe) 
# diesselben!
# Somit ist dieses Package zuveröässig und kann verwendet werden! :)

Erstellung von Vorhersagen mit einem MNL-Modell

predict(model1, data)#Vorhersagen in Bezug zur Y-Variable
predict(model1, data, type = "prob")#Vorhersagen in Bezug zur
# Grenz-Wahrscheinlichkeit (engl. "marginal probabilities").

Überprüfung der Präzision meiner Vorhersage mittels MNL-Modells

Der nachstehende Code erzeugt eine “Confusion Matrix”, aus der hervorgeht, wie viele unserer Klassifizierungen richtig/falsch waren.

cm <- table(predict(model1), data$choice)#beachte: funktioniert nur, wenn
# du keine NAs im Datensatz hast...
print(cm)

Daten Visualisierung


Streudiagramm

Mit dem folgenden Code kann die Korrelation zwischen 2 Variablen visualisiert werden:

with(data, plot(data$educ, data$cigs, main = "Years of Education VS. Cigarrets smoked per day", xlab = "Years of education", ylab="Cigarrets smoked per day")) # Bachte: plot(x-variable, y-variable)
abline(model, lwd = 2, lty = 3) #lwd = Linien-Dicke; lty = Linien-Typ

Histogramm

hist(data$wdi_mort, main ="Distribution of infant mortality", xlab = "Mortality Rates",ylab = "Frequency of Mortality Rates",col = "red3", ylim=c(0,110)) #erstelle ein Histogramm der Kindersterblichkeits-Rate

Darstellung von Konfidenzintervallen

Konf <- predict(reg1, interval="confidence", level=.95) # beachte: du
# musst eine lineare Regression schätzen, damit du überhaupt ein 
# Konfidenz-Intervall abbilden kannst...

with(data, plot(data$corruptionun, data$mortalityun, main = "Corruption vs. Mortality", xlab = "Corruption", ylab= "Mortality"))
abline(reg1, lwd = 2, lty = 3)
lines(x = data$corruptionun[order(data$corruptionun)],y= Konf[order(data$corruptionun),2],lwd=2,col= 2)
lines(x = data$corruptionun[order(data$corruptionun)],y= Konf[order(data$corruptionun),3],lwd=2, col= 2)

Residuen-Diagramm erstellen

reslag <- lag(res, k=1) # Verschiebt die Position der Residuen im Vektor um 1 nach vorne
cor(res[2:807], reslag[2:807]) #Bildet die Korrelation. Achtung: wenn du hier
# ab "1" beginnst, wird es einen Error geben!!!

Dichtefunktionen zeichnen

plot(density(res))

Autokorrelation zeichnen

Mit dem folgenden Code wird die Korrelation zwischen den Residuen dargestellt:

acf(res, main ="Autocorrelation of the residuals")

Statistische Berechnungen


Berechnung der t-Statistik “von Hand”

Im folgenden Beispiel haben wir ein Modell geschätzt und wollen nun die t-Statistik unseres dritten Koeffizienten berechnen.

Dies wird durch den folgenden Code erreicht:

se <- sqrt(diag(vcov(reg5)))
t.stat <- reg5$coefficients[4]/se[4] #beachte: in unserem Modell gibt es 
# eine "Konstante" [= intercept], deshalb müssen wir die 4 und nicht die 3
# selektieren.
t.stat

Ein komplizierterer t-Test, der “von Hand” berechnet wurde: beta4 - beta7 = 0

reg19 <- lm(sam$lw ~ sam$educ +sam$age+sam$childrenly+sam$Bus+sam$hea+sam$tech+sam$scie) # 7 Regressoren 
# und 1 Konstante = 8 geschätzte Koeffizienten
summary(reg19)
cov <- (vcov(reg19))
se19 <- sqrt(cov[5,5]+cov[8,8]-2*cov[5,8]) #beachte: wir haben eine
# Konstante, weshalb wir hier "beta4 = 5" and "beta7 = 8" haben...
t.stat19 <- (reg19$coefficients[5]-reg19$coefficients[8])/se19 # vergiss 
# nicht, die Konstante [= intercept] mitzuzählen, wenn du die Koeffizienten 
# hier selektierst! --> immer schön "+1" rechnen... ;)
p.val <-2*pt(-abs(t.stat19),df=reg19$df.residual)
p.val

Berechnung der F-Statistik “von Hand”

reg7 <- lm(s$lw ~ s$educ +s$age+s$female+ s$educ*s$female+s$female*s$age) #5
# Regressoren & 1 Konstante = 6 Koeffizienten werden hier geschätzt
summary(reg7) #das isr das sog. "unrestricted model", mit allen Regressoren
R <- rbind (c(0 ,0 ,0,1 ,0,0) , c(0 ,0,0,0 ,1 ,0),c(0,0,0,0,0,1)) # Setze
# eine 1 für diejenigen Koeffizienten, die du testen möchtest 
# --> Hinweis: die erste 0 steht für die Konstante!
r <- c(0 ,0,0) # Anzahl an Gleichungen
ftest <- linearHypothesis ( reg7 , hypothesis.matrix =R, rhs=r, vcov = vcovHC ( reg7 ,"HC1"))
regrest <- lm(s$lw ~ s$educ +s$age) #das ist das sog. "restricted model", 
# welches OHNE die getesteten Regressoren geschätzt wird.
summary(regrest)
f.test <- ((sum((regrest$residuals)^2)-sum((reg7$residuals)^2))/3)/(sum((reg7$residuals)^2)/(reg7$df.residual))
f.test
crit_value <- qf(0.95, df1=3, df2=561073)

Erstellung einer Monte Carlo Simulation “von Hand”

N = 10  # Grösse der Stichprobe, die man ziehen möchte --> du kannst 
# diesen Parameter ändern, wenn du möchtest...
R = 200 # das ist das Ende deines Zählers (vom For-Loop, siehe weiter unten 
# im Code...) --> das ist die Anzahl an Wiederholungen / "Epochen", bei denen
# du zufällig(!) eine Stichprobe der Grösse "N" ziehst. --> auch diesen 
# Parameter kannst du ändern, wenn du möchtest :)
x_r <- mat.or.vec(R,1) # Erstellt einen 0-Vektor der Länge "R" (= 200) und
# einer Dimension von "1", dh wir haben es hier mit einem Vektor (und keiner)
# Matrix zu tun...

# Erstelle einen For-Loop:
for(i in 1:R){
  x <- rexp(N) # Zufällige Ziehung einer Stichprobe der Grösse 'N' --> 
  # hier: eine zufällige Ziehung von 10 Beobachtungen
  meanx_r <- mean(x) # Bererchung unseres 'Stichproben-Mittelwertes'
  # (= Zufallsvariable)
  x_r[i]<-meanx_r # Speichere den gerade eben berechneten
  # 'Stichproben-Mittelwert' an der "i"-ten Position im Vektor, den wir 
  # oben erstellt haben..
}

hist(x_r, main ="Distribution of x^r with N=1 and R=200", xlab = "x^r",ylab = "Frequency of x^r",col = "red3")
meanx <- mean(x_r) # Berechne nun den Mittelwert aller zufällig generierten
# 'Stichproben-Mittelwert' (das sollten insgesamt 200 sein in diesem
# Beispiel, was dem zugewiesenen Wert von "R" entspricht, siehe oben...)
varx <-var(x_r) # Berechne auch die Varianz der zufällig generierten
# 'Stichproben-Mittelwerten'

Simulieren einer Normalverteilung via einer Sequenz

Schritt 1:

Wir definieren eine Abfolge von Werten via R:

sequence <- seq(-50, 50, by = 0.1) # wir definieren diese Sequenz, damit wir
# eine Menge an X-Variablen haben. Es ist wichtig, dass wir darauf achten,
# dass wir den gesamten Definitionsbereich der Residuen in dieser definierten
# Sequenz berücksichtigen. Deshalb geben wir ein Minimum als Startpunkt und
# das Maximum als Endpunkt ein.

Schritt 2:

Als Nächstes, weisen wir R an, eine Normalverteilung über die definierte Abfolge (siehe Schritt 1) zu konstruieren.

Auf diese Weise können wir sehen, welche Werte mit hoher Wahrscheinlichkeit in der Normalverteilung vorkommen werden.

normal <- dnorm(sequence, mean = 0, sd = sqrt(var(res))) # jetzt sagt man R,
# es solle eine Normalverteilung von der angegebenen Sequenz bilden. 
# Dadurch sieht man, welche Werte mit hoher Wahrscheinlichkeit innerhalb 
# der Normalverteilung auftauchen werden...

Allgemeines zum Projekt-Management


Eine Liste von Packages zur Erstellung eines vollständigen Econ Data-Science Projekts

library (sandwich)
library (lmtest) #um Regressionen zu erstellen
library (car)
library(foreign)
library(stargazer) # um Tabellen im wissenschaftlichen Format zu erstellen
library(readstata13) #um Stata-Files laden zu können

Zu meinen Interessen gehören Webentwicklung, Data Science, Verhaltensökonomie und alles, was mit Unternehmertum zu tun hat.