Das Tidyverse

Wie im einleitenden Abschnitt über R beschrieben existieren viele Erweiterungen für R, manche davon erleichtern oder zumindest modifizieren die Arbeit mit R grundlegend. Eine davon ist das so genannte tidyverse, manchmal auch nach seinem Autor Hadley Wickham als Hadleyverse bezeichnet. Hadley Wickham ist einer der Protagonisten von RStudio und hat außerdem eine unglaublich gute sowie kostenlose Einführung in das Thema Data Science mit R geschrieben. DasTidyverse enthält mehrere Libraries:

  • ggplot2: Erweiterte Plotting-Möglichkeiten
  • dplyr: Eine beliebte Bibliothek zur Daten-Manipulation, die im Kurs ausführlicher besprochen wird
  • tidyr: Zum “Aufräumen” von Daten
  • readr: Zum Einlesen von Daten
  • purrr: Erweiterung der Funktionalen Programmierung in R
  • tibble: Eine moderne Version der Dataframes; wenn Sie das tidyverse laden, dann werden aus Ihren Dataframes automatisch Tibbles
  • stringr: Library zur Bearbeitung von Strings
  • forcats: Library zur Lösung von Problemen mit Factors

Im Kurs werden nicht alle Pakete behandelt. Es ist möglich, dass auch nur einzelne Libraries installiert werden, mit library(tidyverse) werden alle Libraries auf einmal installiert.

dplyr

Im Kurs werden wir uns vor allem mit dplyr beschäftigen (das wird wie dieplair ausgesprochen). Eine wunderbare Einführung gibt der Meister himself hier (bitte beachten, dass hier ein anderes Pipe-Symbol verwendet wird, siehe weiter unten):

dplyr verwendet 5 Haupt-Verben, mit denen grundlegende Befehle ausgeführt werden.

  • select: Zum Auswählen von Variablen
  • filter: Zum Auswählen von Zeilen
  • mutate: Zum Erzeugen von neuen Variablen/Spalten oder auch zum Verändern dieser
  • summarize: Ergebnisse berechnen (im Video sagt Hadley, dass zu einer Zeile reduziert wird, aber man kann auch mehrere Zeilen als Ergebnis haben)
  • arrange: Zum Sortieren von Zeilen

Ein weiterer wichtiger Punkt ist die so genannte Pipe. Unter UNIX sind Pipes ein beliebtes Mittel, um die Ausgabe aus einer Funktion als Input für eine andere Funktion zu nutzen, z.B.

grep '2018' bericht.csv | wc -l

In diesem Beispiel wird in der Datei bericht.csv nach allen Zeilen gesucht, in denen der String 2018 vorkommt.  Die Ausgabe wären dann genau diese Zeilen. Mit dem Operator | wird diese Ausgabe in den nächsten Befehl geleitet. wc -l zählt die Zeilen. Wir erfahren also mit diesem Befehl, wie viele Zeilen den String 2018 enthalten. Pipes sind ein sehr effizientes Mittel unter UNIX.

In dplyr wird anstatt des | der Operator %>% verwendet (früher %.% wie oben im Video zu sehen). Schauen wir uns ein Beispiel an, hierfür nehmen wir den Datensatz, der im Kurs zur Verfügung gestellt wird.

gadata %>%
filter(dimension2 == "pageview") %>%
group_by(pagePath) %>%
summarize(n = n()) %>%
arrange(desc(n))

Zunächst einmal “werfen” wir den ganzen Datensatz auf die nächste Funktion filter, die dann die Zeilen auswirft, die in der benutzerdefinierten Dimension 2 “pageview” enthält; wir wollen nur die Pageviews sehen.

Im nächsten Schritt gruppieren wir Zeilen; dies ist kein Standardverb wie oben beschrieben, aber äußerst nützlich. Es erfordert allerdings, einmal “um die Ecke” zu denken. In unserem Datensatz haben wir ja verschiedene Nutzer, die sich die Seiten auf der Homepage ansehen. Nicht jeder Nutzer wird jede Seite sehen, manche sehen dieselbe Seite, andere sehen sich andere Seiten an. group_by(pagePath) sagt ungefähr so etwas wie “gruppiere mir doch mal alle unterschiedlichen pagePaths, und dann gehen wir in den folgenden Schritten jede Gruppe einmal durch”. Da wir im nächsten Schritt summieren, passiert also folgendes: Für jede Seite bilde eine Gruppe, und dann zählen wir jede Gruppe einmal durch, also wie viele Elemente in der Gruppe sind, oder in diesem Fall wie häufig diese Seite vorkommt also aufgerufen wird. Einigermaßen verständlich wird das in diesem Video erklärt:

in summarize verwenden wir die Funktion n(), die alles zusammenzählt und schreiben das Ergebnis in die Variable n (wir hätten auch m oder y nehmen können). Im letzten Schritt wird das Ergebnis von summarize auf arrange geworfen, wo wir nichts anderes tun als n absteigend (desc) zu sortieren. Das Ergebnis ist eine Tabelle:

Diese wenigen Verben helfen uns also, Datensätze zu filtern, sortieren und zu manipulieren. Der besondere Vorteil von dyplr ist hier, dass es eine etwas einfachere Herangehensweise an R bietet.

gadata %>%
filter(!grepl("/amp/",pagePath)) %>%
filter(!grepl("\\?",pagePath)) %>%
mutate(dimension3 = as.numeric(dimension3)) %>%
group_by(dimension1,pagePath) %>%
mutate(time_spent = round((max(dimension3)-min(dimension3))/1000)) %>%
mutate(time_spent = round(time_spent/60),4) %>%
select(dimension1,pagePath,time_spent) %>%
unique() %>%
ungroup() %>%
select(pagePath,time_spent)

Das Ergebnis sieht wie folgt aus (hier habe ich Kommentare zu den Code-Zeilen hinzugefügt):