library(RefManageR)
BibOptions(check.entries = FALSE,
           bib.style = "authoryear",
           cite.style = "authoryear",
           style = "markdown",
           hyperlink = FALSE,
           dashed = FALSE)
myBib <- ReadBib("./readings.bib", check = FALSE)

Vorbereitungen

Die Folien nutzen den Datensatz corona_by_county, der ab v0.0.3 im learningR-Paket enthalten ist. Die Tabelle enthält zur Corona-Pandemie etliche Variablen auf Kreisebene (Landkreise, kreisfreie Städte).

remotes::install_github("ablaette/learningR") # Installation der aktuellen Version
library(learningR)
dim(corona_by_county)

Die HTML-Variante dieser Folien ist im Paket als "Vignette" enthalten. Sie können Sie wie folgt aufrufen:

browseVignettes(package = "learningR")

Um den Code selbst nachzuvollziehen, öffnen Sie die R Markdown-Datei, auf welcher der Foliensatz beruht (Auswahl von "f_statistics.Rmd"):

learningR::open_rmd_file()

Über den Corona-Regionaldatensatz

Der Corona-Regionaldatensatz corona_by_county, der im Paket enthalten ist, umfasst die folgenden Variablen:

Der Datensatz wurde mit diesem R-Skript durch die Verknüpfung verschiedener Datenquellen automatisch erstellt. Die konsistente Nutzung des Regionalschlüssels (RS) in offiziellen Daten auf Kreisebene erleichtert diese Verknüpfung von Daten ungemein.


Statistische Daten: 'dplyr' als Standard

| Funktion | Kurzbeschreibung | | ---------|------------------| | mutate() | Definition neuer Variablen, die von existierenden Variablen abgeleitet sind | | select() | Auswahl von Variablen | | filter() | Auswahl von Fällen entsprechend ihrer Werte | | summarise() | Erstellen von "summary statistics" | | arrange() | Umgruppierung von Spalten (Reihenfolge von Variablen) |


Deskriptive Statistik

income <- corona_by_county[["income"]]
mean(income, na.rm = TRUE)
sd(income, na.rm = TRUE)
c(min = min(income, na.rm = TRUE), max = max(income, na.rm = TRUE))

... doch welcher Landkreis hat das höchste durchschnittliche Haushaltseinkommen (den höchsten Ausländeranteil, die niedrigste Inzidenz etc.)?


Verteilungen

hist(corona_by_county[["income"]])

Deskriptive Statistik II (for-Schleife)

by_county_data <- subset(corona_by_county, !is.na(region))
regions <- unique(by_county_data[["region"]])
county_data_aggr_li <- list()
for (buland in regions){
  corona_by_county_min <- subset(corona_by_county, region == buland)
  county_data_aggr_li[[buland]] <- data.frame(
    mean = mean(corona_by_county_min[["agequot"]], na.rm = TRUE),
    sd = sd(corona_by_county_min[["agequot"]], na.rm = TRUE)
  )
}
county_data_aggr <- do.call(rbind, county_data_aggr_li)
head(county_data_aggr, 3)

Deskriptive Statistik II (lapply-Variante)

regions <- unique(by_county_data[["region"]])
county_data_aggr_li <- lapply(
  regions,
  function(buland){
    corona_by_county_min <- subset(corona_by_county, region == buland)
    data.frame(
      region = buland,
      mean = mean(corona_by_county_min[["agequot"]], na.rm = TRUE),
      sd = sd(corona_by_county_min[["agequot"]], na.rm = TRUE)
    )
  }
)
county_data_aggr <- do.call(rbind, county_data_aggr_li)
head(county_data_aggr, 3)

Deskriptive Statistik II (dplyr-Variante)

library(dplyr, quietly = TRUE, warn.conflicts = FALSE)
corona_by_county %>%
  filter(!is.na(region)) %>%
  group_by(region) %>%
  summarise(mean = mean(agequot), sd = sd(agequot)) %>%
  head(6)

Deskriptive Statistik II (data.table)

library(data.table, warn.conflicts = FALSE)
dt <- data.table(corona_by_county)
dt[!is.na(region), list(mean = mean(.SD$agequot), sd = sd(.SD$agequot)), by = "region"]

Formeln in R: Boxplot

boxplot(agequot ~ region , data = by_county_data, las = 2)

Formeln in R: lattice

lattice::histogram(~ afd | region, data = corona_by_county)

Formeln in R: lattice

library(lattice)
vars <- c("cases7_per_100k", "foreign_pop_share", "afd", "income", "per_km2", "agequot")
lattice::splom(~ corona_by_county[, vars], data = corona_by_county)

Lineare Regression

