data > opinion

Tom Alby

01 Einführung in die Datenanalyse

2021-05-02


Was sind Daten?

Das Wort Daten stammt vom lateinischen Wort dare (geben, daher auch Datum als “gegeben am”), doch zunächst stand das Wort data für das Ergebnis einer Berechnung. Erst später wurde es auch als Bezeichnung für Messungen, Beobachtungen und Erhebungen genutzt.

DIKW Pyramide Quelle: Wikipedia, Attribution-Share Alike 4.0 International-Lizenz

In der DIKW-Pyramide (Data, Information, Knowledge, Wisdom) bilden Daten die Grundlage, sind aber nicht mit Informationen gleichzusetzen. Informationen werden aus Daten generiert, zum Beispiel dadurch, dass sie in Bezug gesetzt werden zu anderen Daten.

In der Statistik werden Daten in Bezug auf eine Grundgesamtheit oder Population interpretiert. Wird eine solche Population beziehungsweise eine Stichprobe (sample) aus einer Grundgesamtheit einmalig zu einem bestimmten Zeitpunkt untersucht, wird von einer Querschnittstudie (cross-sectional study) gesprochen. Im Gegensatz dazu steht eine Langzeitstudie beziehungsweise Längsschnittstudie, Englisch longitudinal study, bei der dieselbe Population beziehungsweise dieselbe Stichprobe mehrmals hintereinander in Zyklen untersucht wird. Für manche Studien sind auch nur Teile einer Grundgesamtheit von Interesse, zum Beispiel Jugendliche. In diesem Fall wird von einer Teilpopulation oder Teilgesamtheit gesprochen.

In einem Datensatz werden die einzelnen Elemente als statistische Einheit bezeichnet. Dies können Haushalte, Personen, Murmeln oder Eisbecher sein. In einer Befragung von Personen wird von Befragten oder Respondents gesprochen. Eine Befragung ist repräsentativ, wenn alle Befragten dieselbe Chance gehabt haben, an der Befragung teilnehmen zu können. Dem gegenüber steht das Oversampling, bei dem Gruppen von statistischen Einheiten häufiger in der Stichprobe vorhanden sind als in der Grundgesamtheit.

Bei der Befragung, Beobachtung oder dem Messen einr statistischen Einheit sind Merkmale, Features oder Variablen und ihre Ausprägungen bzw. Werte von Interesse. Statistische Einheiten werden daher auch manchmal als Merkmalsträger bezeichnet. Beispiel: Vor einem Wahllokal werden Menschen gefragt, welche Eiscreme sie am liebsten mögen. Die jeweilige Lieblingseiscreme eines Merkmalsträgers, zum Beispiel Pistazie, ist eine Merkmalsausprägung des Merkmals Eiscreme.

Datenanalyse in der Statistik und weiteren Disziplinen

Datenanalyse ist ein wesentlicher Teil der Statistik, der Lehre von Methoden zum Umgang mit quantitativen Daten. Die statistische Datenanalyse wird differenziert in die folgenden Teilbereiche:

Der explorativen Datenanalyse (häufig einfach nur als EDA bezeichnet) soll hier etwas mehr Beachtung geschenkt werden. Von Fahrmeir et al wird sie wie folgt beschrieben [@fahrmeir2011]:

Über die Darstellung von Daten hinaus ist [die explorative Datenanalyse] konzipiert zur Suche nach Strukturen und Besonderheiten in den Daten und kann so oft zu neuen Fragestellungen oder Hypothesen in den jeweiligen Anwendungen führen. Sie wird daher typischerweise eingesetzt, wenn die Fragestellung nicht genau definiert ist oder auch die Wahl eines geeigneten statistischen Modells unklar ist.

Es empfielt sich dennoch, zu Beginn mindestens eine Ausgangsfragestellung zunächst so klar wie möglich zu definieren und immer wieder zu dieser Ausgangsfragestellung zurückzukehren, bevor man sich in einer Analyse “verliert”. Gleichzeitig ist eine EDA auch eine Art “State of Mind”, wie es Hadley Wickham bezeichnet: jeder Idee, die einem kommt, soll nachgegangen werden im Analyse-Prozess. Es ist ein kreativer Prozess, so dass es auch ok ist, viele Fragen zu generieren. Denn das Schwierigste ist häufig, die richtigen Fragen an die Daten zu stellen [@wickham2017]:

Data exploration is the art of looking at your data, rapidly generating hypotheses, quickly testing them, then repeating again and again and again. The goal of data exploration is to generate many promising leads that you can later explore in more depth

