9  Ergebnisse exportieren

Der Export von Tabellen und Grafiken ist ein zentraler Schritt im Forschungsprozess. Ergebnisse müssen nicht nur korrekt berechnet, sondern auch ansprechend und reproduzierbar aufbereitet werden — sei es für eine Abschlussarbeit oder eine Präsentation. Anstatt Ergebnisse manuell zu kopieren und in Textverarbeitungsprogramme einzufügen, bietet R zahlreiche Funktionen und Pakete, um Outputs direkt in gängigen Formaten zu speichern. Dieser automatisierte Ansatz ist nicht nur zeitsparend, sondern vor allem entscheidend für die Reproduzierbarkeit wissenschaftlicher Analysen: Jeder Schritt bleibt im Code dokumentiert und kann jederzeit nachvollzogen oder mit neuen Daten rasch erneut ausgeführt werden. Manuelles Kopieren hingegen ist fehleranfällig, schwer überprüfbar und erschwert die transparente Weitergabe von Ergebnissen.

In diesem Kapitel lernen wir, wie wir Tabellen und ggplot-Grafiken aus R in unterschiedliche Formate exportieren können. Für die Beispiele verwenden wir erneut den wage1-Datensatz aus dem wooldridge-Package:

library(tidyverse)
library(wooldridge)
wage1 <- wage1 |>
  as_tibble() |>
  select(wage, educ, exper, female)

9.1 Tabellen exportieren

Tabellen lassen sich in R auf verschiedene Arten exportieren, wobei die Wahl des Packages vor allem vom gewünschten Output-Format abhängt. In vielen Fällen müssen wir uns die gewünschten Informationen zuerst selbst in R aufbereiten und als data.frame oder tibble Objekt speichern. Als Beispiel erstellen wir eine deskriptive Tabelle, in der wir Mittelwert und Standardabweichung von Lohn und Bildung sowohl für den ganzen Datensatz als auch nach Geschlecht darstellen:

overall <- wage1 |>
  select(wage, educ) |>
  pivot_longer(cols = everything(), names_to = "variable") |>
  summarise(
    mean.insg = mean(value, na.rm = T),
    sd.insg = sd(value, na.rm = T),
    .by = variable
  )

bysex <- wage1 |>
  select(wage, educ, female) |>
  pivot_longer(cols = -female, names_to = "variable") |>
  summarise(
    mean = mean(value, na.rm = T),
    sd = sd(value, na.rm = T),
    .by = c(variable, female)
  ) |>
  pivot_wider(values_from = c(mean, sd), names_from = female) |>
  select(variable, ends_with("_1"), ends_with("_0"))

tbl <- left_join(overall, bysex)
rm(overall, bysex)

tbl
#> # A tibble: 2 × 7
#>   variable mean.insg sd.insg mean_1  sd_1 mean_0  sd_0
#>   <chr>        <dbl>   <dbl>  <dbl> <dbl>  <dbl> <dbl>
#> 1 wage          5.90    3.69   4.59  2.53   7.10  4.16
#> 2 educ         12.6     2.77  12.3   2.47  12.8   3.00

Das Objekt tbl enthält alle notwendigen Informationen, ist jedoch nicht ansprechend formatiert. Auf dieser Basis werden wir nun die folgende Tabelle exportieren:

Tabelle 9.1: Lohn und Bildung im wage1-Datensatz
Insgesamt
Frauen
Männer
MW SD MW SD MW SD
Stundenlohn (USD) 5.90 3.69 4.59 2.53 7.10 4.16
Bildungsjahre 12.56 2.77 12.32 2.47 12.79 3.00
Anm.: MW = Mittelwert, SD = Standardabweichung.

9.1.1 Tabellen nach LaTeX

Für den Export nach LaTeX nutzen wir das Package kableExtra, welches eine Vielzahl an Formatierungsoptionen bietet. Dazu zählen die Unterstützung für booktabs-Linien, die in wissenschaftlichen Papers übliche und typografisch empfohlene Tabellenformatierung, sowie für mehrspaltige Zellen, Fußnoten und Landscape-Tabellen. kableExtra ermöglicht außerdem den Export nach HTML. Für einen Überblick siehe hier.

