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
ggplotEs 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:
graph1 <- ggplot(data = mpg)
graph1graph2 <- graph1 + geom_point(mapping = aes(x = displ, y = hwy))
graph2graph3 <- graph1 + geom_point(mapping = aes(x = displ, y = hwy, color = class))
graph3graph2 + geom_smooth(mapping = aes(x = displ, y = hwy), method = "loess", formula = y ~ x)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 LinienSie 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 KonfidenzintervallIn 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.nz <- map_data("nz")
ggplot(nz, aes(long, lat, group = group)) +
geom_polygon(fill = "white", colour = "black")coord_polar(): Verwendung von Polarkoordinaten.bar <- ggplot(data = mpg) +
geom_bar(mapping = aes(x = class, fill = class), width = 1) +
labs(x = NULL, y = NULL)
bar + coord_flip()bar + coord_polar()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)
diamondsUm 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:
Verschiedene Grafiken
cut
und fügen Sie ein facet mit der Variable
clarity ein.labs() und verschieben Sie die Legende nach unten mit
theme().