“Erfunden” wurde die Explorative Datenanalyse von John W. Tukey in einem Artikel “The Future of Data Analysis”; sein Buch Exploratory Data Analysis gilt als Klassiker und Grundlage für das Thema Data Science. Eine EDA kann auch Elemente der deskriptiven und induktiven Statistik enthalten.

Der Begriff Statistiken bezieht sich auf Zusammenfassung oder Repräsentation analysierter Daten. Dies kann verwirrend sein, vor allem im Englischen, wenn von einer statistic besprochen wird, aber damit nicht das Gebiet der Statistik gemeint ist.

Machine Learning ist ein Teilbereich der Künstlichen Intelligenz, eine Schnittmenge mit Statistik ist vorhanden und formal undefiniert. Oberflächlich könnte gesagt werden, dass sich Statistik auf die Inferenz und Machine Learning auf die Vorhersage fokussiert, aber auch dieser Unterschied ist nicht eindeutig. In beiden Fällen ist Datenanalyse aber elementar.

Data Science ist kein offiziell definierter Begriff; in manchen Fällen ist auch der Unterschied zur Statistik nicht klar definiert. Statistik ist ein fester Teil von Data Science, wenngleich nicht alle Bereiche der Statistik benötigt werden. Ebenso ist Machine Learning ein Teil von Data Science. In der Literatur wird Data Science oft in Bezug auf einen Business Impact definiert, was auch Problemdefinition sowie Kommunikation und Bereitstellung eines Modells beinhaltet.

Ablauf einer Datenanalyse

CRISP-DM

Das Akronym steht für Cross-industry standard process for data mining, ist also eigentlich für Data Mining gedacht, dennoch aber auch für andere Anwendungsbereiche einsetzbar. Es ist, wie in der folgenden Abbildung zu sehen, kein Wasserfallmodell. Schritte können je nach Bedarf wiederholt werden.

Gartner

Das Analytics Ascendancy Model von Gartner aus dem Jahr 2012 unterscheidet die unterschiedlichen Fragestellungen der Analyse und referenziert auf die unterschiedlichen Facetten der statistischen Analyse (deskriptiv und induktiv).

Wickhams Modell

Das Modell von Hadley Wickham ist vor allem auf Data Science-Projekte gerichtet, ihm fehlen wie dem Modell von Gartner auch die Phase des Business Understandings. Dafür zeigt es aber wie das CRISP-DM-Modell, dass eine Analyse nicht unbedingt in einem Wasserfallmodell verläuft.

Was ist R?

R ist eine Umgebung zur statistischen Datenverarbeitung und gleichzeitig eine Programmiersprache. Sie wurde 1996 veröffentlicht und ist eine Open Source-Implementierung der Sprache S.

Im Gegensatz zu SPSS, das mittlerweile zu IBM gehört, ist R eine kostenlose Lösung. Ein weiterer Unterschied zu SPSS: R ist sozusagen “nackt”, es kommt nicht mit einer graphischen Benutzeroberfläche wie SPSS, bei der vieles mit ein paar Klicks abgehandelt werden kann.

Programme, die in R geschrieben sind, werden nicht kompiliert, es handelt sich bei R also um eine dynamische Programmiersprache, deren Anweisungen in Echtzeit interpretiert werden.

R “pur”

R pur ## Installation R

R kann von der R Project Website heruntergeladen werden. Sofern Sie danach gefragt werden, nutzen Sie bitte einen CRAN-Mirror, der Ihrem Standort am nächsten ist. Dann ist der Download-Link eventuell etwas versteckt:

Wählen Sie hier bitte die aktuelle Version, falls bereits eine neuere Version als die im Screenshot dargestellte existiert.

Nach dem Start begrüßt R den Nutzer mit einer Eingabeaufforderung, wie ein UNIX/Linux-Terminal oder die altehrwürdige DOS-Benutzeroberfläche. Einige Befehle können auch mit dem Menü ausgeführt werden, aber die meiste Zeit verbringt der Analyst hier mit der sogenannten Konsole. Befehl eingeben, Ausgabe ansehen. Dies ist die interaktive Art, R zu nutzen.

Möchte man ein längeres Programm schreiben, so ergibt es jedoch wenig Sinn, den Programm-Code jedes Mal neu einzugeben. Daher werden Programme meistens in Dateien geschrieben, zum Beispiel hello_world.R, und diese Dateien dann in der R-Konsole ausgeführt, nachdem sie geladen wurden. R selbst bietet einen einfachen Editor.

Die Entwicklungsumgebung RStudio