Um unser tbl-Objekt wie in Tabelle 9.1 zu exportieren, verwenden wir die Funktion kbl() um eine Tabelle zu erstellen. Die wichtigsten Argument in kbl() sind in Tabelle 9.2 angeführt:

Tabelle 9.2: Übersicht: Relevante Argumente in kbl()
Argument Bedeutung Beispiel
caption Tabellenüberschrift caption = "Deskriptive Statistiken"
label LaTeX-Label für Querverweise label = "desc:wage1"
col.names Spaltenbezeichnungen col.names = c("Variable", "Mean")
row.names Zeilennamen anzeigen row.names = FALSE
align Spaltenausrichtung (l, c, r) align = c("l", "c", "r")
digits Nachkommastellen digits = 2
format Output-Format erzwingen format = "latex"
booktabs Booktabs-Linien für LaTeX booktabs = TRUE
escape LaTeX-Sonderzeichen escapen escape = FALSE
longtable Mehrseitige Tabellen in LaTeX longtable = TRUE

Um die gewünschten Formatierungen zu erreichen, wenden wir noch andere Funktionen aus dem kableExtra Package an: Mit add_header_above() fügen wir gruppierte Spalten hinzu, row_spec() adaptiert die Formatierung einer Zeile und footnote() spezifiziert die Fußnote der Tabelle. Für Erklärungen zu diesen und vielen weiteren Optionen bei der Erstellung von LaTeX-Tabellen mit kableExtra siehe die Online-Dokumentation des Packages. Mit save_kable("<DATEIPFAD>") speichern wir schlussendlich die Tabelle ab. LaTeX-Tabellen werden als .tex-Dateien gespeichert.

library("kableExtra")
tbl |>
  mutate(variable = c("Stundenlohn (USD)", "Bildungsjahre")) |>
  kbl(
    # Caption
    caption = "Lohn und Bildung im wage1-Datensatz",
    # Tabellenlabel
    label = "desc:wage1",
    # Spaltenbezeichnungen
    col.names = c(" ", rep(c("MW", "SD"), 3)),
    # Spaltenausrichtung
    align = c("l", rep("c", 6)),
    # Zahlen runden
    digits = 2,
    # Exportformat
    format = "latex",
    booktabs = T
  ) |>
  # Gruppierende Kopfzeile
  add_header_above(
    c(" ", "Insgesamt" = 2, "Frauen" = 2, "Männer" = 2),
    bold = T
  ) |>
  # Kopfzeile formatieren
  row_spec(0, italic = T) |>
  # Fußnote
  footnote(
    general = "MW = Mittelwert, SD = Standardabweichung.",
    general_title = "Anm.:",
    footnote_as_chunk = T
  ) |>
  # Export
  save_kable("Tabellen/desc_wage1.tex")

9.1.2 Tabellen nach Word

Während kableExtra sehr gute Unterstützung bei der Erstellung von LaTeX- und HTML-Tabellen bietet, ist die Nutzung dieses Packages für Word-Tabellen umständlich. Tabellen müssen hier zuerst als HTML formatiert werden und können dann nach Word kopiert werden (siehe hier). Stattdessen verwenden wir das Package flextable. flextable folgt einer ähnlichen Pipe-basierten Logik wie kableExtra und lässt sich daher gut in bestehende tidyverse-Workflows integrieren.

Mit der Funktion flextable() erstellen wir eine Tabelle aus unserem tibble Objekt. Anschließend wenden wir verschiedene Funktionen aus dem flextable Package an, um die gewünschte Formatierung zu erhalten. Für Details siehe die die Online-Dokumentation des Packages. Anschließend exportieren wir die Tabelle mit save_as_docx(path = <DATEIPFAD>):

library(flextable)

