Zuerst müssen wir erneut tidyverse
laden, da wir eine
neue Session angefangen haben:
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
method from
print.tbl_lazy
print.tbl_sql
── Attaching packages ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.2 ──✔ ggplot2 3.3.6 ✔ purrr 0.3.4
✔ tibble 3.1.8 ✔ dplyr 1.0.10
✔ tidyr 1.2.1 ✔ stringr 1.4.1
✔ readr 2.1.3 ✔ forcats 0.5.2 ── Conflicts ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
Sie haben bereits Streudiagramme kennengelernt:
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy))
Hier sehen wir beispielsweise den Zusammenhang von Hubraum und dem Kraftstoffverbrauch von einigen Autos.
Die Fragestellung ist hierbei immer, wie die eine Variable von der anderen Variable abhängt.
In der Statistik gibt es ebenfalls eine Maßzahl, die uns diesen Zusammenhang angibt: der Korrelationskoeffizient.
cor(mpg$displ, mpg$hwy)
[1] -0.76602
Wir halten fest:
Das Streudiagramm zeigt einen absteigenden Trend. Wenn die Motorgröße (Hubraum) steigt, dann sinkt die Kraftstoffeffizienz tendenziell ebenfalls
Der Korrelationskoeffizient ist negativ und bestätigt unsere Beobachtung
ggplot
Es lassen sich bereits durch Aesthetics Daten auf Grund von
Kategorien visuell unterscheiden. So können wir in dem mpg
Datensatz die unterschiedlichen Autotypen hervorheben:
ggplot(data = mpg) +
geom_point(mapping = aes(x = hwy, y = displ, color = class))
Falls die einzelnen Kategorien getrennt betrachtet werden sollen,
werden facets
(Facetten/Gitter) verwendet.
Hierbei wird die Grafik für jede Kategorie in einem Gitter angezeigt.
Falls eine einzelne Kategorie betrachtet werden soll, wird ein weiterer
Layer mit der Funktion facet_wrap()
hinzugefügt.
Als erstes Argument wird eine formula
(ein spezielle
Datenstruktur) erwartet, bei der das Tilde-Symbol ~
gefolgt
von einem Variablennamen (unabhängige Variable/Kategorie) eingegeben
wird.
ggplot(data = mpg) +
geom_point(mapping = aes(x = hwy, y = displ)) +
facet_wrap(facets = ~ class, nrow = 2)
Falls mehrere Kategorien gleichzeitig betrachtet werden sollen, dann
wird ein Layer mit facet_grid()
benötigt.
Es lässt sich mit facet_grid()
ebenfalls eine Kategorie
betrachten, jedoch sieht dies meist weniger kompakt aus als
facet_wrap()
:
ggplot(data = mpg) +
geom_point(mapping = aes(x = hwy, y = displ)) +
facet_grid(facets = ~ class)
Um mehrere Kategorien gleichzeitig zu betrachten, wird bei
facet_grid()
ebenfalls eine formula
angegeben.
In diesem Fall besteht die formula
aus zwei Variablen;
eine Variable vor der Tilde und eine Variable nach der Tilde.
Falls die Kraftstoffeffizienz (hwy
) bezüglich des
Hubraums betrachtet werden soll, wobei für jeden Autotypen und jeden
Antriebstypen (Frontrad, Hinterrad, Vierrad) eine Grafik erstellt werden
soll, so muss in der formula
in facet_grid
drv ~ class
spezifiert werden:
ggplot(data = mpg) +
geom_point(mapping = aes(x = hwy, y = displ)) +
facet_grid(facets = drv ~ class)
ggplot
ObjekteEs ist ebenfalls möglich die Grafiken von ggplot
weiterzuverwenden, indem sie als Objekte gespeichert werden.
Jede Funktion von ggplot
liefert ein geometrisches
(geom
) Objekt zurück, mit dem weitergearbeitet werden kann.
Da es sich um geometrische Objekte handelt, entsprechen die Namen der
Funktionen von ggplot
dieser Namensgebung (z. B.
geom_point
für Streudiagramme oder geom_bar
für Balkendiagramme/Barplots).
Statt die gesamte Grafik in einem Schritt durch die Verkettung von
+
und das Hinzufügen von Layern zu erstellen, können die
Objekte/Grafiken auch zwischengespeichert werden:
<- ggplot(data = mpg)
graph1 graph1
<- graph1 + geom_point(mapping = aes(x = displ, y = hwy))
graph2 graph2
<- graph1 + geom_point(mapping = aes(x = displ, y = hwy, color = class))
graph3 graph3
+ geom_smooth(mapping = aes(x = displ, y = hwy), method = "loess", formula = y ~ x) graph2
Da sich in ggplot
die Layer Schritt für Schritt
hinzufügen lassen, können Sie so Ihren Code nach Bedarf besser
strukturieren oder wiederverwenden.
Abhängig von dem visuellen/geometrischen Objekt, welches verwendet wird, ändert sich die Darstellung, auch wenn dieselben Variablen verwendet werden:
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy))
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy))
Auf der einen Seite erhalten wir ein Streudiagramm von
hwy
und displ
und auf der anderen eine
Modell-Linie, die sich denselben Datenpunkten annähert.
Alle geom
Funktionen benötigen einen
mapping
Parameter, allerdings unterscheiden sich die
Aesthetics für jede Funktion.
So lässt sich beispielsweise nicht die Punktform der Linie von
geom_smooth
mit shape
verändern:
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy, shape = drv))
Warnung: Ignoring unknown aesthetics: shape
Die Linien werden für die Kategorien (Front, Hinter, Vierrad) gruppiert, allerdings ändern sich die Linien nicht.
Um die Aesthetic der Linien zu ändern, kann beispielsweise der
Linientyp mit linetype
verändert werden:
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy, linetype = drv))
Nun sehen wir für jeden Antriebstypen eine andere Linienart.
Um mehr über die Aesthetics einer geom
Funktion zu
erfahren, kann immer die Hilfsfunktion ?geom_smooth
(oder
eine Suchmaschine) zu Rat gezogen werden.
Selbstverständlich lassen sich die unterschiedlichen Layer der
geoms
auch übereinanderlegen. So können ebenfalls
Datenpunkte und Linien zugleich betrachtet werden:
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = drv)) +
geom_smooth(mapping = aes(linetype = drv, color = drv))
Sie sehen, dass die Linien die Datenpunkte für den entsprechenden
Antriebstyp drv
annähern.
Achten Sie vor allem auch auf die unterschiedlichen Aesthetics. In
der ggplot
Funktion werden die grundsätzliche Aesthetics
für die x-und y-Achse definiert (displ
und
hwy
). Diese Werte werden (global) übernommen und müssen in
den weiteren geom
Funktionen nicht geändert werden. Auf
diese Art muss nicht in jeder geom
Funktion die Aesthetics
neu definiert werden, sofern Sie keine anderen Variablen betrachten
wollen.
In geom_point
werden zusätzlich die Farben auf den
Antriebstyp drv
angepasst. Auch in geom_smooth
werden Farben und Linientyp auf den Antriebstyp drv
angepasst.
Ein gleichwertiger, aber wesentlich umständlicher Aufruf sähe wie folgt aus:
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(x = displ, y = hwy, color = drv)) +
geom_smooth(mapping = aes(x = displ, y = hwy, linetype = drv, color = drv))
Für weitere Beispiele, was mit ggplot
möglich ist,
schauen Sie in die tidyverse
Gallerie.
Für einen Spickzettel zu den geom
Funktionalitäten,
schauen Sie auf die offiziellen
Cheat-Sheets.
Standardmäßig wird mit ggplot
nur ein Objekt gezeichnet.
Um mehrere Objekte zeichnen zu lassen, muss die group
Aesthetic auf eine kategorische Variable gesetzt werden. In den meisten
Fällen wird das automatisch von ggplot
übernommen, z. B.
wenn die Farbe bezogen auf eine Kategorie geändert wird:
# Eine Linie
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy))
# Mehrere Linien gruppiert nach Antriebstyp
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy, group = drv))
# Automatische Gruppierung nach Antriebstyp durch color Aesthetic
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy, color = drv), show.legend = FALSE)
Durch die Aesthetics in mapping
jeder geom
Funktion lassen sich die globalen Aesthetics für den entsprechenden
Layer überschreiben oder erweitern:
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) + # Globale Aesthetics
geom_point(mapping = aes(color = class)) + # Lokale Aesthetics für das Streudiagramm
geom_smooth(fill = "red") # Lokale Aesthetics für die Linien
Sie sehen, dass die Farb-Aesthetics von geom_point
in
dem Layer von geom_smooth
nicht übernommen werden.
Ebenfalls sehen Sie, dass die fill
Aesthetic in
geom_smooth
eine andere Bedeutung hat als in
geom_point
. Mit fill
wird hierbei die Farbe
der Wolke (Konfidenzintervall) um die Linie verändert.
Somit können Sie jeden Layer beliebig gestalten.
Tatsächlich lassen sich auch in jedem Layer andere Datenpunkte darstellen oder hervorheben (z. B. durch Filterung).
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point() +
geom_point(data = filter(mpg, hwy > 30), color = "red") +
geom_smooth(se = FALSE) # ohne Konfidenzintervall
In diesem Beispiel wurden in einem geom_point
Layer die
Datenpunkte rot markiert, die einen Wert über 30 bei der
hwy
Variable aufweisen. Später wird die filter
Funktion weitergehend erläutert.
Eine weitere Graphenart ist das Balkendiagramm, welches die absoluten Häufigkeiten von Kategorien darstellt.
Das Balkendiagramm zeigt beispielsweise, dass die meisten erfassten Autos SUVs waren und nur wenige Zweisitzer oder Minivans:
ggplot(data = mpg, mapping = aes(x = class)) +
geom_bar()
Ein weiterer Aspekt fällt auf. Die y-Achse count
gibt
die Häufigkeiten an, obwohl dieses nicht als Variable in den Aesthetics
überliefert wurde.
Mit Hilfe statistischer Transformationen werden hier neue Daten “erzeugt”.
Weitere solche Grafiken umfassen:
Balkendiagramme und Histogramme
Vorhersagemodelle von geom_smooth
Boxplots
Die zugrundeliegende Mathematik/Statistik wird hierbei von
ggplot
übernommen und muss meistens nicht weiter
berücksichtigt werden.
In Einzelfällen ist dies notwendig (z. B. zum Darstellen von
relativen Häufigkeiten bei Balkendiagrammen) und wird durch
Spezifikation der stat
Funktionen von ggplot
übernommen. Details hierzu lassen wir an dieser Stelle aus.
Die Aesthetics fill
und color
haben
beziehen sich auch bei Balkendiagrammen auf die Füll- und
Randfarben:
ggplot(data = mpg) +
geom_bar(mapping = aes(x = class, color = class))
ggplot(data = mpg) +
geom_bar(mapping = aes(x = class, fill = class))
Die Häufigkeit von einer kategorischen Variable lässt sich auch anhand einer anderen kategorischen Variable aufteilen und übereinanderlegen, sofern Aesthetics entsprechend verwendet werden. So können wir auch die gemeinsamen Häufigkeiten der Autotypen und Antriebstypen betrachten.
ggplot(data = mpg) +
geom_bar(mapping = aes(x = class, fill = drv))
Das position
Argument von geom_bar
erlaubt
auch andere Arten, die Balken zu ordnen:
position = "identity"
überlappt die Balken (ohne
Stapeln). Hierbei sind Überlappungen ohne Transparenz nicht
einsehbar:ggplot(data = mpg) +
geom_bar(mapping = aes(x = class, fill = drv), position = "identity")
ggplot(data = mpg) +
geom_bar(mapping = aes(x = class, fill = drv), position = "identity", alpha = 0.2)
ggplot(data = mpg) +
geom_bar(mapping = aes(x = class, color = drv), position = "identity", fill = NA)
Lediglich wenn die Transparenz mit der Aesthetic alpha
angepasst wird oder die Füllfarbe fill
entfernt wird,
werden die einzelnen Balken sichtbar.
position = "fill"
stapelt die einzelnen Balken, jedoch
werden die Balkenhöhen auf 1 skaliert. Somit lassen sich die einzelnen
Kategorien besser vergleichen:ggplot(data = mpg) +
geom_bar(mapping = aes(x = class, fill = drv), position = "fill")
position = "dodge"
platziert die Balken der einzelnen
Kategorien nebeneinander. Somit lassen sich die Gruppierungen einer
Kategorie einfacher untereinander vergleichen:ggplot(data = mpg) +
geom_bar(mapping = aes(x = class, fill = drv), position = "dodge")
Auch bei Streudiagramme gibt es in geom_point
den
Parameter position
.
Dieser ist besonders dann nützlich, wenn beispielsweise nicht alle Datenpunkte in einer Grafik erkennbar sind.
In dem folgenden Streudiagramm sind nur ungefähr die Hälfte aller Datenpunkte sichtbar, da die andere Hälfte von ihnen überdeckt wird:
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy))
Durch zufälliges “Ruckeln” dieser Datenpunkte lassen sich die
verdeckten Datenpunkte sichtbar machen. Hierzu wird das Argument
position = "jitter"
in geom_point
gesetzt:
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy), position = "jitter")
Durch diese Transformation der Positionen der Datenpunkte wird die Grafik ungenauer, allerdings können so mehrere Datenpunkte aufgedeckt und der gesamte Trend besser betrachtet werden.
Alternativ lässt sich auch statt
geom_point(position = "jitter")
direkt
geom_jitter()
verwenden.
Weitere Information zu den Positionsanpassungen finden sich unter
?position_dodge
, ?position_fill
,
?position_identity
, ?position_jitter
und
?position_stack
.
Auch das Koordinatensystem lässt sich durch ggplot
ändern:
coord_flip()
: Wechsel der x- und y-Achse. Inbesondere
nützlich für lange Label oder längere Grafiken:ggplot(data = mpg, mapping = aes(x = class, y = hwy)) +
geom_boxplot()
ggplot(data = mpg, mapping = aes(x = class, y = hwy)) +
geom_boxplot() +
coord_flip()
ggplot(data = mpg, mapping = aes(x = displ)) +
geom_histogram(bins = 20)
ggplot(data = mpg, mapping = aes(x = displ)) +
geom_histogram(bins = 20) +
coord_flip()
coord_quickmap()
: Darstellung von Karten.<- map_data("nz")
nz ggplot(nz, aes(long, lat, group = group)) +
geom_polygon(fill = "white", colour = "black")
coord_polar()
: Verwendung von Polarkoordinaten.<- ggplot(data = mpg) +
bar geom_bar(mapping = aes(x = class, fill = class), width = 1) +
labs(x = NULL, y = NULL)
+ coord_flip() bar
+ coord_polar() bar
Anhand dieses Beispieles sehen Sie auch bereits, dass es weitere
Layer für die Anpassung der Label (labs
) gibt.
Sie haben bereits gesehen, dass sich in ggplot
aus
sieben Parametern alle grundlegenden Grafiken erstellen lassen.
Dazu zählt der Datensatz in ggplot()
, ein
geom
mit einem mapping
, einer Transformation
stat
, einer Position position
sowie einem
Koordinatenystem und einem Schema für die Facetten/Gitter.
Somit kann sich das Kochrezept erweitern auf:
ggplot(data = <DATA>) +
<GEOM_FUNCTION>(
mapping = aes(<MAPPINGS>),
stat = <STAT>,
position = <POSITION>
+
) <COORDINATE_FUNCTION> +
<FACET_FUNCTION>
So lässt sich das Erstellen von Grafiken auf folgende Schritte beschränken:
Datensatz auswählen
geom
auswählen (ggf. mit statistischer
Transformation stat
)
Optional: Aesthetics definieren
Optional: Koordinatensystem auswählen
Optional: facet
auswählen
Desweiteren lassen sich Skalierungen, Legenden, Label, usw. ebenfalls durch weitere Funktionen/Layer anpassen.
Neben den geoms
können auch weitere Layer hinzugefügt
werden, um beispielsweise die Legende, Label oder Überschrift zu
bearbeiten. Prinzipiell lassen sich alle Elemente der
ggplot
Grafiken manuell anpassen, sofern dies notwendig
ist.
Weitere Layer lassen sich nach Bedarf aus dem Spickzettel entnehmen:
labs()
: Ändere Label der Grafik:ggplot(data = mpg) +
geom_point(mapping = aes(x = hwy, y = displ, color = class)) +
labs(x = "Kraftstoffersparnis (Autobahnmeilen pro Gallone)", y = "Hubraum (in Liter)",
title = "Kraftstoffeffizienz von Autos der EPA")
annotate()
: Text/Elemente an einer bestimmten Position
einfügen:ggplot(data = mpg) +
geom_point(mapping = aes(x = hwy, y = displ, color = class)) +
annotate(geom = "text", x = 30, y = 5, label = "Text einfügen")
theme()
: Position der Legende:ggplot(data = mpg) +
geom_point(mapping = aes(x = hwy, y = displ, color = class)) +
theme(legend.position = "top") # oder "bottom", "left", "right"
xlim()
und ylim()
: Grafik auf einen
Bereich der x- oder y-Achse beschränken:ggplot(data = mpg) +
geom_point(mapping = aes(x = hwy, y = displ, color = class)) +
xlim(15, 25) +
ylim(3, 6)
Je nach Fragestellung oder Vorlieben lassen sich alle Elemente der Grafik anpassen. Der Aufbau der Grafik bleibt gleich und es können einfach weitere Layer hinzugefügt werden. Hierzu kann bei speziellen Anforderungen auf den Spickzettel geschaut werden oder bei einer Suchmaschine nachgeschlagen werden.
Für die Übungsaufgaben gehen wir zu dem diamonds
Datensatz über. Der Datensatz befasst sich mit Preis, Qualität und
weiteren Eigenschaften von knapp 54.000 Diamanten.
Zuerst geben wir wieder die folgenden Befehle ein, um die Bibliothek
tidyverse
zu laden und den Datensatz einzusehen:
library(tidyverse)
diamonds
Um mehr über den Datensatz zu erfahren, geben Sie wieder den
Hilfsbefehl ?diamonds
ein.
Erstellen Sie eine Grafik von den Variablen carat
und price
des diamonds
Datensatzes, wobei Sie
die Datenpunkte nach der Kategorie clarity
färben.
Erstellen Sie eine weitere Grafik von den Variablen
carat
und price
des diamonds
Datensatzes, wobei Sie ein facet
für die Kategorie
clarity
hinzufügen. Worin liegen die Vor- und Nachteile der
Farb-Aesthetics und der Nutzung von facets
?
Verwenden Sie nun als facet
eine kontinuierliche
Variable wie z. B. table
. Was passiert hier?
Verwenden Sie nun ein facet
mit zwei Variablen
cut
und clarity
, um die Variablen
carat
und price
zu vergleichen. Was können Sie
dieser Grafik entnehmen?
Erstellen Sie eine passende Grafik, um die Verteilungen von
cut
und price
darzustellen. Denken Sie auch an
passende Gruppierungen, Farben und Positionen!
Erstellen Sie die folgenden Grafiken:
cut
und fügen Sie ein facet
mit der Variable
clarity
ein.labs()
und verschieben Sie die Legende nach unten mit
theme()
.