Das Download-Paket findet sich auf der RStudio Website.

Man kann RStudio entweder als Desktop-Applikation installieren oder auf einem Server. Für die Server-Installation existieren Amazon Machine Images von Louis Aslett. Für ein paar Euro im Monat kann man sich somit eine RStudio-Instanz gönnen, die von jedem Browser aus erreichbar ist. Somit kann man zum Beispiel eine Analyse starten, den Rechner zuklappen, und den Server weiterhin rechnen lassen.

Zwar ist R auch in RStudio immer noch “nackter” als SPSS, aber schon um einiges komfortabler als das komplett “nackte” R. RStudio kann als integrierte Entwicklungsumgebung (oder IDE für Integrated Development Environment) für R angesehen werden. Alle wichtigen Funktionen und Programme für die Entwicklung von Software oder das Handling von Daten sind über eine Schnittstelle bedienbar. Es findet sozusagen kein “Medienbruch” statt, da man nicht zwischendurch zum Dateibrowser oder zum Terminal wechseln muss. Wichtig: Es muss zunächst R installiert werden (siehe vorheriger Abschnitt), dann RStudio.

RStudio GUI

Nachdem R und RStudio installiert und gestartet ist, erscheint RStudio mit drei beziehungsweise vier Fenstern, deren Funktionen unterschiedlich konfiguriert werden können. Die vier Fenster in der Standardkonfiguration haben folgende Funktionen:

  • Links oben ist der eigene Code sowie der Inhalt von Data Frames zu finden (dieses Fenster ist nicht beim Start zu sehen, sondern erst wenn eine Code-Datei oder ein Data Frame geöffnet wird)
  • Rechts oben werden alle Objekte aufgeführt.
  • Links unten ist die R-Konsole (die man auch sehen würde, wenn man nur R nutzte und nicht RStudio dazu) sowie ein Terminal-Fenster (das direkten Zugriff auf das darunter liegende Betriebssystem erlaubt)
  • Rechts unten sind die Daten im Dateisystem sowie Plots und eine Hilfefunktion zu sehen

in dem folgenden Video kann ein Rundgang durch das RStudio-Interface angesehen werden:

Eine Besonderheit bei RStudio sind die Projekte. Wird ein Projekt angelegt, so wird automatisch ein Verzeichnis erstellt und beim Wechsel von einem Projekt zum nächsten auch der jeweilige Workspace geladen. Die Projekte finden sich ganz oben rechts. Es wird empfohlen, dass für diesen Kurs ein eigenes Projekt in RStudio angelegt wird.

RStudio bietet auch eine Cloud-Lösung an; zum jetzigen Zeitpunkt ist die Nutzung noch kostenlos.

R interaktiv

R kann wie ein Taschenrechner genutzt werden, indem Operationen in die Konsole eingegeben werden:

7 + 4
## [1] 11

Das Ergebnis einer solchen Operation kann in einer Variable gespeichert werden. Eine Variable ist eines der einfachsten Objekte in R. Als Objekt wird alles bezeichnet, das der Nutzer erstellt. Eine Variable ist wie ein Container, in dem ein Wert abgespeichert werden kann. Wird der Variable ein neuer Wert zugewiesen, so ist der alte Wert nicht mehr abrufbar. In dem folgenden Beispiel wird der Variable “ergebnis” das Ergebnis einer Rechenoperation zugewiesen:

ergebnis <- 7 + 4

Wird das Ergebnis einer Rechenoperation in einer Variable gespeichert, so können wir das Ergebnis nicht mehr sehen. Wir müssen den Variablennamen eingeben, um das Ergebnis sehen zu können:

ergebnis
## [1] 11

Das kann geändert werden, indem der Ausdruck in Klammern gesetzt wird:

(ergebnis <- 7 + 4)
## [1] 11

Bei R muss man Groß- und Kleinschreibung beachten:

(Ergebnis <- 7+5)
## [1] 12
(ergebnis <- 2+3)
## [1] 5
Ergebnis-ergebnis
## [1] 7

Bei der Wahl von Variablennamen sollte ein einheitlicher Ansatz gewählt werden, zum Beispiel camelCase (jedes Wort in einer Variable wird durch einen großen Anfangsbuchstaben markiert) oder snail_case (durch Unterstriche getrennt) oder durch Punkte getrennt (getrennt.durch.punkte). Nicht erlaubt ist ein -. Wie in dem vorherigen Beispiel zu sehen, wird das wie ein Minus-Zeichen behandelt. Auch ein Leerzeichen ist nicht möglich. Umlaute sind nicht möglich, funktionieren dann aber nicht unbedingt auf jedem System, was nachteilig ist, wenn man seinen Code an andere Nutzer weitergeben will.

