Einführung in R

Autor:in

Farhad Razeghpour, Herold Dehling, Michael Kallweit, Daniel Meißner, Christian Müller, Katrin Rolka

Zusammenfassung
Dieses Skript bietet Ihnen eine praxisnahe Einführung in die Anwendung von R. Mithilfe theoretischer Erklärungen, praktischer Beispiele und Aufgaben lernen Sie, R für die Verarbeitung, Visualisierung und Interpretation von Daten einzusetzen. Dabei erwerben Sie eine solide Grundlage, um R als ein Werkzeug zur Analyse und Auswertung von Daten in Ihrem Studium nutzen zu können. Die praxisnahen Beispiele und Aufgaben tragen dazu bei, Ihr Verständnis und Ihre praktischen Fertigkeiten im Umgang mit R zu fördern. Während der Bearbeitung der Aufgaben haben Sie die Möglichkeit, zwischen der Verwendung der eigentlichen Programmiersprache R, der Entwicklungsumgebung RStudio und der webbasierten Plattform WebR zu wählen. Diese Auswahlmöglichkeiten ermöglichen es Ihnen, die Vor- und Nachteile jeder Variante kennenzulernen und Ihr bevorzugtes Tool individuell auszuwählen. Zu einigen Aufgaben finden Sie direkt unterhalb hilfreiche Tipps, die Sie bei Bedarf aufklappen können. Zum Abschluss des Skripts finden Sie umfassende Lösungen für alle gestellten Aufgaben.

1 Was ist R, RStudio und WebR?

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.

1.1 Installation

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:

  • Linux: Den Link für Linux mit der passenden Distribution auswählen.
  • macOS: Den Link für macOS und anschließend die neueste Version auswählen.
  • Windows: Den Link für Windows auswählen, anschließend Base anklicken und dann die neueste Version herunterladen.

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.

1.2 Benutzeroberflächen

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.

1.2.1 Benutzeroberfläche von R

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.

Benutzeroberfläche von R Version 4.3.2 unter Windows

Benutzeroberfläche von R-Version 4.3.2 unter Windows

1.2.2 Benutzeroberfläche von RStudio

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.

Benutzeroberfläche von RStudio Version 2023.12.1 unter macOS

Benutzeroberfläche von RStudio Version 2023.12.1 unter macOS

Im Gegensatz zur Benutzeroberfläche von R befinden sich auf der rechten Seite oben und unten weitere Tabs:

  • Environment: Anzeige von zuvor definierten Datensätzen und Variablen
  • History: Protokoll über verwendete Befehle
  • Viewer: Anzeige von lokalen Webinhalten
  • Files: Navigation von Dateien auf der Festplatte
  • Plots: Anzeige von erstellten Plots
  • Packages: Installation von zusätzlichen Paketen
  • Help: Informationen zu den Befehlen in R

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.

1.2.3 Benutzeroberfläche von WebR

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.

Benutzeroberfläche von WebR Version 0.2.3

Benutzeroberfläche von WebR Version 0.2.3

2 Wie bekomme ich meine Daten in R hinein?

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.

2.1 Manuelle Eingabe

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:

    gewicht <- c(70, 89, 110, 45, 55, 67, 80, 63, 55, 91)


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:

    gewicht <- c(70, 89, 110, 45, 55, 67, 80, 63, 55, 91)
    alter <- c(28, 39, 60, 54, 17, 60, 15, 25, 28, 19)
    geschlecht <- c("M", "M", "W", "W", "M", "W", "W", "M", "M", "W")


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:

erhebung <- data.frame(gewicht, alter, geschlecht)


2.2 Automatisiertes Einlesen

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 = ",").

2.3 Datensätze aus R

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.

3 Erste Befehle anhand eines Datensatzes

3.1 Die Palmerpinguine

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).

Illustration dreier Pinguinarten auf dem Palmer-Archipel: Zügelpinguin, Eselspinguin und Adeliepinguin.

Werk von Allison Horst unter CC0 Lizenz

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:

  • die Schnabellänge in mm (bill_length_mm),
  • die Schnabeldicke in mm (bill_depth_mm),
  • die Flossenlänge in mm (flipper_length_mm),
  • das Körpergewicht in g (body_mass_g).

Erklärung der Messung von Schnabellänge und Schnabeldicke bei einem Pinguin.

Werk von Allison Horst unter CC0 Lizenz