tbl |>
  mutate(variable = c("Stundenlohn (USD)", "Bildungsjahre")) |>
  flextable() |>
  # Spaltenbezeichnungen
  set_header_labels(
    variable = " ",
    mean.insg = "MW",
    sd.insg = "SD",
    mean_1 = "MW",
    sd_1 = "SD",
    mean_0 = "MW",
    sd_0 = "SD"
  ) |>
  # Gruppierende Kopfzeile
  add_header_row(
    values  = c(" ", "Insgesamt", "Frauen", "Männer"),
    colwidths = c(1, 2, 2, 2)
  ) |>
  # Kopfzeilen formatieren
  bold(part = "header", i = 1) |>
  italic(part = "header", i = 2) |>
  # Zahlen runden
  colformat_double(digits = 2) |>
  # Spaltenausrichtung
  align(j = 1, align = "left", part = "all") |>
  align(j = 2:7, align = "center", part = "all") |>
  # Fußnote
  add_footer_lines("Anm.: MW = Mittelwert, SD = Standardabweichung.") |>
  # Caption
  set_caption("Lohn und Bildung im wage1-Datensatz") |>
  # Spaltenbreite automatisch anpassen
  autofit() |>
  # Export
  save_as_docx(path = "Tabellen/desc_wage1.docx")

Neben dem Export von Tabellen als Word-Datei unterstützt flextable außerdem den Export als RTF-Datei (save_as_rtf()) oder Powerpoint-Datei (save_as_pptx()).

9.1.3 Regressionstabellen

Um Ergebnisse von Regressionen nicht mühsam selbst als Tabelle formatieren zu müssen, stehen in R mehrere Packages zur Verfügung, die die Aufbereitung der Ergebnisse für uns vornehmen. In dieser Einführung verwenden wir das Package modelsummary, welches eine Vielzahl von Modellen unterstützt. Die mit modelsummary erstellten Tabellen sind außerdem mit den Funktionen von kableExtra und flextable adaptierbar.

Um die Verwendung von modelsummary zu illustrieren, verwenden wir die Regressionsmodelle aus Kapitel 8.1:

ols1 <- lm(wage ~ educ + exper + female, data = wage1)
ols2 <- lm(log(wage) ~ educ + exper + I(exper^2) + female, data = wage1)
ols3 <- lm(wage ~ educ * exper + female, data = wage1)

Mit modelsummary() können wir die Ergebnisse aller drei OLS-Modelle in einer Tabelle zusammenfassen:

library(modelsummary)

modelsummary(
  # Auflistung der Modelle
  models = list(
    "Modell 1" = ols1,
    "Modell 2" = ols2,
    "Modell 3" = ols3
  ),
  # Estimate-Zeile (Koeffizient + Sig.-Sterne)
  estimate = "{estimate} {stars}",
  # Statistikzeile (SE in Klammern)
  statistic = "({std.error})",
  # Signifikanzlevels
  stars = c("*" = 0.1, "**" = 0.05, "***" = 0.01),
  # Standardfehler-Typ
  vcov = "HC3",
  # Variablen + Labels
  coef_map = c(
    "educ" = "Bildungsjahre",
    "exper" = "Berufserfahrung",
    "tenure" = "Betriebszugehörigkeit",
    "female" = "Weiblich",
    "I(exper^2)" = "Berufserfahrung (quadr.)",
    "educ:exper" = "Bildung × Berufserfahrung"
  ),
  # Modellstatistiken + Labels
  gof_map = tibble(
    raw = c("nobs", "r.squared", "adj.r.squared"),
    clean = c("Beobachtungen", "R²", "Adj. R²"),
    fmt = c(0, 3, 3)
  ),
  # Fußnote
  notes = "Robuste Standardfehler in Klammern. * p < 0.1, ** p < 0.05, *** p < 0.01"
)
Tabelle 9.3
Modell 1 Modell 2 Modell 3
Robuste Standardfehler in Klammern. * p < 0.1, ** p < 0.05, *** p < 0.01
Bildungsjahre 0.603 *** 0.084 *** 0.504 ***
(0.065) (0.008) (0.093)
Berufserfahrung 0.064 *** 0.039 *** 0.008
(0.010) (0.005) (0.040)
Weiblich -2.156 *** -0.337 *** -2.194 ***
(0.260) (0.036) (0.272)
Berufserfahrung (quadr.) -0.001 ***
(0.000)
Bildung × Berufserfahrung 0.005
(0.004)
Beobachtungen 526 526 526
0.309 0.400 0.312
Adj. R² 0.305 0.395 0.307