Hinweise für besseres Programmieren

Code sollte immer kommentiert sein, auch wenn man als Programmierer gerne glaubt, dass der Code selbsterklärend sei. Spätestens aber, wenn man nach ein paar Monaten oder Jahren seinen Code noch mal öffnet, rächt sich das Fehlen von Kommentaren. Kommentare werden mit einem Hash gekennzeichnet, so dass Code darin nicht ausgeführt wird.

# Hier steht ein Kommentar
2*4+2
## [1] 10

Von Programmieren wird aber nicht nur erwartet, dass sie gegen ihre eigene Faulheit ankämpfen, sie werden dafür auch stark von R und RStudio unterstützt. Gibt man zum Beispiel nur “sum” ein und drückt dann die Tabulator-Taste, so machen sowohl R als auch RStudio Vorschläge. Nutzt man die Pfeiltasten nach oben und unten, so kann man vorherige Befehle sehen, die man eingegeben hat. Mit etwas Übung kann die Arbeit in R somit erheblich beschleunigt werden.

Ist ein Befehl nicht vollständig, dann wirft R netterweise keine Fehlermeldung aus, sondern zeigt durch das Zeichen “+”, dass man doch bitte noch etwas hinzufügen soll:

Wird Hilfe benötigt, so kann man auch einfach nur ein ? vor einen Befehl schreiben:

?summary

Datentypen

Bevor die Datentypen genauer erläutert werden, soll ein Blick auf die möglichen Unterscheidungen zwischen den Werten von Beobachtungen geworfen werden. Diese haben einen großen Einfluss auf die Wahl des Datentypen. Eine mögliche Unterscheidung sind Skalen:

  • Im oben genannten Beispiel der Eiscreme-Sorten sind die Daten kategorial bzw. nominalskaliert. Aus technischen Gründen werden solchen Kategorien manchmal Zahlen zugeordnet, was zu dem Trugschluss führen könnte, dass somit Rechenoperationen möglich wären, was aber nicht der Fall ist. So könnte der Eiscreme-Sorte Vanille eine 1 zugeordnet werden, der Sorte Erdbeer eine 2 und der Sorte Schokolade eine 3. Im Machine Learning wird häufig mit Distanzen in numerischen Werten gearbeitet, aber dies ist hier offensichtlich nicht möglich. Auch Postleitzahlen sind nominalskaliert, obwohl sie numerisch sind.
  • Ordinalskalierte Merkmale können zwar geordnet werden, ihre Abstände sind aber nicht interpretierbar. Beispiel: Eine Fußball-Mannschaft hat nach dem 1. Spieltag 3 Punkte, eine andere 1 Punkt. Das bedeutet aber nicht, dass die erste Mannschaft drei Mal besser ist.
  • Die Kardinalskala (auch metrische Skala) hingegen bietet die Möglichkeit der Interpretation der Abstände. Das Einkommen eines Fußballspielers kann mit dem eines Eiscreme-Verkäufers verglichen werden.
  • Eine besondere Form bildet die Intervallskala, die der Kardinalskala ähnlich ist, aber keinen sinnvollen Nullpunkt hat. Ein Beispiel hierfür ist der Geburtsjahrgang.

Eine andere Unterscheidung ist die der stetigen und diskreten Merkmale:

  • Diskrete Merkmale können nur endliche viele Merkmalsausprägungen annehmen, zum Beispiel die Anzahl der Zuschauer bei einem Konzert.
  • Stetige Merkmale können unendlich viele Merkmalsausprägungen eines Intervalls annehmen, zum Beispiel ein Wasserpegel.

In den bisherigen Beispielen wurden den Variablen ausschließlich Zahlen zugeordnet. In der Sprache R kann eine Variable jederzeit einen anderen Typ annehmen, in dem folgenden Beispiel wird x eine Zahl zugeordnet:

(x <- 4)
## [1] 4

Nun wird x eine Zeichenkette, häufig String genannt, zugeordnet:

(x <- "Hello World")
## [1] "Hello World"

Diese dynamische Typisierung, bei der der Variablentyp nicht vorab deklariert werden muss und die Variable jede Art von Typ annehmen kann, auch während des Programms, hat Vor- und Nachteile. Der Vorteil ist, dass man schnell mal etwas ändern kann, und der Nachteil ist, dass dieses “schnell mal etwas ändern” zu Fehlern führen kann.

