Skip to content
Snippets Groups Projects
tidyr-grammar.Rmd 16.82 KiB
title: "Datensätze zusammenführen"
subtitle: "Daten bändigen & visualisieren"
author: "B. Philipp Kleer"
date: "11. Oktober 2021"
output: 
  slidy_presentation:
      footer: "CC BY-SA 4.0, B. Philipp Kleer"
      slide_level: 3
      widescreen: true
      highlight: pygments
      theme: readable
      css: ./styles/style-slides.css
      df_print: paged
      mathjax: default
      self_contained: false
      incremental: false #True  dann jedes Bullet einzeln
      collapse: true # means the text output will be merged into the R source code block
library("knitr")
library("rmarkdown")
library("tidyverse")

uni <- readRDS("../datasets/uni.rds")
uni1 <- readRDS("../datasets/uni1.rds")
uni2 <- readRDS("../datasets/uni2.rds")
uni3 <- readRDS("../datasets/uni3.rds")
uni4 <- readRDS("../datasets/uni4.rds")
uniMacro <- readRDS("../datasets/unimacro.rds")
statclass <- readRDS("../datasets/statclass.rds")
statclass2 <- readRDS("../datasets/statclass2.rds")

points <- readRDS("../datasets/points.rds")
opts_chunk$set(fig.path = 'pics/s6-', # path for calculated figures
               fig.align = 'center',  # alignment of figure (also possible right, left, default)
               fig.show = 'hold', # how to show figures: hold -> direct at the end of code chunk; animate: all plots in an animation
               fig.width = 3,   # figure width
               fig.height = 4,  # figure height
               echo = TRUE,     # Code is printed
               eval = FALSE,    # Code is NOT evaluated
               warning = FALSE, # warnings are NOT displayed
               message = FALSE, # messages are NOT displayed
               size = "tiny",  # latex-size of code chunks
               background = "#E7E7E7", # background color of code chunks
               comment = "", # no hashtags before output
               options(width = 80),
               results = "markdown",
               rows.print = 15
)

htmltools::tagList(
  xaringanExtra::use_clipboard(
    button_text = "<i class=\"fa fa-clipboard\"></i>",
    success_text = "<i class=\"fa fa-check\" style=\"color: #90BE6D\"></i>",
    error_text = "<i class=\"fa fa-times-circle\" style=\"color: #F94144\"></i>"
  ),
  rmarkdown::html_dependency_font_awesome()
)

Tidyr und dplyr

Wenn wir mit Sekundärdaten arbeiten, sind diese oftmals bereits so vorbereitet, dass die Daten entweder im long- oder im wide-Format vorliegen. Wenn wir aber selbst Daten erheben oder z.B. über eine API laden, kann es sein, dass dies nicht der Fall ist. Auch kommt es vor, dass die Datenerhebung in Teilschritten erfolgt oder zum Beispiel Daten aus zwei verschiedenen Zeitpunkten für die Datenanalyse zusammengefügt werden sollen. Auch bei Multi-Level-Modellen werden oftmals Makrodaten mit Mikrodaten vor der Analyse verbunden.

Diese verschiedenen Varianten werden wir uns nun in tidyverse mithilfe von tidyr und dplyr anschauen.

Das Gerüst von Datensätzen mit tidyr

Es ist für die Verarbeitung wichtig, dass die Datensätz tidy sind, damit die Funktionen in R problemlos mit den Daten laufen. Das bedeutet, dass die Daten in einem bestimmten Format vorliegen müssen, damit die Funktionen in R auch gut mit den Daten funktionieren (weniger troubleshooting).

Was ist ein Datensatz? Ein Datensatz ist generell immer eine Sammlung von Werten, sei es numerisch oder eine Zeichenkette. Diese Werte sind immer auf zwei Arten organisiert: Jeder Wert gehört zu einer Variable und zu einer Beobachtung. Eine Variable inkludiert alle Werte, die für diese gemessen worden sind (also alle Beobachtungen auf dieser Variable). Eine Beobachtung inkludiert alle Werte, die für diese Beobachtung gemessen wurden (also alle Variablenwerte dieser Einheit).

Damit Daten in R gut mit den Funktionen genutzt werden können, müssen diese in einem tidy-Format vorliegen (auch long-Format genannt). Ein Datensatz ist dann tidy, wenn ...

  • ... jede Variable eine Spalte ist,
  • ... jede Beobachtung eine Zeile ist,
  • ... und jede Beobachtungseinheit eine Tabelle formt.

untidy data sets

Die folgenden zwei Datensätze zeigen Daten, die jeweils nicht tidy sind. Wir werden diese im Folgenden bereinigen.

statclass

Dieser Datensatz ist im sogenannten wide-Format. D.h. wenn wir neue Prüfungen hätten, würden wir einfach weitere Spalten hinzufügen. Dies ist aber für die Verarbeitung mit R teilweise problematisch, denn wir benötigen oft ein long-Format.

statclass2

In diesem Fall haben wir mehrere Probleme: Zum einen sind in den Spalten nicht überall Variablen, sondern Beobachtungen (momo, kim, sascha) und in exam finden wir wiederum Variablennamen.

Fangen wir mit statclass an.

Tidy-up statclass

In der Tabelle kann die Note jeder Person aus jeder Prüfung ausgelesen werden. Überlegt kurz, welche Variablen wir bei diesem Satz generieren möchten!

statclass
  • names: momo, sascha, kim
  • course: statI, statII, r, spss
  • grade: Wert in Abhängigkeit der zwei oberen.

Es sind also zwei Informationen in den Spalten stat1, stat2, r und spss. Nämlich welcher Test es ist (implizit über Variablenname) und die Note. D.h. hier sind Werte als Variablenname angegeben und das verstößt gegen die Regeln eines tidy Datensatzes. Wir benötigen in einem tidy-Format aber beide Informationen explizit! Denn die Spaltennamen sind hier Werte (Art der Prüfung) und nicht einfach Namen.

Um dies zu bereinigen, nutzt man pivot_longer(). Hierbei geben wir zuerst an, welche Spalten neugeordnet werden sollen (in unserem Fall stat1 bis spss), dann in welche neuen Variablen die Namen bzw. die Werte gespeichert werden sollen. Mit names_to benennen wir die neue Variable, die den Test unterscheidet und mit values_to benennen wir die Variable, die die Noten beinhaltet.

statclassTidy <- statclass %>% 
  pivot_longer(stat1:spss, 
               names_to = "course", 
               values_to = "grade"
               ) %>% 
  arrange(name,
          course
          )

statclassTidy

Jetzt haben wir ein long-Format, dass die Datenbearbeitung oft einfacher macht (z.B. mit ggplot2). Aber Aufpassen: Man kann jetzt nicht einfach mehr einen Mittelwert von grade berechnen, da dies verschiedene Kurse beinhaltet. Man muss dabei also Bedingungen setzen (wenn man im long-Format ist).

Möchte man dies wieder umkehren, nutzt man die Funktion pivot_wider():

statclassRe <- statclassTidy %>% 
  pivot_wider(names_from = course, 
              values_from = grade, 
              )

statclassRe

Tidy-up statclass2

Wo liegt hier das Problem?

statclass2