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
- Daten bereinigen
- Einfache & übersichtliche Datenexploration
- Variablen-Transformationen
- Spalten
- Umbenennen einer Spalte
- Alle Spaltennamen gleichzeitig ändern
- Auswahl einer Teilmenge von Spalten gemäss ihrer Position im Datensatz
- Auswahl einer Teilmenge von Spalten im Datensatz gemäss deren Spalten-Namen
- Spalten löschen
- Neue Spalten in einem Datensatz erstellen
- Ersetzen von Werten innerhalb einer Spalte
- Missings (=
NA
s)- Zähle die Anzahl an Missings
- Selektiere alle NA-Werte innerhalb einer Spalte
- Filtriere alle NA-Warte in einen neuen Datensatz
- Erstellen eines Datensatzes, welcher ausschliesslich NA-Werten besteht
- Korrelation mit Missings
- Lösche Zeilen, die Missings enthalten
- Lösche Spalten, die Missings enthalten
- Manuelle “Missing-Imputation”: Ersetze die Missings mit einem neuen Wert
- Erstellung eines Datensatzes
- Duplikate in den Daten
- Filtrierung von Daten
- Summary Statistics
- Datensatz Transformation
- Fusion von Datensätzen
- Regressions-Modelle
- Methoden
- Daten Visualisierung
- Statistische Berechnungen
- Allgemeines zum Projekt-Management
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 RStrings
automatisch alsFaktor-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 einemstring
“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 Funktionread.xls()
zum Einlesen von.xls
-Dateien, und dasxlsx
-Paket hat eine Funktionread.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()
: SASread_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 (= NA
s)
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