Wird eine Zahl in Anführungszeichen gesetzt, dann passiert folgendes:

x <- "4"
str(x)
##  chr "4"

Die Zahl ist plötzlich keine Zahl mehr, sondern auch eine Zeichenkette. Mit dem Befehl “str” wird die Struktur eines Objekts angezeigt. An diesem Beispiel wird übrigens auch ein Prinzip von Befehlen in R deutlich: Einem Befehl folgen die Parameter, die in Klammern gesetzt sind. Dies ist die einfachste Möglichkeit, einen Befehl auszuführen.

Warum sind Datentypen überhaupt wichtig? Weil R wissen muss, was mit bestimmten Objekten gemacht werden kann und was nicht. Ein Beispiel hatten wir schon oben gesehen; sobald eine Zahl zum Character wird, kann sie nicht mehr zum Rechnen verwendet werden. R unterscheidet die folgenden Datentypen:

  • Numeric: Eine Zahl wie 1 oder 3,42 (tatsächlich wird in R auch noch zwischen Integern und Double unterschieden)
  • Character: Eine Zeichenkette
  • Logical: TRUE oder FALSE
  • Factor: Wird für kategoriale Variablen verwendet; dabei wird ein Integerwert gespeichert und jedem Integerwert zum Beispiel ein Character. Somit wird Speicher gespart. Postleitzahlen könnten von R als Numeric interpretiert werden, sollten aber den Typ Factor haben.

Schauen wir uns nun ein paar Operationen mit den Datentypen an:

str(x)
##  chr "4"
mode(x)
## [1] "character"

Der Datentyp kann jederzeit durch einen as.[gewünschter Datentyp] geändert werden, sofern die Operation unterstützt werden kann.

x_char <- as.character(x)
mode(x_char)
## [1] "character"

Ein Datum kann verschiedene Formen annehmen, zum Beispiel 1. Mai 2019 oder 01/05/2019 usw. In dem letzten Fall ist allerdings nicht unbedingt klar, ob es sich um den 1.5. oder den 5.1. handelt, denn in den USA wird erst der Monat genannt, dann der Tag. Ein solches Datumsformat hat aber auch den Nachteil, dass man es erst umwandeln muss, um damit Rechenoperationen durchzuführen, zum Beispiel wenn man wissen will, wie viele Tage zwischen dem 1. Mai und dem 27. April liegen. Eine Möglichkeit, um bequemer mit Datumsformaten zu arbeiten, ist der UNIX Timestamp, bei dem die Anzahl der Sekunden seit dem 1.1.1970 verwendet wird.

my_time <- 1561321833
str(my_time)
##  num 1.56e+09

Diese Zahl lässt sich umwandeln in ein richtiges Datum:

(my_date <- as.POSIXct(my_time, origin="1970-01-01"))
## [1] "2019-06-23 22:30:33 CEST"
str(my_date)
##  POSIXct[1:1], format: "2019-06-23 22:30:33"

Das Wissen über Datentypen ist auch deswegen wichtig, weil R beim Importieren selbst entscheidet, welchen Datentyp eine Variable hat, wenn es keine zusätzliche Spezifikation erhält. Mitunter führt dies zu Problemen, wenn die Daten nach dem Import dadurch nicht mehr richtig ausgewertet werden können. Siehe hierzu auch den Abschnitt über Datenimporte.

Vektoren

Vektoren sind nach den Variablen das nächsteinfachste Objekt in R. Sie sind eine eindimensionale Sammlung von Datenpunkten. Mit dem Befehl c() sagt man R, dass ein Vektor angelegt werden soll.

x <- c(1,2,3,4)
x
## [1] 1 2 3 4

Wie oben bereits erwähnt sind Programmierer faule Menschen, sie versuchen alles zu vereinfachen, was öfter getan werden muss, so dass dieser Vektor auch einfacher erstellt werden kann:

x <- c(1:4)
x
## [1] 1 2 3 4

Bei der Ausgabe verwundert eventuell die Zahl vor der Ausgabe. Sie gibt den Index-Wert des ersten Werts an. Jeder Wert erhält seine eigene Indexnummer. Anders als viele anderen Programmiersprachen wird bei R bei 1 angefangen zu zählen, nicht bei 0.

x <- c(1:100)
x
##   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18
##  [19]  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36
##  [37]  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54
##  [55]  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72
##  [73]  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
##  [91]  91  92  93  94  95  96  97  98  99 100

Vektoren können nur Daten des gleichen Typs enthalten.