Fragestellungen / Hypothesen:

Bei Berechnung einer Regression mit der lm()-Funktion kommt die bereits bekannte Formelnotation zum Einsatz:

r <- lm(cases7_per_100k ~ afd, data = by_county_data)

Lineare Regression - summary()

summary(r)

Das lm-Objekt - str()

str(summary(r))

Lineare Regression im Scatterplot

plot(by_county_data$afd, by_county_data$cases7_per_100k)
abline(r)

Multivariate Regression: Vorbereitungen

Vor der Berechnung einer Regression sollten die Variablen normalisiert werden.

normalize <- function(x){
  ((x - max(x, na.rm = TRUE)) / (max(x, na.rm = TRUE) - min(x, na.rm = TRUE))) + 1
}
by_county_data_norm <- mutate(
  .data = by_county_data,
  cases7_per_100k = normalize(cases7_per_100k),
  foreign_pop_share = normalize(foreign_pop_share),
  afd = normalize(afd), income = normalize(income),
  per_km2 = normalize(per_km2), agequot = normalize(agequot)
)

Alternativ:

vars <- c("cases7_per_100k", "foreign_pop_share", "afd", "income", "per_km2", "agequot")
normalize_col <- function(x){
  x <- by_county_data[[x]]
  (max(x, na.rm = TRUE) - x) / (max(x, na.rm = TRUE) - min(x, na.rm = TRUE))
}
df_norm <- data.frame(lapply(setNames(vars, vars), normalize_col))

Modelle im Vergleich

Berechnung alternativer Modelle

m1 <- lm(cases7_per_100k ~ foreign_pop_share, data = by_county_data_norm)
m2 <- lm(cases7_per_100k ~ foreign_pop_share + income, data = by_county_data_norm)
m3 <- lm(cases7_per_100k ~ foreign_pop_share + income + afd, data = by_county_data_norm)
m4 <- lm(
  cases7_per_100k ~ foreign_pop_share + income + afd + agequot + per_km2,
  data = by_county_data_norm
)

Für den Vergleich der Modelle nutzen wir das stargazer-Paket:

stargazer::stargazer(
  m1, m2, m3, m4,
  dep.var.labels.include = FALSE, type = "html", align = TRUE, single.row = TRUE, column.sep.width = "1pt",
  omit.stat = c("n", "rsq", "f", "ser")
)

Modelle im Vergleich

s <- stargazer::stargazer(m1, m2, m3, m4, dep.var.labels.include = FALSE, title = "Results", type = "html", align = TRUE, font.size = "tiny", single.row = TRUE, column.sep.width = "1pt", omit.stat = c("n", "rsq", "f", "ser"))

Diskussion


Logistische Regression: Daten

Wenn die abhängige Variable binär codiert ist, kommt die logistische Regression zum Einsatz. Ein typisches Szenario hierfür ist in der Politikwissenschaft die Wahl einer Partei.

Im folgenden Szenario interessieren wir uns für die möglichen Gründe einer Wahlentscheidung zugunsten der AfD bei der Bundestagswahl 2017. Als Datengrundlage verwenden wir die GLES-Nachwahlbefragung 2017.

Für die Vorbereitung des Datensatzes nutzen wir Funktionen des dplyr-Pakets.

library(dplyr)
library(gles)

bt_min <- filter(bt2017nw, !is.na(q19ba)) %>% 
  mutate(AfD = as.character(haven::as_factor(q19ba)) == "AfD") %>%
  mutate(income = as.integer(haven::as_factor(q192))) %>%
  mutate(dissatisfaction = as.integer(haven::as_factor(q33))) %>%
  mutate(citysize = as.integer(haven::as_factor(q197)))

Beachte: Die glm()-Funktion könnte auch Faktoren "verdauen"!


Logistische Regression: Modelle

Die abhängige Variable unseres ist die binär codierte Variable "AfD" mit den logischen Werten TRUE und FALSE. Wenn eine Befragte keine Angabe zur Parteiwahl gemacht hat (NA-Werte), haben wir den Fall aus der Analyse ausgeschlossen.

Wir verfolgen - sehr grobschlächtig! - drei Hypothesen, welche die Wahl der AfD erklären könnten:

Wir berechnen hierzu zwei Modelle. Die Notation verläuft parallel zur linearen Regression ...

m1 <- glm(AfD ~ income, data = bt_min, family = binomial())
m2 <- glm(AfD ~ income + dissatisfaction + citysize, data = bt_min, family = binomial())

Literatur

NoCite(myBib, "DiscoveringStatistics")
PrintBibliography(myBib)


ablaette/learningR documentation built on July 1, 2023, 1:11 a.m.