Mit dem Argument output = "<DATEIPFAD>" in modelsummary() können wir diese Tabelle etwa als Word- oder LaTeX-Datei abspeichern. Für mehr Informationen, siehe die Online-Dokumentation des Packages oder ?modelsummary.

TippWeitere Möglichkeiten im modelsummary Package

Zusätzlich zur Erstellung von Regressionstabellen beinhaltet modelsummary auch Funktionen zum Erstellen von Tabellen mit deskriptiven Statistiken (datasummary()) sowie von Modellplots (modelplot()). Für weitere Informationen, siehe die Online-Dokumentation.

9.2 Grafiken exportieren

Das Exportieren von Grafiken ist in ggplot2 denkbar einfach: Die Funktion ggsave() speichert einen Plot direkt aus R in eine Datei, ohne dass das Grafik-Fenster in RStudio verwendet werden muss. Das hat den entscheidenden Vorteil, dass Größe, Auflösung und Format vollständig im Code festgelegt werden und der Export damit reproduzierbar ist — ein manuelles Speichern über das RStudio-Interface würde bei jedem Export potenziell zu leicht abweichenden Ergebnissen führen. ggsave() speichert per Default den zuletzt erstellten Plot. Über das Argument plot = ... kann aber auch ein gespeichertes Plot-Objekt übergeben werden, was bei der Arbeit mit mehreren Grafiken empfehlenswert ist:

p <- ggplot(
  data = wage1,
  aes(x = educ, y = wage, color = factor(female, labels = c("Männer", "Frauen")))
) +
  geom_point(alpha = 0.4) +
  geom_smooth(method = "lm") +
  labs(
    x     = "Bildungsjahre",
    y     = "Stundenlohn (USD)",
    color = NULL
  ) +
  theme_bw()

ggsave(
  filename = "grafik_lohn_bildung.png",
  plot = p,
  width = 18,
  height = 12,
  units = "cm",
  dpi = 300
)

Tabelle 9.4 gibt einen Überblick über die wichtigsten Argumente in ggsave():

Tabelle 9.4: Übersicht: Relevante Argumente in ggsave()
Argument Bedeutung
filename Dateipfad inkl. Endung — bestimmt das Format
plot Das zu speichernde Plot-Objekt (Default: letzter Plot)
width, height Breite und Höhe der Grafik
units Einheit: "cm", "mm", "in", "px"
dpi Auflösung (relevant für PNG/JPEG, nicht für PDF/SVG)
scale Skalierungsfaktor für Grafik inkl. Text und Elemente
bg Hintergrundfarbe (Default: "white")
TippWahl des Dateityps in ggsave()

Die Wahl des Dateiformats hängt vom Verwendungszweck ab. Grundsätzlich unterscheiden wir zwischen Vektorgrafiken, die verlustfrei skalierbar sind und deren Dateiendung im filename-Argument automatisch das Format bestimmt, und Rastergrafiken, die aus einer fixen Pixelmatrix bestehen:

  • PDF: Vektorgrafik — die erste Wahl für LaTeX-Dokumente und wissenschaftliche Paper, da sie in beliebiger Größe scharf bleibt und von den meisten LaTeX-Distributionen direkt eingebunden werden kann.
  • SVG: Vektorgrafik für Webseiten sowie zur Weiterbearbeitung in Vektorgrafik-Programmen wie Inkscape oder Adobe Illustrator.
  • PNG: Rastergrafik mit Transparenz-Unterstützung — gut geeignet für Word-Dokumente, Präsentationen und Webseiten. Mit dpi = 300 für Druckqualität.
  • JPEG: Rastergrafik ohne Transparenz — für Datenvisualisierungen wegen der verlustbehafteten Komprimierung meist weniger empfehlenswert.