x <- c(x,"Hallo Welt")
x
##   [1] "1"          "2"          "3"          "4"          "5"         
##   [6] "6"          "7"          "8"          "9"          "10"        
##  [11] "11"         "12"         "13"         "14"         "15"        
##  [16] "16"         "17"         "18"         "19"         "20"        
##  [21] "21"         "22"         "23"         "24"         "25"        
##  [26] "26"         "27"         "28"         "29"         "30"        
##  [31] "31"         "32"         "33"         "34"         "35"        
##  [36] "36"         "37"         "38"         "39"         "40"        
##  [41] "41"         "42"         "43"         "44"         "45"        
##  [46] "46"         "47"         "48"         "49"         "50"        
##  [51] "51"         "52"         "53"         "54"         "55"        
##  [56] "56"         "57"         "58"         "59"         "60"        
##  [61] "61"         "62"         "63"         "64"         "65"        
##  [66] "66"         "67"         "68"         "69"         "70"        
##  [71] "71"         "72"         "73"         "74"         "75"        
##  [76] "76"         "77"         "78"         "79"         "80"        
##  [81] "81"         "82"         "83"         "84"         "85"        
##  [86] "86"         "87"         "88"         "89"         "90"        
##  [91] "91"         "92"         "93"         "94"         "95"        
##  [96] "96"         "97"         "98"         "99"         "100"       
## [101] "Hallo Welt"

Aus den Zahlen sind auf einmal Zeichenketten geworden, allein dadurch, dass die Zeichenkette “Hallo Welt” angefügt wurde.

Listen

Listen sind eine Datenstruktur in R, die, anders als man sich üblicherweise eine Liste vorstellt, nicht nur aus einer Reihe von Werten bestehen können, sondern aus mehreren Reihen, die auch noch unterschiedliche Längen haben können. Dies ist bei einem Data Frame nicht möglich.

x <- c(1:4)
y <- c("1","2","3","4","5")
(my_list <- list(x,y))
## [[1]]
## [1] 1 2 3 4
## 
## [[2]]
## [1] "1" "2" "3" "4" "5"

Soll ein einzelner Wert aufgerufen werden, so müssen zwei Index-Werte angegeben werden:

my_list[[2]][2]
## [1] "2"

Wir werden mit Listen zunächst wenig zu tun haben.

Data Frames

Data Frames sind ein essentielles Konzept in R (und übrigens auch in Python). Ein Data Frame ist wie eine Art Excel-Tabelle, idealerweise mit Beobachtungen in den Zeilen und Variablen in den Spalten (es kann aber auch andere Formate geben). Um das zu verdeutlichen, schauen wir uns einen der Data Frames an, die in R bereits mitgeliefert werden:

mtcars
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

Mit str() können wir wieder die Struktur anzeigen lassen:

str(mtcars)
## 'data.frame':    32 obs. of  11 variables:
##  $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
##  $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
##  $ disp: num  160 160 108 258 360 ...
##  $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
##  $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
##  $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
##  $ qsec: num  16.5 17 18.6 19.4 17 ...
##  $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
##  $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
##  $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
##  $ carb: num  4 4 1 1 2 1 4 2 2 4 ...

Durch die Eingabe von head() werden die ersten Zeilen des Data Frames angezeigt:

head(mtcars)
##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

Der Befehl “summary” gibt mehrere Statistiken aus. Auf die Bedeutung der einzelnen Statistiken wird auf den nächsten Seiten eingegangen:

summary(mtcars)
##       mpg             cyl             disp             hp       
##  Min.   :10.40   Min.   :4.000   Min.   : 71.1   Min.   : 52.0  
##  1st Qu.:15.43   1st Qu.:4.000   1st Qu.:120.8   1st Qu.: 96.5  
##  Median :19.20   Median :6.000   Median :196.3   Median :123.0  
##  Mean   :20.09   Mean   :6.188   Mean   :230.7   Mean   :146.7  
##  3rd Qu.:22.80   3rd Qu.:8.000   3rd Qu.:326.0   3rd Qu.:180.0  
##  Max.   :33.90   Max.   :8.000   Max.   :472.0   Max.   :335.0  
##       drat             wt             qsec             vs        
##  Min.   :2.760   Min.   :1.513   Min.   :14.50   Min.   :0.0000  
##  1st Qu.:3.080   1st Qu.:2.581   1st Qu.:16.89   1st Qu.:0.0000  
##  Median :3.695   Median :3.325   Median :17.71   Median :0.0000  
##  Mean   :3.597   Mean   :3.217   Mean   :17.85   Mean   :0.4375  
##  3rd Qu.:3.920   3rd Qu.:3.610   3rd Qu.:18.90   3rd Qu.:1.0000  
##  Max.   :4.930   Max.   :5.424   Max.   :22.90   Max.   :1.0000  
##        am              gear            carb      
##  Min.   :0.0000   Min.   :3.000   Min.   :1.000  
##  1st Qu.:0.0000   1st Qu.:3.000   1st Qu.:2.000  
##  Median :0.0000   Median :4.000   Median :2.000  
##  Mean   :0.4062   Mean   :3.688   Mean   :2.812  
##  3rd Qu.:1.0000   3rd Qu.:4.000   3rd Qu.:4.000  
##  Max.   :1.0000   Max.   :5.000   Max.   :8.000

