Geoms mit statistischen Berechnungen (Transformationen)

Mehrere geometrische Objekte (engl. geoms) verfügen über integrierte Funktionen für statistische Transformationen und Berechnungen. In mehreren vorangegangenen Kapiteln haben wir geom_smooth() vorgestellt, das den Zusammenhang zwischen x und y berechnet und visualisiert. Die Funktion geom_smooth() besitzt das Argument method, das auf "loess" gesetzt werden kann, um eine flexible Regressionslinie zu erzeugen, oder auf "lm", wodurch eine lineare Regressionslinie erzeugt wird. Dasselbe Prinzip gilt für zahlreiche weitere Geoms: Sie führen Berechnungen durch, um Daten zu visualisieren.

In diesem Kapitel verwenden wir Daten aus gapminder, um zu zeigen, wie Transformationen funktionieren. Zunächst laden wir das Package gapminder und sehen uns die ersten 10 Zeilen an. Die Daten lassen sich unter anderem mit der Funktion head() inspizieren.

library(gapminder)
head(gapminder, 10)
country <fctr> continent <fctr> year <int> lifeExp <dbl> pop <int> gdpPercap <dbl>
Afghanistan Asia 1952 28.801 8425333 779.4453
Afghanistan Asia 1957 30.332 9240934 820.8530
Afghanistan Asia 1962 31.997 10267083 853.1007
Afghanistan Asia 1967 34.020 11537966 836.1971
Afghanistan Asia 1972 36.088 13079460 739.9811
Afghanistan Asia 1977 38.438 14880372 786.1134
Afghanistan Asia 1982 39.854 12881816 978.0114
Afghanistan Asia 1987 40.822 13867957 852.3959
Afghanistan Asia 1992 41.674 16317921 649.3414
Afghanistan Asia 1997 41.763 22227415 635.3414

Anschließend erstellen wir ein Balkendiagramm, das zeigt, wie viele Beobachtungen (Zeilen) es für jeden Kontinent gibt. Dazu dient geom_bar(), das ein Balkendiagramm erzeugt. Die einzige ästhetische Zuordnung, die wir festlegen, ist x=continent. Die Funktion berechnet die y-Achse (Anzahl der Zeilen je Kontinent) automatisch.

ggplot(data=gapminder) +
  geom_bar(aes(x=continent))
Balkendiagramm der Anzahl der Beobachtungen je Kontinent in gapminder, wobei Afrika die meisten und Ozeanien die wenigsten hat

Alternativ können wir die Anzahl der Beobachtungen je Kontinent selbst berechnen. Das gelingt einfach mit der Funktion count() aus dem Package dplyr. Vermutlich haben Sie dplyr bereits geladen, da es Teil des Packages tidyverse ist. Andernfalls laden wir es jetzt:

library(tidyverse)

Die Funktion count() zählt die Anzahl der Zeilen für eine oder mehrere kategoriale Variablen, und zwar wie folgt:

gapminder |>
  count(continent)
continent <fctr> n <int>
Africa 624
Americas 300
Asia 396
Europe 360
Oceania 24

Wie oben ersichtlich, wird die Anzahl der Zeilen (n) für jeden Kontinent (continent) berechnet.

Wie oben ersichtlich, wird die Anzahl der Zeilen (n) für jeden Kontinent (continent) berechnet. Mit diesen Daten erstellen wir nun ein Balkendiagramm, das mit dem vorherigen identisch ist. Da geom_bar() die y-Achse nicht mehr selbst berechnen soll, geben wir y=n an und verwenden das Argument stat="identity", um mitzuteilen, dass die Werte bereits berechnet sind. Beachten Sie außerdem, dass wir count() mit ggplot() verketten und damit das Ergebnis von count() direkt in ggplot() verwenden. Das ist möglich, weil die Pipe (|>) das Ergebnis einer Operation an die nächste Funktion weitergibt, wo es als erstes Argument verwendet wird (das erste Argument der Funktion ggplot() ist data).

gapminder |>
  count(continent) |>
  ggplot(aes(x=continent, y=n)) +
  geom_bar(stat="identity")
Balkendiagramm der Anzahl der Zeilen n je Kontinent in gapminder, identisch mit dem vorherigen, aber mit stat identity erstellt

Es gibt weitere Transformationen (Berechnungen), die in geometrische Objekte integriert sind. geom_smooth() ist Ihnen bereits im vorherigen Kapitel begegnet. Hier folgen weitere Beispiele für Geoms, die bei ihrer Verwendung Berechnungen durchführen:

  • geom_bar(), geom_histogram(), geom_freqpoly() berechnen Summen und Anteile.
  • geom_boxplot(), geom_violin() berechnen Verteilungen.
  • geom_smooth() erstellt ein Regressionsmodell, das visualisiert wird.

Im nächsten Beispiel verwenden wir gapminder für Folgendes:

  • Zeile 2: Wir behalten nur Länder in Afrika, indem wir mit dem Argument continent=="Africa" filtern.
  • Zeile 2: Wir behalten nur Daten aus dem Jahr 1997, indem wir mit dem Argument year==1997 filtern.
  • Zeile 2: Wir verketten ggplot() mit |> direkt mit den vorangehenden Operationen.
  • Zeile 4: Wir erstellen ein Balkendiagramm, in dem das Land die y-Achse und die Lebenserwartung die x-Achse bildet. Da diese Werte bereits berechnet sind, wird das Argument stat="identity" verwendet:
gapminder |>
  filter(continent=="Africa", year==1997) |>
  ggplot()+
  geom_bar(aes(y=country,
               x=pop),
           stat="identity")
Horizontales Balkendiagramm der Bevölkerungszahl 1997 afrikanischer Länder in alphabetischer Reihenfolge