Außerdem wurden das Beobachtungsjahr (year) sowie drei nominale Merkmale festgehalten:

  • die Pinguinart (species) mit den Ausprägungen Adelie, Chinstrap und Gentoo,
  • die Insel (island) mit den Ausprägungen Biscoe, Dream und Torgersen,
  • das Geschlecht (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?

Mit dem Befehl nrow(penguins) können Sie die Anzahl der Pinguine zählen. Kombinieren Sie diesen Befehl mit dem subset()-Befehl.


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?


3.2 Hilfe in R

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/.

4 Datenanalyse mit R

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.

4.1 Datenanalyse durch numerische Zusammenfassungen

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?

Definieren Sie zunächst die Vektoren der männlichen und die der weiblichen Pinguine.


Aufgabe 4.2
Wie groß ist der Schnabellängenunterschied zwischen dem Pinguin mit dem kürzesten und dem längsten Schnabel?

Versuchen Sie die diff() und die range() Funktion zu kombinieren.


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.


4.2 Datenanalyse durch grafische Zusammenfassungen

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.

4.2.1 Säulendiagramm

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.

Ändern Sie im Beispielcode das Merkmal, das auf x abgebildet wird. Passen Sie in der Funktion labs() die Achsenbeschriftung an den neuen Plot an.


Aufgabe 4.6
Wie müssen Sie die Grafik aus Aufgabe 4.5 modifizieren, um anzugeben, auf welchen Inseln eine bestimmte Pinguinart beobachtet wurde?

Die Pinguinart können Sie über die Füllfarbe darstellen.


Aufgabe 4.7
Erzeugen Sie die folgende Grafik. Welche Informationen können Sie ihr entnehmen?

Bei einigen Pinguinen konnte das Geschlecht nicht bestimmt werden, der Datensatz enthält daher fehlende Einträge NA. Diese detektieren wir mit einer Kombination aus den beiden Funktionen filter() und is.na():

  filter(penguins, is.na(sex))

NA wird von geom_bar() als weitere Ausprägung aufgefasst und in einer eigenen Säule geplottet. Jedoch möchten wir nur den Teil des Datensatzes plotten, der keine NAs und somit inhaltlich relevante Angaben enthält. Wir müssen penguins also erst entsprechend filtern, bevor wir die Daten an ggplot2 übergeben.

  ggplot(filter(penguins, !is.na(sex)))

Der logische Negationsoperator ! sorgt dafür, dass alle NA Einträge entfernt werden. Vervollständigen Sie nun diesen Code, um den gewünschten Plot zu erstellen.


4.2.2 Histogramm

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?

Ändern Sie im Beispielcode das Merkmal, das auf x abgebildet wird. Passen Sie in der Funktion labs() die Achsenbeschriftung an den neuen Plot an. Probieren Sie in geom_histogram() verschiedene Werte für das Argument binwidth aus.


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.

Orientieren Sie sich erneut an der Faustregel, den Wertebereich in ungefähr \sqrt{n} Intervalle einzuteilen. Nutzen Sie daher binwidth = 1.5. Nutzen Sie den subset Befehl, um Pinguine aus dem Datensatz zu entfernen, deren Geschlecht nicht bekannt ist.


4.2.3 Streudiagramm

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?

Ändern Sie im Beispielcode die Merkmale, die auf x und y abgebildet werden. Passen Sie in der Funktion labs() die Achsenbeschriftung an den neuen Plot an.


Aufgabe 4.11
Erzeugen Sie die folgende Grafik.

Wie unterscheidet sich diese Grafik von derjenigen aus Aufgabe 1? Worauf müssen Sie die Variable bill_depth_mm abbilden?


4.2.4 Boxplot

Ein Boxplot stellt zusammenfassende Statistiken eines metrisch skalierten Merkmals grafisch dar. Diese zusammenfassenden Statistiken sind:

  • das Minimum,
  • das 25%-Quantil,
  • der Median,
  • das 75%-Quantil,
  • das Maximum.

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

  • um mehr als das 1.5-fache des IQR größer ist als das 75%-Quantil oder
  • um mehr als das 1.5-fache des IQR kleiner ist als das 25%-Quantil.

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?

Verwenden Sie zunächst die Funktion filter() zusammen mit is.na(), um fehlende Einträge aus dem Datensatz zu entfernen. Ändern Sie im Beispielcode die Merkmale, die auf x und y abgebildet werden. Passen Sie in der Funktion labs() die Achsenbeschriftung an den neuen Plot an.


Lösungen zu den Aufgaben

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.

nrow(subset(penguins, sex == "male"))
[1] 168
nrow(subset(penguins, sex == "female"))
[1] 165

Zurück zu Aufgabe 3.1

nrow(subset(penguins, sex == "male" &  bill_length_mm>50)) / 344
[1] 0.1337209
nrow(subset(penguins, sex == "female" &  bill_length_mm>50)) / 344
[1] 0.01744186

Zurück zu Aufgabe 3.2

Pinguine_M <- subset(penguins, sex == "male")
mean(Pinguine_M$bill_length_mm, na.rm = TRUE)
[1] 45.85476
Pinguine_W <- subset(penguins, sex == "female")
mean(Pinguine_W$bill_length_mm, na.rm = TRUE)
[1] 42.09697

Zurück zu Aufgabe 4.1

diff(range(penguins$bill_length_mm, na.rm = TRUE))
[1] 27.5

Zurück zu Aufgabe 4.2

summary(penguins$bill_length_mm, quantile.type = 2)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
  32.10   39.20   44.45   43.92   48.50   59.60       2 

Daraus folgt: Q_{0.25} = 29.2, Q_{0.5} = 44.45, Q_{0.75} = 48.5

Zurück zu Aufgabe 4.3

IQR(penguins$bill_length_mm, type = 2, na.rm = TRUE)
[1] 9.3

Ein Interquartilsabstand von 9,3 mm bedeutet, dass die mittleren 50 % der Schnabellängen der Pinguine maximal 9,3 mm voneinander abweichen.

Zurück zu Aufgabe 4.4

Ein Säulendiagramm des Merkmals island erhalten wir mit dem folgenden Code.

ggplot(penguins, aes(x = island)) +
  geom_bar() +
  labs(
    x = "Insel",
    y = "Anzahl"
  )

Die meisten Pinguine wurden somit auf den Biscoe-Inseln gesichtet.

Zurück zu Aufgabe 4.5

Um weiter nach der Pinguinart zu unterscheiden, setzen wir fill auf species und legen manuell ein Farbschema fest.

ggplot(penguins, aes(x = island, fill = species)) +
  geom_bar() +
  scale_fill_manual(values = c("darkorange", "purple", "cyan4")) +
  labs(
    x = "Insel",
    y = "Anzahl",
    fill = "Art"
  )

Wir sehen, dass Adeliepinguine auf allen drei Inseln vorkamen, während Zügelpinguine nur auf Dream Island und Eselspinguine nur auf den Biscoe-Inseln zu finden waren.

Zurück zu Aufgabe 4.6

Zuerst filtern wir alle Beobachtungen heraus, bei denen das Merkmal sex den Wert NA hat. Anschließend zeichnen wir wie gewohnt ein Säulendiagramm, wobei wir die Säulen nach den Ausprägungen von island farbig füllen. Das Farbschema wird von ggplot2 automatisch gewählt.

  ggplot(filter(penguins, !is.na(sex)), aes(x = sex, fill = island)) +
  geom_bar() +
  labs(
    x = "Geschlecht",
    y = "Anzahl",
    fill = "Insel"
  )

Wir sehen, dass der Datensatz ungefähr gleich viele weibliche wie männliche Tiere enthält, wobei auf den Biscoe-Inseln etwas mehr männliche als weibliche Tiere beobachtet wurden.

Zurück zu Aufgabe 4.7

Zuerst schauen wir uns mit der Funktion range() an, in welchem Wertebereich die Beobachtungen liegen. Dabei entfernen wir mit na.rm = TRUE alle fehlenden Einträge, da das Ergebnis sonst ebenfalls NA wäre.

range(penguins$bill_length_mm, na.rm = TRUE)
[1] 32.1 59.6

Der erste Wert ist das Minimum, der zweite das Maximum. Die Spannweite beträgt somit 27,5 mm. Wir wählen zunächst eine Intervalllänge von 5 mm, setzen also binwidth = 5.

ggplot(penguins, aes(x = bill_length_mm)) +
  geom_histogram(binwidth = 5) +
  labs(
    x = "Schnabellänge (mm)",
    y = "Anzahl"
  )

Diese Einteilung ist offenbar zu grob. Wir erkennen kaum eine Struktur in der zugrunde liegenden Verteilung, da die meisten Werte in lediglich vier Intervalle fallen.

Als Nächstes wählen wir daher eine deutlich kleinere Intervallbreite, beispielsweise binwidth = 0.25.

ggplot(penguins, aes(x = bill_length_mm)) +
  geom_histogram(binwidth = 0.25) +
  labs(
    x = "Schnabellänge (mm)",
    y = "Anzahl"
  )

Diese Einteilung wiederum erscheint zu fein. In viele Intervalle fallen weniger als fünf Beobachtungen und insbesondere an den Rändern gibt es deutliche Lücken. Damit lässt sich kaum eine zuverlässige Aussage über die Verteilung der Daten machen.

Wir versuchen es mit einem eher mittleren Wert und orientieren uns an der Faustregel, den Wertebereich in ungefähr \sqrt{n} Intervalle einzuteilen, wobei n der Stichprobenumfang ist. Dabei dürfen wir NA Einträge nicht miteinbeziehen. Wir überprüfen zunächst, ob es tatsächlich fehlende Einträge gibt.

  filter(penguins, is.na(bill_length_mm))

Von den 344 Beobachtungen in penguins bleiben damit 342 übrig. Wegen 27.5 / \sqrt{342} \approx 1.5 wählen wir also binwidth = 1.5.

ggplot(penguins, aes(x = bill_length_mm)) +
  geom_histogram(binwidth = 1.5) +
  labs(
    x = "Schnabellänge (mm)",
    y = "Anzahl"
  )

Diese Grafik gibt uns einen vergleichsweise guten Überblick über die Daten. Unter anderem erkennen wir eine bimodale Verteilung, was aus der ersten Grafik gar nicht und aus der zweiten nur annähernd ersichtlich war. Eine bimodale Verteilung ist durch zwei ausgeprägte Maxima charakterisiert.

Zurück zu Aufgabe 4.8

Wir orientieren uns an der Faustregel, den Wertebereich in ungefähr \sqrt{n} Intervalle einzuteilen. Daher nutzen wir erneut binwidth = 1.5. fill setzen wir diesmal nicht auf species, sondern auf sex. Die Farbwahl für die Rechtecke lassen wir von R automatisch vornehmen. Mithilfe des subset Befehls entfernen wir alle Pinguine aus unserem Datensatz, dessen Geschlecht wir nicht kennen.

ggplot(subset(penguins, !is.na(sex)), aes(x = bill_length_mm, fill = sex)) +
  geom_histogram(
    aes(y = after_stat(density)),
    binwidth = function(x) (max(x) - min(x)) / sqrt(length(x)),
    show.legend = FALSE
  ) +
  labs(
    x = "Geschlecht",
    y = "Anzahl"
  ) +
  facet_wrap(~sex)

Zurück zu Aufgabe 4.9

Wir ändern lediglich die Zuordnung zu x und y sowie die Achsenbeschriftung, um das gewünschte Streudiagramm zu erhalten.

ggplot(penguins, aes(x = body_mass_g, y = flipper_length_mm)) +
  geom_point(aes(color = species, shape = species)) +
  scale_color_manual(values = c("darkorange", "purple", "cyan4")) +
  labs(
    x = "Körpergewicht (g)",
    y = "Flossenlänge (mm)",
    color = "Art",
    shape = "Art"
  )

Wir erkennen, dass Körpergewicht und Flossenlänge sowohl innerhalb einer Art als auch artübergreifend positiv korreliert sind. Außerdem sind zwei Cluster zu sehen. Einen davon bilden die Eselspinguine, die typischerweise schwerer sind und eine längere Flosse haben als Adelie- und Zügelpinguine. Diese wiederum bilden zusammen das zweite Cluster.

Zurück zu Aufgabe 4.10

Die Farbe der Datenpunkte wird nicht wie bisher durch das nominale Merkmal species bestimmt, sondern durch das stetige Merkmal bill_depth_mm. Wir spezifizieren diese Zuordnung innerhalb von geom_point(), müssen allerdings kein manuelles Farbschema festlegen, da ggplot2 automatisch eine kontinuierliche Farbskala wählt.

ggplot(penguins, aes(x = body_mass_g, y = flipper_length_mm)) +
  geom_point(aes(color = bill_depth_mm)) +
  labs(
    x = "Körpergewicht (g)",
    y = "Flossenlänge (mm)",
    color = "Schnabeldicke (mm)",
  )

Zurück zu Aufgabe 4.11

Wir entfernen zunächst alle NA Einträge aus dem Datensatz und zeichnen dann den Boxplot.

  ggplot(filter(penguins, !is.na(sex)), aes(x = flipper_length_mm, y = sex)) +
  geom_boxplot() + 
  labs(
    x = "Flossenlänge (mm)",
    y = "Geschlecht"
  )

Es ist deutlich zu erkennen, dass männliche Pinguine im Allgemeinen eine längere Flosse besitzen als weibliche Pinguine.

Zurück zu Aufgabe 4.12

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.

Literatur

Hocken, A. G. 2002. Post-mortem examination of penguins. Department of Conservation.
Horst, Allison Marie, Alison Hill, und Kristen B. Gorman. 2020. palmerpenguins: Palmer Archipelago (Antarctica) penguin data. https://doi.org/10.5281/zenodo.3960218.

Wiederverwendung