Mit diesem Data Frame können wir nun die ersten Analysen starten. Wollen wir nur eine Spalte untersuchen, so wird der Data Frame, ein Dollar-Zeichen und dann die Spalte genannt, die untersucht werden soll.

summary(mtcars$mpg)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   10.40   15.43   19.20   20.09   22.80   33.90

Daten einlesen

Daten werden meistens nicht mitgeliefert, sondern müssen von extern eingelesen werden. Hier werden nun zwei typische Fälle vorgestellt. Der erste Fall ist das Einlesen aus einer CSV-Datei. CSV steht für Comma Seperated Value, wobei das Komma irreführend ist. Es kann ebenso gut ein Semikolon sein oder ein Tab.

read.csv("data/mtcars.csv")
##                      X  mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1            Mazda RX4 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 2        Mazda RX4 Wag 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 3           Datsun 710 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 4       Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## 5    Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## 6              Valiant 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## 7           Duster 360 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## 8            Merc 240D 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 9             Merc 230 22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 10            Merc 280 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## 11           Merc 280C 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## 12          Merc 450SE 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## 13          Merc 450SL 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## 14         Merc 450SLC 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## 15  Cadillac Fleetwood 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## 16 Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## 17   Chrysler Imperial 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## 18            Fiat 128 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 19         Honda Civic 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 20      Toyota Corolla 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## 21       Toyota Corona 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## 22    Dodge Challenger 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## 23         AMC Javelin 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## 24          Camaro Z28 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## 25    Pontiac Firebird 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## 26           Fiat X1-9 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## 27       Porsche 914-2 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## 28        Lotus Europa 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## 29      Ford Pantera L 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## 30        Ferrari Dino 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## 31       Maserati Bora 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## 32          Volvo 142E 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

Manchmal ist es sinnvoll, sich eine Datei erst einmal anzusehen, um den Separator zu wissen:

head(readLines("data/mtcars.csv"))
## [1] "\"\",\"mpg\",\"cyl\",\"disp\",\"hp\",\"drat\",\"wt\",\"qsec\",\"vs\",\"am\",\"gear\",\"carb\""
## [2] "\"Mazda RX4\",21,6,160,110,3.9,2.62,16.46,0,1,4,4"                                            
## [3] "\"Mazda RX4 Wag\",21,6,160,110,3.9,2.875,17.02,0,1,4,4"                                       
## [4] "\"Datsun 710\",22.8,4,108,93,3.85,2.32,18.61,1,1,4,1"                                         
## [5] "\"Hornet 4 Drive\",21.4,6,258,110,3.08,3.215,19.44,1,0,3,1"                                   
## [6] "\"Hornet Sportabout\",18.7,8,360,175,3.15,3.44,17.02,0,0,3,2"

RStudio erleichtert das Einlesen von Dateien ungemein, aber auch hier ist das Verständnis von Separatoren wichtig. Hierzu wird im Dateibrowser von RStudio auf eine Datei geklickt, wo man sich dann entscheiden kann, ob man sich die Datei ansehen möchte oder ob sie importiert werden soll.

Das Dialogfenster bietet mehrere Funktionen:

  • Mit der Eingabe einer Zahl bei “Skip” kann die Anzahl von zu ignorierenden Zeilen spezifiziert werden
  • Manche Dateien haben keinen “Kopf”, der die Spalte beschreibt. Hier muss dann “First Row as Names” deaktiviert werden.
  • Bei dem Delimiter wird der Separator auswgewählt
  • Außerdem kann für jede Spalte einzeln bestimmt werden, um welchen Datentypen es sich handelt.

Die zweite Möglichkeit ist das Einlesen von einer URL. Sie funktioniert eigentlich genau so, nur dass anstatt eines Dateipfades eine URL angegeben wird.

Datenvisualisierung