Als Nächstes sortieren wir die y-Achse nach der Lebenserwartung (lifeExp). Das lässt sich direkt in aes() mit der Funktion reorder() erledigen. In reorder wird angegeben, was sortiert werden soll (country) und nach welcher Spalte sortiert wird (pop, die Bevölkerungszahl). Siehe Zeile 4 unten.

gapminder |>
  filter(continent=="Africa", year==1997) |>
  ggplot()+
  geom_bar(aes(y=reorder(country, pop),
               x=pop),
           stat="identity")
Horizontales Balkendiagramm der Bevölkerungszahl 1997 in Afrika, sortiert mit Nigeria oben und Sao Tome und Principe unten

Ein Minuszeichen (-) vor pop in reorder() führt zu einer umgekehrten Sortierung, wie folgt (siehe Zeile 4):

gapminder |>
  filter(continent=="Africa", year==1997) |>
  ggplot()+
  geom_bar(aes(y=reorder(country, -pop),
               x=pop),
           stat="identity")
Horizontales Balkendiagramm der Bevölkerungszahl 1997 in Afrika in umgekehrter Sortierung, mit Nigeria unten

Wir müssen außerdem die Lebenserwartung (lifeExp) jedes Landes visualisieren und können dies über das Argument fill() tun, und zwar wie folgt (Zeile 6):

gapminder |>
  filter(continent=="Africa", year==1997) |>
  ggplot()+
  geom_bar(aes(y=reorder(country, pop),
               x=pop,
               fill=lifeExp),
           stat="identity")
Horizontales Balkendiagramm der Bevölkerungszahl 1997 in Afrika, bei dem der Blauton des Balkens die Lebenserwartung zeigt

Anteile

Mit geom_bar() lassen sich Anteile (prop) statt Anzahlen (count) berechnen. Dazu wird eine „Nachberechnung“ (after_stat) auf y durchgeführt und group=1 angegeben, was bedeutet, dass der Gesamtanteil über alle Kontinente 1 betragen soll:

ggplot(data = gapminder) +
  geom_bar(mapping = aes(x = continent,
                         y = after_stat(prop),
                         group = 1))
Balkendiagramm des Anteils der Beobachtungen je Kontinent in gapminder, wobei Afrika etwa 0,37 ausmacht

Stat Summary: stat_summary()

Wir können auch stat_summary() verwenden, um auszuwählen, welche Parameter berechnet und visualisiert werden sollen. Mit stat_summary() haben wir bei den Berechnungen größere Flexibilität. Wir legen selbst fest, welche Funktionen verwendet werden, und wählen zudem, welche Art von Geom das Ergebnis darstellen soll. Im Folgenden verwenden wir stat_summary(), um Mittelwert, Minimum und Maximum der Lebenserwartung für jeden Kontinent zu berechnen; dies wird mit dem Geom „pointrange“ (geom_pointrange()) visualisiert:

## Wir verwenden nur Daten aus dem Jahr 1997
ggplot(data = filter(gapminder, year==1997)) +
  stat_summary(
    aes(x = continent,
        y = lifeExp),
    fun = mean,
    fun.min = min,
    fun.max = max,
    geom = "pointrange"
  )
Punkt-Intervall-Diagramm von Mittelwert, minimaler und maximaler Lebenserwartung je Kontinent 1997

Segmentierte Balkendiagramme

Wir kehren zu den mpg-Daten zurück, um weitere Funktionen von geom_bar() zu veranschaulichen. Im nächsten Beispiel verwenden wir fill, um Anteile eines Balkens zu kennzeichnen. Wir möchten in jedem Balken die Anteile der Spalte drv (Antriebsart des Fahrzeugs) kennzeichnen. Im folgenden Code haben wir zudem das Theme der Grafik mit der Funktion theme() angepasst, um den Text auf der x-Achse um 45° zu neigen (Themes werden in einem späteren Kapitel behandelt).

mpg |>
  ggplot(aes(x=manufacturer,
             fill=drv)) +
  geom_bar() +
  # Neigt den Text auf der x-Achse um 45°
  theme(axis.text.x = element_text(angle=45))
Gestapeltes Balkendiagramm der Anzahl der Autos je Hersteller in mpg, eingefärbt nach den Antriebsarten 4, f und r

Offenbar stellt der Hersteller Volkswagen ausschließlich Autos mit Frontantrieb (f) her, während Subaru ausschließlich Autos mit Allradantrieb herstellt. Land Rover stellt ausschließlich Autos mit Hinterradantrieb her.

Im obigen Beispiel haben wir geom_gar() ohne Argumente geschrieben. Das bedeutet, dass position seinen Standardwert erhielt, nämlich „identity“. Es gibt außerdem die Alternativen „dodge“ und „fill“, die zu folgenden Grafiken führen:

mpg |>
  ggplot(aes(x=manufacturer,
             fill=drv)) +
  geom_bar(position="dodge") +
  theme(axis.text.x = element_text(angle=45))
Balkendiagramm der Anzahl der Autos je Hersteller mit den Antriebsarten 4, f und r als nebeneinander stehende Balken

Wie oben ersichtlich, führt position="dodge" dazu, dass die Segmente nebeneinander platziert statt übereinander gestapelt werden. Wir fahren mit position="fill" fort:

mpg |>
  ggplot(aes(x=manufacturer,
             fill=drv)) +
  geom_bar(position="fill") +
  theme(axis.text.x = element_text(angle=45))
Balkendiagramm, in dem der Balken jedes Herstellers den Anteil der Autos mit den Antriebsarten 4, f und r bis 1 zeigt

Wie oben ersichtlich, führt position="fill" dazu, dass die Segmente in jedem Balken als Anteile (Proportionen) statt als Anzahlen dargestellt werden.