7 + 3
[1] 10
Die Software R wurde 1993 von Ross Ihaka und Robert Gentleman an der University of Auckland in Neuseeland entwickelt und wird heute von einer großen Community von Entwickler-/innen unterstützt. R bietet eine umfangreiche Sammlung von Paketen, die eine Vielzahl von Funktionen für die Datenanalyse und -visualisierung bereitstellen. Durch das Schreiben von Skripten können auch komplexe Datenanalysen durchgeführt und reproduziert werden. R beinhaltet eine schlicht gehaltene standardmäßige Benutzeroberfläche, die sich je nach Betriebssystem unterscheidet.
RStudio stellt eine alternative grafische Benutzeroberfläche für R bereit. Die Oberfläche bietet zusätzlich zur regulären Benutzeroberfläche von R ein Menüsystem an, welches die Navigation durch die verschiedenen Funktionen von R erleichtern soll. RStudio bietet zudem Funktionen wie Syntax-Hervorhebung, automatisierte Vervollständigung und Fehlerkorrektur, die das Schreiben von R-Code für Anwender/-innen vereinfachen.
WebR ist eine Browser-Version für die Software R. Sie ermöglicht, R-Code im Browser auszuführen, ohne dass die Software R auf dem Rechner installiert sein muss. Daher kann es auch auf Tablets und Smartphones verwendet werden. Alle Basisfunktionen aus R können auch in WebR angewendet werden. Beschränkungen existieren beim Installieren von Erweiterungspaketen, die zusätzliche Funktionen und beispielhafte Datensätze bereitstellen. In WebR lassen sich mittlerweile eine Vielzahl an Paketen installieren. Die hier in diesem Skript verwendeten Pakete lassen sich auch in WebR nutzen.
Auf der Seite https://cran.r-project.org/ kann die Software R für Linux, MacOS und Windows heruntergeladen werden. Die Installation variiert je nach Betriebssystem:
Für die Installation von RStudio muss R bereits installiert sein. Auf der Seite https://www.rstudio.com/products/rstudio/download/ kann die kostenlose Version heruntergeladen werden.
WebR muss nicht installiert werden. Die neueste Version kann auf der Seite https://webr.r-wasm.org/latest/ abgerufen werden.
Alle drei Benutzeroberflächen haben gemeinsam, dass ein Bereich für das Skript und ein Bereich für die Konsole zur Verfügung stehen. In der Konsole werden Befehle direkt ausgeführt. Im Skript lassen sich mehrere Befehle sammeln und anschließend gemeinsam ausführen. Außerdem lassen sich Skripte speichern und dadurch geschriebene Befehlsfolgen zu späteren Zeitpunkten wiederverwenden. Das Arbeiten mit R-Skripten und der R-Konsole ist keine Entweder-oder-Entscheidung. Die Kombination aus Skript und Konsole ermöglicht eine interaktive Skriptentwicklung, in der einzelne Abschnitte geschriebener Befehle immer wieder ausgeführt werden und die Ausgabe in der Konsole überprüft wird.
Im Skript werden mehrere Befehle durch Zeilenumbruch oder Semikolon getrennt. Kommentare lassen sich an einer beliebigen Stelle durch Eingabe von # setzen. Diese können hilfreich sein, um ein geschriebenes Befehlsskript zu einem späteren Zeitpunkt besser nachvollziehen zu können. Eingegebene Befehle werden in RStudio und WebR bei Windows mit Strg und Enter und bei macOs mit Cmd und Enter ausgeführt. In R werden Befehle bei Windows mit Strg und R und bei macOs mit Cmd und R ausgeführt. Zur Ausführung mehrerer Befehle müssen diese vorher markiert werden. Die Ausgabe erscheint in der Konsole. Zum Testen können wir den folgenden Code in einem Skript eingeben und die Ausgabe in der Konsole überprüfen:
7 + 3
[1] 10
Der grau hinterlegte Text zeigt den Bereich des R-Codes an. Wenn Sie bei Ihrem Endgerät den Mauszeiger oder bei einem Touchscreen Ihren Finger über die graue Fläche bewegen, können Sie den Code kopieren, um ihn direkt in die R-Konsole einzufügen. In diesem Dokument erscheint die Ausgabe direkt darunter. Die Zahl in den eckigen Klammern beschriftet die Zeile der Ausgabe. In diesem Fall wird das Ergebnis 10 ausgegeben.
Beim Schreiben von Code sind eine einheitliche und lesbare Struktur entscheidend, da sie das Verständnis und die Wartung erleichtern. Der tidyverse Style Guide bietet klare Empfehlungen, um eine konsistente und gut lesbare R-Code-Struktur zu gewährleisten. Weitere Informationen finden Sie unter: https://style.tidyverse.org.
In R wird beim Starten immer lediglich die Konsole angezeigt. Ein neues Skript lässt sich durch Klicken auf Datei Neues Skript öffnen. Anschließend öffnet sich ein neues Fenster für das Skript.
Auch beim erstmaligen Starten von RStudio muss zunächst ein Skript erstellt werden. Beim nächsten Start öffnet sich jedoch stets das zuletzt verwendete Skript. Ein neues Skript lässt sich durch Klicken auf File New File R Script öffnen. Anschließend befindet sich auf der linken Seite oben das Skript und unten die Konsole.
Im Gegensatz zur Benutzeroberfläche von R befinden sich auf der rechten Seite oben und unten weitere Tabs:
Dieser standardmäßige Aufbau der Oberfläche lässt sich über die Menüeinträge Tools Global Options an die eigenen Präferenzen anpassen. Unter anderem lässt sich hier variieren, wo die zuvor genannten Bereiche positioniert sind.
Die Benutzeroberfläche von WebR besteht aus 3 Bereichen. Oben links befindet sich das Skript, das zu Beginn bereits angezeigt wird. Unten links befindet sich die Konsole. Auf der rechten Seite lassen sich Dateien, wie beispielsweise Skripte oder Datensätze, hoch- und herunterladen. Außerdem lassen sich Dateien öffnen und löschen sowie neue Ordner erstellen.
Bevor Statistik betrieben werden kann, müssen Daten gesammelt und in R manuell eingegeben oder automatisiert eingelesen werden. Für Testzwecke können auch bereits in R vorhandene Datensätze geladen werden.
In R ist ein Vektor eine Datenstruktur mit geordneten Elementen des gleichen Datentyps. Zwei verschiedene Datentypen, wie Zahlen und Zeichenketten, können nicht gleichzeitig in einem Vektor enthalten sein. Die Elemente sind in einer festen Reihenfolge gespeichert und über ihre Indizes eindeutig adressierbar. Dies gewährleistet die Beibehaltung der Reihenfolge, was insbesondere bei Messdaten relevant ist. Beispielsweise können Messungen der Körpergröße mehrerer Probanden in einem Vektor gespeichert werden, wodurch die Zuordnung der Messwerte zu den jeweiligen Probanden konsistent bleibt.
Beispiel 2.1
Es liegt ein Datensatz zu dem Gewicht in Kilogramm von zehn Proband/-innen aus einer Untersuchung vor. Dieser Datensatz kann mit dem folgenden Befehl als ein Vektor definiert werden:
<- c(70, 89, 110, 45, 55, 67, 80, 63, 55, 91) gewicht
Dabei ist gewicht
die Bezeichnung des Vektors und frei wählbar. Der Pfeil ist der Zuweisungsoperator. Alternativ kann auch ein Gleichheitszeichen verwendet werden. Das c
steht für concatenate (deutsch: zusammenfügen). In RStudio wird der Vektor nach dem Anlegen im oberen rechten Fenster unter Environment angezeigt. An dieser Stelle ist außerdem zu erkennen, dass der Vektor als ein numerischer Datentyp gespeichert wurde.
In vielen Fällen werden bei einer Erhebung mehrere Variablen untersucht. Für derartige Datensätze eignet sich die Datenstruktur Dataframe. Hierunter wird eine matrixförmige Struktur verstanden, in der die einzelnen Spalten auch unterschiedlichen Typs sein können (Zahlen oder Zeichen). Ein Dataframe lässt sich am einfachsten erzeugen, indem zunächst die Werte der Spalten durch Vektoren definiert werden. Zeichenketten sind in Anführungszeichen zu setzen. Fehlende Merkmalsausprägungen einer Variablen sind mit NA
(not available, deutsch: nicht verfügbar) kenntlich zu machen.
Beispiel 2.2
Neben dem Gewicht wurde noch Alter und Geschlecht der Proband/-innen erhoben:
<- c(70, 89, 110, 45, 55, 67, 80, 63, 55, 91)
gewicht <- c(28, 39, 60, 54, 17, 60, 15, 25, 28, 19)
alter <- c("M", "M", "W", "W", "M", "W", "W", "M", "M", "W") geschlecht
In RStudio kann man unter dem Tab Environment nun beobachten, dass der Vektor geschlecht
mit dem Datentyp character
hinterlegt wurde. Diesen Datentyp verwendet R für Objekte, deren Werte Zeichenketten sind.
Die drei erzeugten Vektoren können zu einem Dataframe zusammengeführt werden. Dieser Dataframe wird in diesem Fall erhebung
genannt. Die einzelnen Vektoren bilden die Spalten des Dataframes:
<- data.frame(gewicht, alter, geschlecht) erhebung
Datensätze, die bereits in einer Datei abgespeichert sind, müssen nicht händisch eingegeben, sondern können eingelesen werden. Insbesondere für größere Datensätze spart dies Zeit. Für den Import einer lokal gespeicherten Textdatei muss zunächst das Working Directory (deutsch: Arbeitsverzeichnis) angepasst werden. Als Verzeichnis muss der Ort angegeben werden, an dem sich die jeweilige Textdatei befindet. Dies lässt sich mit der Funktion setwd()
realisieren. Innerhalb der Klammern muss der Pfad des Speicherorts der Quelldatei in Anführungszeichen eingegeben werden. Ein möglicher Befehl lautet: setwd("C:/Users/Mustermann/R")
. Benutzer/-innen des Betriebssystems Windows müssen beim Kopieren des Pfads gegebenenfalls die enthaltenen \
durch /
ersetzen.
Mithilfe der read.table()
-Funktion lassen sich Datensätze aus Textdateien im TXT- oder CSV-Format aus dem Arbeitsverzeichnis einlesen. In WebR müssen lokal gespeicherte Datensätze durch Upload file an der gewünschten Stelle hochgeladen werden.
Bei vorhandenen Datensätzen ist es wichtig, dass für jede Variable eine Spalte und für jedes Beobachtungsobjekt eine Zeile existiert, in der die Werte hinterlegt sind. Fehlende Werte sollten ausgelassen oder mit NA
kenntlich gemacht werden. Datensätze, die mit Programmen wie zum Beispiel Excel oder SPSS erstellt wurden, lassen sich als CSV-Dateien exportieren und dadurch auch mit der read.table()
-Funktion in R einlesen. Für einen fehlerfreien Import sollten einige grundlegende Argumente der Funktion berücksichtigt werden. In der Programmiersprache R ist es möglich, einem Befehl unterschiedliche Argumente zuzuweisen, um diesen genauer zu spezifizieren. Mehrere Argumente werden durch Kommata verbunden. Falls einzelne Argumente nicht explizit im Befehl festgelegt werden, greift R auf zuvor definierte Standardwerte zurück. Für den Befehl read.table()
wird mit header
kommuniziert, ob Spaltenüberschriften existieren. sep
kennzeichnet das verwendete Trennzeichen zwischen den einzelnen Merkmalsausprägungen und dec
das in der Datei verwendete Dezimaltrennzeichen. Ein potenzieller R-Befehl könnte so geschrieben werden: read.table ("Schockolinsen.CSV", header = TRUE, sep = ";", dec = ",")
.
In R befinden sich Datensätze, die geladen und verwendet werden können. Darüber hinaus existiert eine Vielzahl von Zusatzpaketen, welche die Basisfunktionen erweitern und weitere Datensätze bereitstellen. Für die Verwendung müssen die Pakete einmalig mit der Funktion install.packages()
installiert werden. Der Paketname wird in Anführungszeichen innerhalb der Klammern eingefügt. Das Paket muss dann für spätere Verwendungszwecke stets mit der Funktion library()
geladen werden.
Im Folgenden wird ein Zusatzpaket mit einem Datensatz vorgestellt, der für die Bearbeitung zukünftiger Aufgaben verwendet wird. Der penguins
Datensatz des palmerpenguins
Pakets enthält Größenmessungen für 344 Pinguine, die auf den Palmer-Inseln in der Antarktis beobachtet wurden (Horst, Hill, und Gorman 2020). Die Pinguine gehören zu den drei Arten: Chinstrap penguins (deutsch: Zügelpinguine), Gentoo penguins (deutsch: Eselspinguine) und Adélie penguins (deutsch: Adeliepinguine).
Zuerst installieren wir das Paket und laden es in die Bibliothek.
install.packages("palmerpenguins")
library(palmerpenguins)
Mit der Funktion head()
verschaffen wir uns einen Überblick über die ersten sechs Zeilen des Datensatzes penguins
.
head(penguins)
Die Funktion str()
gibt uns detaillierte Informationen über die erhobenen Merkmale. Der Name des Befehls steht für “structure” (deutsch: Struktur).
str(penguins)
tibble [344 × 8] (S3: tbl_df/tbl/data.frame)
$ species : Factor w/ 3 levels "Adelie","Chinstrap",..: 1 1 1 1 1 1 1 1 1 1 ...
$ island : Factor w/ 3 levels "Biscoe","Dream",..: 3 3 3 3 3 3 3 3 3 3 ...
$ bill_length_mm : num [1:344] 39.1 39.5 40.3 NA 36.7 39.3 38.9 39.2 34.1 42 ...
$ bill_depth_mm : num [1:344] 18.7 17.4 18 NA 19.3 20.6 17.8 19.6 18.1 20.2 ...
$ flipper_length_mm: int [1:344] 181 186 195 NA 193 190 181 195 193 190 ...
$ body_mass_g : int [1:344] 3750 3800 3250 NA 3450 3650 3625 4675 3475 4250 ...
$ sex : Factor w/ 2 levels "female","male": 2 1 1 NA 1 2 1 2 NA NA ...
$ year : int [1:344] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 ...
Wir sehen, dass vier metrisch skalierte, stetige Merkmale gemessen wurden:
bill_length_mm
),bill_depth_mm
),flipper_length_mm
),body_mass_g
).Außerdem wurden das Beobachtungsjahr (year
) sowie drei nominale Merkmale festgehalten:
species
) mit den Ausprägungen Adelie
, Chinstrap
und Gentoo
,island
) mit den Ausprägungen Biscoe
, Dream
und Torgersen
,sex
) mit den Ausprägungen female
und male
.Besonders bei größeren Datensätzen ist es oftmals nützlich oder erforderlich, Teilmengen des Datensatzes zu betrachten. Für das Definieren einer Teilmenge eines Datensatzes wird die subset()
-Funktion verwendet. Sollen nur bestimmte Variablen betrachtet werden, wird das Argument select
gesetzt. Innerhalb der Variablen können Operatoren gesetzt werden, um einzelne Beobachtungen auszuschließen. Eine Liste hilfreicher Operatoren ist in der folgenden Tabelle aufgeführt.
Operator | Restriktion |
---|---|
== |
Gleich |
!= |
Ungleich |
<= |
Kleiner oder gleich |
>= |
Größer oder gleich |
< |
Strikt kleiner |
> |
Strikt größer |
Die Operatoren lassen sich mit den logischen Verknüpfungen &
und |
verbinden. Dabei bedeutet &
zwischen zwei Operatoren, dass beide Restriktionen erfüllt sein müssen. Wenn mindestens eine Restriktion gegeben sein soll, ist die |
Verknüpfung zu wählen. ::: {#exm-RSkript}
Mithilfe der Operatoren kann beispielsweise die Teilmenge bestehend aus Pinguinen definiert werden, die auf der Dream-Insel leben und deren Schnabellängen mindestens 55 mm lang sind.
subset(penguins, island == "Dream" & bill_length_mm >= 55)
Möchte man die Anzahl dieser Pinguine bestimmen, kann die Funktion nrow()
verwendet werden.
nrow(subset(penguins, island == "Dream" & bill_length_mm >= 55))
[1] 2
:::
Bei einigen Pinguingattungen konnte empirisch belegt werden, dass die Männchen eine größere Schnabellänge haben als die Weibchen (Hocken 2002). Nun stellt sich die Frage, inwieweit dieses Merkmal auch auf die Palmerpinguine zutrifft. Für die Untersuchung dieser Frage sollen die folgenden Aufgabenstellungen bearbeitet werden.
Aufgabe 3.1
Wie viele Männchen und wie viele Weibchen enthält der Datensatz?
Aufgabe 3.2
Wie groß sind die Anteile der Weibchen und Männchen mit einer größeren Schnabellänge als 50 mm in der gesamten Stichprobe?
Falls Sie bei bestimmten Befehlen zusätzliche Unterstützung benötigen, können Sie die Funktion help()
verwenden, indem Sie den entsprechenden Befehl als Argument übergeben. Zum Beispiel:
help(mean)
Dadurch öffnet sich die R-Dokumentation, die hilfreiche Informationen zu den verfügbaren Argumenten und zur Nutzung des Befehls bereitstellt. Alternativ können Sie direkt über den folgenden Link auf die umfassende R-Dokumentation zugreifen: https://www.rdocumentation.org/.
Die Vielzahl an vorhandenen Befehlen bietet uns die Möglichkeit, einen umfassenden Überblick über unseren Datensatz zu gewinnen. In diesem Kapitel werden wir uns daher eingehend mit der praktischen Anwendung von R-Befehlen befassen.
In diesem Abschnitt wird anhand des penguins
Datensatzes das numerische Zusammenfassen von Daten erläutert. Es werden charakteristische Kenngrößen wie der arithmetische Mittelwert, Median, Quartile und Varianz für einzelne Variablen untersucht. Hierfür werden einige zentrale Funktionen in R vorgestellt.
Befehl | Kenngröße |
---|---|
mean() |
Arithmetischer Mittelwert |
median() |
Median |
var() |
Varianz |
sd() |
Standardabweichung |
sum() |
Wert der Summe aller Einträge |
prod() |
Wert des Produkts aller Einträge |
diff() |
Liste der Differenzen zwischen je zwei aufeinanderfolgenden Einträgen |
max() |
Größter Wert |
min() |
Kleinster Wert |
range() |
Liste mit größtem und kleinstem Wert |
which.max() |
Index des größten Werts |
which.min() |
Index des kleinsten Werts |
Bei den beiden Befehlen which.max()
und which.min()
werden, im Falle mehrerer Maxima oder Minima, die jeweils kleinsten Indizes ausgegeben.
Nicht jede statistische Größe lässt sich berechnen, wenn eine Variable mit fehlenden Merkmalsausprägungen vorliegt. Da der NA-Wert lediglich ein Platzhalter und kein tatsächlicher numerischer Wert ist, kann er in einige Berechnungen nicht einbezogen werden. Das Argument na.rm
teilt der zugrundeliegenden Funktion mit, diese Werte zu überspringen, wenn es auf TRUE
gesetzt wird.
Wenn Sie nur eine bestimmte Spalte innerhalb des Dataframes ansprechen möchten, können Sie das Symbol $
nutzen. Beispielsweise wird mit dem Befehl penguins$bill_length_mm
ein Vektor gebildet, der die Schnabellängen der Pinguine beinhaltet.
Beispiel 4.1
Mittels der vorgestellten Funktionen lassen sich erste Analysen an dem Pinguin-Datensatz vornehmen. Der Median der Schnabellängen könnte beispielsweise mit dem folgenden Befehl ermittelt werden.
median(penguins$bill_length_mm, na.rm = TRUE)
[1] 44.45
Nutzen Sie die kennengelernten Funktionen, um die folgenden Aufgabenstellungen zu lösen.
Aufgabe 4.1
Wie groß sind die arithmetischen Mittelwerte von den Schnabellängen der weiblichen und der männlichen Pinguine?
Aufgabe 4.2
Wie groß ist der Schnabellängenunterschied zwischen dem Pinguin mit dem kürzesten und dem längsten Schnabel?
Im Folgenden werden weitere Funktionen vorgestellt, die dabei helfen können, den Datensatz ausführlicher zu beschreiben. Ein wichtiges Werkzeug für die Beschreibung der Verteilung von Variablen ist die Quantilfunktion. In R ist die Quantilfunktion mit dem Befehl quantile()
implementiert, die es ermöglicht, verschiedene Typen von Quantilen zu berechnen. Es gibt insgesamt neun Typen von Quantilen, die mit dieser Funktion in R berechnet werden können. Jeder Typ verwendet eine andere Berechnungsmethode, was zu unterschiedlichen Ergebnissen führen kann. Die Wahl des Quantiltyps hängt von der Fragestellung ab und sollte daher sorgfältig ausgewählt werden. Im Folgenden wird Typ 2 ausführlicher dargestellt. Bei diesem werden das 25 %-, 50 %- und 75 %-Quantil mit den folgenden Formeln berechnet:
Q_{0.25}= \begin{cases}x_{\left(\left[\frac{n}{4}\right]+1\right)} & \text { falls } \frac{n}{4} \text { nicht ganzzahlig } \\ \frac{1}{2}\left(x_{\left(\frac{n}{4}\right)}+x_{\left(\frac{n}{4}+1\right)}\right) & \text { falls } \frac{n}{4} \text { ganzzahlig }\end{cases}
Q_{0.5}= \begin{cases}x_{\left(\frac{n+1}{2}\right)} & \text { falls } n \text { ungerade } \\ \frac{1}{2}\left(x_{\left(\frac{n}{2}\right)}+x_{\left(\frac{n}{2}+1\right)}\right) & \text { falls } n \text { gerade }\end{cases}
Q_{0.75}= \begin{cases}x_{\left(\left[\frac{3 n}{4}\right]+1\right)} & \text { falls } \frac{3 n}{4} \text { nicht ganzzahlig } \\ \frac{1}{2}\left(x_{\left(\frac{3 n}{4}\right)}+x_{\left(\frac{3 n}{4}+1\right)}\right) & \text { falls } \frac{3 n}{4} \text { ganzzahlig. }\end{cases}
Neben der quantile()
-Funktion eignet sich auch die summary()
-Funktion, um die Quantile eines Datensatzes zu bestimmen. Sie ist ein nützliches Werkzeug für das Zusammenfassen von Daten in einer übersichtlichen und leicht verständlichen Art. Die Funktion kann auf verschiedene Datentypen angewendet werden. Wird der summary()
-Befehl auf einen Vektor bestehend aus Zeichenketten angewendet, zählt die Funktion die Anzahl der Zeichenketten. Interessanter wird es, wenn die summary()
-Funktion auf einen numerischen Vektor trifft. Dann berechnet sie die statistischen Maße Minimum, 1. Quartil, Median, arithmetisches Mittelwert, 3. Quartil und Maximum. Dabei entsprechen das 1. Quartil dem 25%-Quantil, der Median dem 50 %-Quantil und das 3. Quartil dem 75%-Quantil. Außerdem wird die Anzahl fehlender Merkmalsausprägungen notiert. Die summary()
-Funktion kann auch auf Dataframes angewendet werden. In diesem Fall wird für jede Spalte im Dataframe eine separate Zusammenfassung generiert. Die Funktion berechnet dann für jede Spalte die gleichen statistischen Maße. Auch hier kann zwischen neun verschiedenen Typen gewählt werden, die sich in ihren Berechnungsvorschriften der Quantile unterscheiden. Im Gegensatz zur quantile()
-Funktion, bei der beispielsweise der Typ 2 mit dem Argument type = 2
gewählt wird, wird bei der summary()
-Funktion der Typ mit dem Argument quantile.type = 2
definiert.
Ein weiteres Maß für die Verteilung von Daten ist der Interquartilsabstand, der durch die Funktion IQR()
berechnet wird. Der Interquartilsabstand gibt an, wie weit die mittleren 50 % der Daten um den Median verteilt sind, indem er den Abstand zwischen dem 1. und dem 3. Quartil einer Verteilung misst. Der Interquartilsabstand ist robust gegenüber Ausreißern und daher eine nützliche Kenngröße für Datensätze bei denen ungewöhnlich große oder kleine Werte auftreten. Für eine konsistente Analyse sollte für die IQR()
-Funktion der gleiche Typ wie für die quantile()
-Funktion gesetzt werden. Dies geschieht hier mit dem Argument type = 2
.
Mittels der vorgestellten Funktionen lassen sich weitere Analysen an dem Datensatz vornehmen. Nutzen Sie die Funktionen, um die folgenden Aufgabenstellungen zu lösen.
Aufgabe 4.3
Bestimmen Sie die drei Quartile in der Verteilung der Schnabellängen, welche die Verteilung in vier Abschnitte einteilen.
Aufgabe 4.4
Bestimmen Sie den Interquartilsabstand in der Verteilung der Schnabellängen und interpretieren Sie das Ergebnis im Sachzusammenhang.
In diesem Abschnitt wird anhand des penguins
Datensatzes das grafische Zusammenfassen von Daten erläutert. Es werden die Darstellungsformen Säulendiagramm, Histogramm, Streudiagramm und Boxplot vorgestellt und erläutert, wie diese in R gezeichnet werden können. In diesem Skript wird hierfür auf das tidyverse
Paket zurückgegriffen. Dieses Paket beinhaltet mehrere R-Pakete, die Funktionen zur Datenaufbereitung und -visualisierung zur Verfügung stellen. Für die Installation und das Laden des Pakets müssen die folgenden Befehle ausgeführt werden.
install.packages("tidyverse")
library(tidyverse)
Von besonderer Relevanz ist das im tidyverse
enthaltene ggplot2
Paket. Im Gegensatz zu den bereits in R verfügbaren Funktionen basiert das ggplot2
Paket auf der Idee der “Grammar of Graphics”, die eine systematische Herangehensweise an die Erstellung von Visualisierungen fördert. Dies erleichtert das Verständnis und die Erstellung komplexer Diagramme, da die Syntax schnell komplex werden kann, wenn Sie mehrere Elemente hinzufügen oder anpassen möchten. Mit ggplot2
können Grafikelemente nicht nur durch das Setzen von Argumenten, sondern auch schichtenweise durch das Hinzufügen von Befehlen mit dem + Operator ergänzt werden.
Ein Säulendiagramm wird verwendet, um beobachtete Häufigkeiten der Ausprägungen eines diskreten Merkmals grafisch darzustellen. Die Säulen grenzen nicht aneinander und die Breite der Säulen hat keine inhaltliche Bedeutung. Um ein Säulendiagramm zu erstellen, beginnt man zunächst damit, die absoluten Häufigkeiten aller beobachteten Ausprägungen zu ermitteln. Anschließend werden für jede dieser Ausprägungen Säulen gezeichnet, deren Höhen den ermittelten Häufigkeiten entsprechen.
Als Beispiel visualisieren wir, wie viele Pinguine einer jeden Art beobachtet wurden. Da das Merkmal species
ein nominales Merkmal ist, eignet sich ein Säulendiagramm. Um ein Säulendiagramm mit ggplot2
zu zeichnen, beginnen wir mit ggplot()
und spezifizieren in dieser Funktion den Datensatz penguins
und bilden mit der Funktion aes()
das uns interessierende Merkmal species
auf die x
-Achse der Grafik ab. Dann erzeugen wir das Säulendiagramm mit geom_bar()
. Schließlich beschriften wir mit der Funktion labs()
die Achsen.
ggplot(penguins, aes(x = species)) +
geom_bar() +
labs(
x = "Art",
y = "Anzahl"
)
Wir sehen, dass Adeliepinguine am häufigsten beobachtet wurden, gefolgt von Eselspinguinen und Zügelpinguinen.
Um die Grafik ansprechender zu gestalten, färben wir die Säulen ein, indem wir zusätzlich das Merkmal fill
auf species
setzen. Dabei wählt ggplot2
automatisch ein geeignetes Farbschema aus. Wir legen aber mit scale_fill_manual()
ein eigenes Farbschema fest und assoziieren Adeliepinguine mit der Farbe darkorange
, Zügelpinguine mit purple
und Eselspinguine mit cyan4
, so wie in der Illustration von Allison Horst zu Beginn.
ggplot(penguins, aes(x = species, fill = species)) +
geom_bar() +
scale_fill_manual(values = c("darkorange", "purple", "cyan4")) +
labs(
x = "Art",
y = "Anzahl",
fill = "Art"
)
Es wird automatisch eine Legende erzeugt, die wir innerhalb von labs()
geeignet beschriften. Bei dieser Grafik ist die Legende nicht unbedingt nötig, da die Art bereits auf der x-Achse angegeben ist. Wir könnten sie innerhalb von geom_bar()
mit der Option show.legend = FALSE
ausschalten.
Aufgabe 4.5
Zeichnen Sie ein Säulendiagramm des Merkmals island
und beschriften Sie die Achsen sinnvoll. Beantworten Sie mithilfe der Grafik die Frage, auf welcher Insel die meisten Pinguine beobachtet wurden.
Aufgabe 4.6
Wie müssen Sie die Grafik aus Aufgabe 4.5 modifizieren, um anzugeben, auf welchen Inseln eine bestimmte Pinguinart beobachtet wurde?
Aufgabe 4.7
Erzeugen Sie die folgende Grafik. Welche Informationen können Sie ihr entnehmen?
Im Fall von metrisch skalierten Merkmalen eignet sich eher ein Histogramm als ein Säulendiagramm. Ein Histogramm besteht aus unmittelbar nebeneinander liegenden Rechtecken, deren Breiten den jeweiligen Klassen entsprechen. Man unterscheidet zwischen einem Histogramm absoluter und relativer Häufigkeiten. Dementsprechend symbolisieren die Rechtecke relative oder absolute Klassenhäufigkeiten. Die Höhe jedes Rechtecks stellt die relative oder absolute Häufigkeitsdichte dar. Sie wird berechnet, indem die relative oder absolute Häufigkeit durch die Breite der entsprechenden Klasse dividiert wird.
Ein Histogramm absoluter Häufigkeiten wird mit der Funktion geom_histogram()
gezeichnet. Standardmäßig wählt ggplot2
30 Intervalle. Je nach Datensatz kann das jedoch eine zu feine oder zu grobe Einteilung sein. Die genaue Intervallanzahl kann mit dem Argument bins
festgelegt werden. Alternativ kann die Intervallbreite mit dem Argument binwidth
angegeben werden. Im Folgenden definieren wir binwidth
durch eine Funktion, die in Abhängigkeit vom Datensatz den Quotienten aus der Spannweite der Daten und der Wurzel des Stichprobenumfangs berechnet. Dies entspricht der Faustregel K\approx\sqrt{n}.
ggplot(penguins, aes(x = body_mass_g)) +
geom_histogram(
binwidth = function(x) (max(x) - min(x)) / sqrt(length(x))
+
) labs(
x = "Körpergewicht (g)",
y = "Anzahl"
)
Indem wir zusätzlich für fill
das Merkmal species
setzen, können wir die artspezifische Verteilung der gemessenen Körpergewichte darstellen. Damit sich die artspezifischen Verteilungen nicht überlappen, ist es notwendig, die Histogramme nebeneinander zu zeichnen. Das erreichen wir mit der Funktion facet_wrap()
.
ggplot(penguins, aes(x = body_mass_g, fill = species)) +
geom_histogram(
binwidth = function(x) (max(x) - min(x)) / sqrt(length(x)),
show.legend = FALSE
+
) scale_fill_manual(values = c("darkorange", "purple", "cyan4")) +
labs(
x = "Körpergewicht (g)",
y = "Anzahl"
+
) facet_wrap(~species)
Aus der Grafik geht hervor, dass Eselspinguine deutlich schwerer sind als Zügel- und Adeliepinguine, deren Gewicht wiederum ungefähr im selben Bereich liegt.
Für ein Histogramm relativer Häufigkeiten müssen die Rechteckhöhen angepasst werden. Innerhalb der geom_histogram()
-Funktion kann mit aes()
die Zuordnung y = after_stat(density)
gesetzt werden. Dies sorgt nach der Berechnung der absoluten Häufigkeiten dafür, dass das Histogramm eine Gesamtfläche von eins aufweist und somit eine Approximation an die Dichte des Merkmals darstellt.
ggplot(penguins, aes(x = body_mass_g, fill = species)) +
geom_histogram(
aes(y = after_stat(density)),
binwidth = function(x) (max(x) - min(x)) / sqrt(length(x)),
show.legend = FALSE
+
) scale_fill_manual(values = c("darkorange", "purple", "cyan4")) +
labs(
x = "Körpergewicht (g)",
y = "Anzahl"
+
) facet_wrap(~species)
Aufgabe 4.8
Erstellen Sie ein Histogramm absoluter Häufigkeiten des Merkmals Schnabellänge mit verschiedenen Werten von binwidth
. Bei welchen Werten von binwidth
gibt Ihnen die Grafik einen guten Überblick über die Verteilung des Merkmals? Bei welchen Werten enthält die Grafik eher wenig Information?
Aufgabe 4.9
Erstellen Sie zur Visualisierung des Ergebnisses aus Aufgabe 4.1 zwei Histogramme relativer Häufigkeiten des Merkmals Schnabellänge nebeneinander. Das erste Histogramm soll ausschließlich Weibchen und das zweite Männchen enthalten. Nutzen Sie einen geeigneten Wert für binwidth
.
Mit einem Streudiagramm kann die Beziehung zwischen zwei quantitativen Merkmalen visualisiert werden. Dadurch kann auch eine Korrelation beider Merkmale deutlich werden. Zur Erstellung eines Streudiagramms wird in einem kartesischen Koordinatensystem das erste Merkmal auf die x-Achse und das zweite Merkmal auf die y-Achse abgebildet. Anschließend wird zu jeder Beobachtung das Wertepaar der Ausprägungen als Punkt in das Koordinatensystem eingetragen.
In ggplot2
zeichnen wir ein Streudiagramm mit der Funktion geom_point()
.
ggplot(penguins, aes(x = flipper_length_mm, y = bill_depth_mm)) +
geom_point() +
labs(
x = "Flossenlänge (mm)",
y = "Schnabeldicke (mm)"
)
Die Daten legen nahe, dass Pinguine mit großer Flossenlänge eine eher kleine Schnabeldicke besitzen und umgekehrt. Wir können mit geom_smooth()
eine sogenannte Regressionsgerade einzeichnen, die eine möglicherweise bestehende lineare Beziehung in den Daten visualisiert. Wir spezifizieren method = "lm"
als Abkürzung für lineares Modell. Standardmäßig wird um die Gerade zusätzlich ein sogenanntes Konfidenzband gezeichnet, das wir mit der Option se = FALSE
ausschalten.
ggplot(penguins, aes(x = flipper_length_mm, y = bill_depth_mm)) +
geom_point() +
geom_smooth(
method = "lm",
se = FALSE
+
) labs(
x = "Flossenlänge (mm)",
y = "Schnabeldicke (mm)"
)
Die monoton fallende Gerade deutet in der Tat auf eine negative Korrelation von Flossenlänge und Schnabeldicke hin.
In dem Streudiagramm zeichnen sich außerdem zwei Cluster ab. Wir können vermuten, dass die Pinguinart einen Einfluss darauf hat, in welchem Verhältnis Flossenlänge und Schnabeldicke zueinander stehen, also zu welchem Cluster eine Beobachtung gehört. Dazu setzen wir innerhalb von geom_point()
die Farbe color
und die Form der Punkte shape
auf das Merkmal species
.
ggplot(penguins, aes(x = flipper_length_mm, y = bill_depth_mm)) +
geom_point(aes(color = species, shape = species)) +
scale_color_manual(values = c("darkorange", "purple", "cyan4")) +
labs(
x = "Flossenlänge (mm)",
y = "Schnabeldicke (mm)",
color = "Art",
shape = "Art"
)
Es wird deutlich, dass die Eselspinguine ein eigenes Cluster bilden und sich in ihren Abmessungen von den Adelie- und Zügelpinguinen unterscheiden, die zusammen das andere Cluster bilden.
Auch erkennen wir, dass innerhalb einer Art eine längere Flosse typischerweise mit einem dickeren Schnabel einhergeht, im Gegensatz zur vorherigen Beobachtung ohne Berücksichtigung der Pinguinart. Wir zeichnen erneut eine Regressionsgerade ein, setzen nun aber innerhalb von geom_smooth()
color
auf das Merkmal species
, um für verschiedene Pinguinarten verschiedene Regressionsgeraden zu erhalten.
ggplot(penguins, aes(x = flipper_length_mm, y = bill_depth_mm)) +
geom_point(aes(color = species, shape = species)) +
geom_smooth(
aes(color = species),
method = "lm",
se = FALSE
+
) scale_color_manual(values = c("darkorange", "purple", "cyan4")) +
labs(
x = "Flossenlänge (mm)",
y = "Schnabeldicke (mm)",
color = "Art",
shape = "Art"
)
Alle drei Geraden sind monoton steigend. Wenn nach der Art unterschieden wird, sind Flossenlänge und Schnabeldicke also positiv korreliert. Dieses Beispiel veranschaulicht das Simpson-Paradoxon, da bei einer Gesamtbetrachtung der Pinguine über alle Arten hinweg eine negative Korrelation zu beobachten ist. Das Paradoxon tritt auf, wenn relevante Störvariablen, wie in diesem Fall die Pinguinart, nicht angemessen berücksichtigt werden. Dies unterstreicht die Bedeutung der Einbeziehung potenzieller Einflussfaktoren in statistische Analysen, um zu einer präzisen und umfassenden Interpretation der Daten zu gelangen.
Aufgabe 4.10
Zeichnen Sie ein Streudiagramm der Merkmale Körpergewicht und Flossenlänge. Stellen Sie dabei Datenpunkte von verschiedenen Pinguinarten durch verschiedene Farben und Formen dar. Welche Informationen können Sie dem Streudiagramm entnehmen?
Aufgabe 4.11
Erzeugen Sie die folgende Grafik.
Ein Boxplot stellt zusammenfassende Statistiken eines metrisch skalierten Merkmals grafisch dar. Diese zusammenfassenden Statistiken sind:
Es wird eine Box gezeichnet, deren Breite den Interquartilsabstand darstellt. Innerhalb der Box wird der Median durch eine dicke vertikale Linie eingetragen. Die Box gibt somit den Wertebereich an, in dem die mittleren 50 % der Daten liegen. Links und rechts der Box verlaufen horizontale Linien, die sogenannten Whisker, bis zum Minimum bzw. Maximum. Zusätzlich werden Ausreißer als separate Datenpunkte eingezeichnet. Dabei gilt eine Beobachtung als Ausreißer, wenn sie
Die Whisker verlaufen dann nur bis zur kleinsten bzw. größten Beobachtung, die kein Ausreißer ist.
In ggplot2
zeichnen wir einen Boxplot mit der Funktion geom_boxplot()
.
ggplot(penguins, aes(x = body_mass_g)) +
geom_boxplot() +
labs(x = "Körpergewicht (g)")
Die y-Achse wird automatisch mit einer Skala versehen, die jedoch nicht in Bezug zu den Daten steht, da das stetige Merkmal body_mass_g
lediglich auf der x-Achse aufgetragen ist.
Anstatt einen Boxplot für alle untersuchten Tiere zu zeichnen, wäre es interessanter, das Körpergewicht für jede Pinguinart separat darzustellen, um mögliche Unterschiede zwischen den Arten zu erkennen. Dazu bilden wir das nominale Merkmal species
auf y
ab und erhalten so für jede Art einen eigenen Boxplot.
ggplot(penguins, aes(x = body_mass_g, y = species)) +
geom_boxplot(
aes(color = species),
show.legend = FALSE
+
) scale_color_manual(values = c("darkorange", "purple", "cyan4")) +
labs(
x = "Körpergewicht (g)",
y = "Art"
)
Wir sehen, dass das Gewicht der Adelie- und Zügelpinguine ungefähr denselben Median aufweist, während Eselspinguine im Allgemeinen deutlich schwerer sind. Bei den Zügelpinguinen ist die Streuung der Daten am geringsten und es gibt zwei Ausreißer.
Aufgabe 4.12
Zeichnen Sie sowohl für männliche als auch für weibliche Pinguine einen Boxplot des Merkmals Flossenlänge. Was können Sie anhand der Grafik über die geschlechtsspezifische Länge der Flosse aussagen?
Die hier vorgestellten Lösungen stellen nur eine von vielen Möglichkeiten dar, die Aufgaben zu lösen. Es existieren in der Regel mehrere Berechnungsmöglichkeiten, die zu den richtigen Lösungen führen.
Lizenz
Die Lerneinheit “Einführung in R” wurde von Herold Dehling, Michael Kallweit, Daniel Meißner, Farhad Razeghpour und Katrin Rolka unter Mithilfe von Christian Müller an der Ruhr-Universität Bochum entwickelt. Es ist lizenziert unter der CC-BY-SA 4.0 Lizenz und ist verfügbar auf ORCA.nrw.