Für eine erste Exploration der Daten eignet sich die Visualisierung, zum Beispiel von zwei Variablen:

plot(cars$speed, cars$dist)

In diesem Fall hätten die Spalten nicht ausgewählt werden müssen, weil der Datensätz nur zwei Spalten hat. Geht es um eine einzige Variable, so eignet sich ein Histogramm, auf das im Abschnitt über Verteilungen genauer eingegangen wird:

hist(cars$dist)

Sollen nur bestimmte Beobachtungen reinkommen, dann können diese wie folgt ausgewählt werden:

hist(cars$dist[cars$dist<100])

R und der Arbeitsspeicher

R lädt alle Daten in den Arbeitsspeicher, das heißt, dass man auf einem normalen Desktop-Rechner schnell an die Grenzen stoßen kann, wenn man mit großen Dateien arbeitet. Hat ein Rechner 8 GB Arbeitsspeicher, so benötigt das Betriebssystem selbst und alle offenen Programme bereits einen Teil des Arbeitsspeichers. Hat man noch 4GB von den 8GB über, so wäre es also theoretisch möglich, einen Datensatz von 4 GB zu nutzen. In der Realität aber ist das alles ein wenig komplizierter. Denn ein UNIX-System wie MacOS zum Beispiel lagert immer einen Teil des Arbeitsspeichers auf die Festplatte aus (“Swapping”), so dass im Prinzip die Grenze von 8 GB nicht ganz so hart sein muss. Andererseits bleibt es selten dabei, dass man nur mit dem einen Datensatz von 4GB arbeitet, denn für das Selektieren, Filtern und Mutieren wird zusätzlicher Speicher benötigt.

Es empfiehlt sich also, den Workspace immer aufzuräumen und zum Beispiel nicht mehr benötigte Objekte zu löschen. Dies geht zum Beispiel mit dem Befehl rm().

rm(y)

R speichert den Workspace, so dass es zu Problemen kommen kann, wenn R oder RStudio neu gestartet wird und ein Projekt geladen wird, das viel Arbeitsspeicher benötigt. Es empfiehlt sich aber auch, unter den Optionen von RStudio anzugeben, dass man .RData nicht beim Start laden soll.

Notebooks

In einem Notebook können Text wie zum Beispiel Fragestellungen und Beschreibungen eines Experiments, Software-Code sowie Daten und Ergebnisse in einem Dokument zusammen erfasst werden. Der Analyst schreibt zum Beispiel zunächst auf, was das Ziel der Analyse ist, dann wird Code geschrieben und das Ergebnis gleich in dem Dokument berechnet. Dadurch, dass alles zusammen in einem Dokument ist, können Vorgehensweise und Software von anderen Analysten nachvollzogen und Analysen einfacher ausgetauscht werden. Notebooks eignen sich hervorragend für explorative Datenanalysen.

In einem Notebook kann in einem Code-Block ein Befehl eingegeben werden. Wird ein neues Notebook erstellt, so ist immer bereits ein Stück Code drin:

plot(women)

Unter dem Code-Block entsteht dann direkt der Plot, der dann im weiteren Fließtext weiter beschrieben werden kann. So folgt ein Teil der Analyse dem anderen, und es ergibt sich ein nachvollziehbarer Gang durch die Gedanken des Analysten.

Die Notebooks in RStudio erlauben nicht nur das Einfügen von R-Code, sondern auch die Nutzung anderer Sprachen wie Python. In einem Dokument können also Code-Stücke verschiedener Sprachen genutzt werden und untereinander Daten austauschen. Im folgenden Video wird die Erstellung eines Notebooks genauer beschrieben.

Unter Windows kann ein R-Code-Snippet über Strg-Alt-I angelegt werden, auf dem Mac ist es Command-Option-I.

Packages und Libraries

Der Funktionsumfang von R wird durch sogenannte Packages erweitert. Ein Package wurde schon zum Einlesen von Daten verwendet, readr. Dies muss einmal installiert sein (zum Beispiel über den Befehl install.packages(“readr”) ) und muss dann vor der Verwendung im Code einmalig geladen werden.

Markdown

Notebooks können in andere Formate exportiert werden, zum Beispiel in HTML-Seiten oder ein PDF-Dokument. So ist wie in der Einleitung beschrieben auch diese Unterlage in R geschrieben worden. Mit Markdown können spezifische Befehle verwendet werden, um die Formatierung zu verändern, HTML-Links einzufügen und so weiter. Ein Beispiel für eine Explorative Datenanalyse, die mit einem Notebook und Markdown entstanden ist, findet sich hier.