9 Deskriptive Statistik für metrische Daten

📢 Zielsetzung dieser Einheit

Diese Einheit widmet sich der Beschreibung metrischer Variablen. Anhand des Beispiels von COVID-19 Erkrankungen in österreichischen Bezirken werden wir

  • die numerische Ermittlung klassischer Lage- und Streuungsparameter behandeln;
  • einen Exkurs zur Frage der Normierung von Daten unternehmen;
  • die Möglichkeiten der graphischen Darstellung von Lageparametern und der Variablen innewohnenden Streuung behandeln;
  • abschließend einen Ausblick auf bivariate Zusammenhänge zwischen metrischen Variablen werfen.

tl;dr: Her mit dem Code!


9.1 Die Ausgangslage

Wie bei den kategorialen wollen wir uns nun den Möglichkeiten zur Beschreibung metrischer Daten widmen. Dazu werden wir folgendes Beispiel nutzen:

Die Österreichische Agentur für Gesundheit und Ernährungssicherheit AGE bietet tagesaktuell Informationen zur COVID-19 Fällen in den politischen Bezirken Österreichs an. Wir wollen diese Daten nutzen, um

  1. herauszufinden, wie unterschiedlich sich COVID-19 Erkrankungen (gesamt und in den letzten sieben Tagen - Variablen Anzahl und AnzahlFaelle7Tage) und Todesfälle (Variable AnzahlTot) auf die Bezirke und Bundesländer verteilen;

  2. herauszufinden, ob es auf Eben der Bezirke zwischen der Anzahl der COVID-19 Erkrankungen (Variable Anzahl) und Todesfälle (Variable AnzahlTot) einen Zusammenhang gibt.

Ein praktischer Hinweis:
Um diese Einheit auch zu einem späteren Zeitpunkt nachvollziehen zu können, werden nicht die tagesaktuellen Daten der AGES genutzt. Stattdessen wurden diese Daten zum Stichtag 25.05.2021 bezogen und als CSV-Datensatz abgelegt.

👉 Diese Stichtagsdaten können hier als CSV-Datei heruntergeladen werden.

9.2 Der Datenimport, die Datenaufbereitung und -validierung

Zur Vorbereitung der weiteren Analyse laden wir zunächst die Packages tidyverse (ggplot, dplyr etc.) und scales (zur Formatierung von Achsen bei Abbildungen):

library(tidyverse)
library(scales)

Dann holen wir uns die Stichtagsdaten und werfen einen Blick auf ihre Struktur:

agesRohdaten <- read.csv2("data/agesRohdaten_25-05-21.csv", encoding = "UTF-8") %>%
  as_tibble()
str(agesRohdaten)
## tibble [94 x 7] (S3: tbl_df/tbl/data.frame)
##  $ X                : int [1:94] 1 2 3 4 5 6 7 8 9 10 ...
##  $ Bezirk           : chr [1:94] "Eisenstadt(Stadt)" "Rust(Stadt)" "Eisenstadt-Umgebung" "Güssing" ...
##  $ GKZ              : int [1:94] 101 102 103 104 105 106 107 108 109 201 ...
##  $ AnzEinwohner     : int [1:94] 14816 1980 43236 25699 17097 40042 59990 37384 54192 101300 ...
##  $ Anzahl           : int [1:94] 985 76 2347 1822 1298 2268 3248 2220 3618 6200 ...
##  $ AnzahlTot        : int [1:94] 11 0 25 56 26 32 42 41 91 158 ...
##  $ AnzahlFaelle7Tage: int [1:94] 5 1 12 7 5 16 19 5 13 41 ...

Sicherheitshalber halten wir noch nach möglichen “Löchern” (aka NAs) in den Daten Ausschau:

colSums(is.na(agesRohdaten)) %>%
  knitr::kable()
x
X 0
Bezirk 0
GKZ 0
AnzEinwohner 0
Anzahl 0
AnzahlTot 0
AnzahlFaelle7Tage 0

Sehr gut, wir haben also keine Löcher in unserem Datensatz.

Bevor wir in die eigentliche Analyse einsteigen, wollen wir noch folgende zwei Schritte setzen:

  1. Um die COVID-19 Zahlen der Bundesländern vergleichen zu können, müssen wir die Bezirke ebendiesen zuordnen.
  2. Um eine Vergleichbarkeit der COVID-19 Erkrankungen zwischen den Bezirken herbeizuführen, normieren wir die Angaben zu den Erkrankungen (in den letzten sieben Tagen) und Verstorbenen auf 100.000 Einwohner.

Für die Zuordnung der Bezirke zu ihrem Bundesland werfen wir einen Blick auf die Logik der Vergabe von Kennziffern (Variable GKZ) für Bezirke in Österreich:

http://statistik.at/web_de/klassifikationen/regionale_gliederungen/politische_bezirke

Wir wissen jetzt also, dass die erste Stelle der Variable GKZ als Index für die Liste der alphabetisch aufsteigend sortierten Bundesländernamen dient. Daher können wir folgendes machen:

covidCases <- agesRohdaten %>%
  mutate(bula = factor(floor(GKZ/100),
                       levels = c(1:9),
                       labels = c("Burgenland",
                                  "Kärnten",
                                  "Niederösterreich",
                                  "Oberösterreich",
                                  "Salzburg",
                                  "Steiermark",
                                  "Tirol",
                                  "Vorarlberg",
                                  "Wien")
                       )
         )
summary(covidCases$bula)
##       Burgenland          Kärnten Niederösterreich   Oberösterreich 
##                9               10               24               18 
##         Salzburg       Steiermark            Tirol       Vorarlberg 
##                6               13                9                4 
##             Wien 
##                1

Zuletzt noch das Normieren der Variablen Anzahl, AnzahlTot und Anzahl7Tage auf 100.000 Einwohner:

covidCases <- covidCases %>%
  mutate(Anzahl_100k = Anzahl/(AnzEinwohner/100000),
         AnzahlTot_100k = AnzahlTot/(AnzEinwohner/100000),
         Anzahl7Tage_100k = AnzahlFaelle7Tage/(AnzEinwohner/100000))

Sehr gut, nun wollen wir die am Beginn gestellten Fragen mithilfe dieser Daten beantworten.

9.3 Ein Blick auf klassische Lage- und Streuungsparameter

Um einen raschen Überblick auf (nicht nur) die bekanntesten Lageparameter wie das arithmetische Mittel und Streuungsparamter zu erhalten, schreiben wir:

summary(covidCases)
##        X            Bezirk               GKZ         AnzEinwohner    
##  Min.   : 1.00   Length:94          Min.   :101.0   Min.   :   1980  
##  1st Qu.:24.25   Class :character   1st Qu.:305.2   1st Qu.:  44745  
##  Median :47.50   Mode  :character   Median :404.5   Median :  64138  
##  Mean   :47.50                      Mean   :418.3   Mean   :  94692  
##  3rd Qu.:70.75                      3rd Qu.:609.0   3rd Qu.:  96836  
##  Max.   :94.00                      Max.   :900.0   Max.   :1911191  
##                                                                      
##      Anzahl         AnzahlTot      AnzahlFaelle7Tage               bula   
##  Min.   :    76   Min.   :   0.0   Min.   :  1.00    Niederösterreich:24  
##  1st Qu.:  3326   1st Qu.:  43.5   1st Qu.: 16.00    Oberösterreich  :18  
##  Median :  5206   Median :  75.0   Median : 30.00    Steiermark      :13  
##  Mean   :  6784   Mean   : 109.4   Mean   : 46.39    Kärnten         :10  
##  3rd Qu.:  6578   3rd Qu.: 112.8   3rd Qu.: 52.50    Burgenland      : 9  
##  Max.   :136512   Max.   :2312.0   Max.   :907.00    Tirol           : 9  
##                                                      (Other)         :11  
##   Anzahl_100k    AnzahlTot_100k   Anzahl7Tage_100k 
##  Min.   : 3838   Min.   :  0.00   Min.   :  7.788  
##  1st Qu.: 6387   1st Qu.: 83.02   1st Qu.: 31.888  
##  Median : 7078   Median :109.56   Median : 40.481  
##  Mean   : 7277   Mean   :117.49   Mean   : 47.734  
##  3rd Qu.: 8186   3rd Qu.:146.56   3rd Qu.: 59.392  
##  Max.   :12266   Max.   :249.25   Max.   :181.896  
## 

Schnell und einfach, jedoch auch ohne eine oftmals inhaltlich erwünschte Gruppierung der Variablen von Interesse. Solche Gruppierungen werden beispielsweise gerne für regionale Vergleiche genutzt. Interessieren wir uns beispielsweise für die durchschnittliche Anzahl der COVID-19 Erkrankungen innerhalb der letzten sieben Tage in den Bezirken, werden wir hiermit zunächst glücklich:

covidCases %>%
  summarise(avg_Faelle7tage = mean(Anzahl7Tage_100k))
## # A tibble: 1 x 1
##   avg_Faelle7tage
##             <dbl>
## 1            47.7

Wenn wir diesen Durchschnitt für mehrere Variablen gleichzeitig ermittel wollen:

covidCases %>%
  summarise(across(Anzahl_100k:Anzahl7Tage_100k, mean)) %>%
  knitr::kable(digits = 1)
Anzahl_100k AnzahlTot_100k Anzahl7Tage_100k
7277.5 117.5 47.7

Wie treffsicher diese bundesweiten Durchschnitte das regionale COVID-19 Infektionsgeschehen wiedergeben, zeigen uns die auf Ebene der Bundesländer ermittelten Durchschnittswerte:

covidCases %>%
  group_by(bula) %>%
  summarise(across(Anzahl_100k:Anzahl7Tage_100k, mean)) %>%
  knitr::kable(digits = 1)
bula Anzahl_100k AnzahlTot_100k Anzahl7Tage_100k
Burgenland 6032.2 103.3 30.8
Kärnten 7479.9 147.0 42.3
Niederösterreich 6478.7 101.5 38.1
Oberösterreich 7951.2 110.3 55.9
Salzburg 9801.6 122.5 37.1
Steiermark 6614.6 175.7 50.4
Tirol 8313.6 86.7 72.4
Vorarlberg 7405.1 75.5 72.2
Wien 7142.8 121.0 47.5

Im Vergleich der Bundesländer zeigen sich klare Unterschiede: Beispielsweise weisen zum Stichtag Tirol und Vorarlberg die geringsten Todesfälle je 100.000 Einwohner aber auch die höchsten Neuerkrankungen je 100.000 Einwohner in den letzten sieben Tagen auf.

Ein Blick auf die Mediane im Vergleich zu den arithmetischen Mitteln erlaubt uns einen ersten Eindruck der den Variablen innewohnenden Streuung:

covidCases %>%
  group_by(bula) %>%
  summarise(across(Anzahl_100k:Anzahl7Tage_100k, median)) %>%
  knitr::kable(digits = 1)
bula Anzahl_100k AnzahlTot_100k Anzahl7Tage_100k
Burgenland 5938.4 79.9 29.2
Kärnten 7082.3 152.0 39.8
Niederösterreich 6482.6 101.7 33.2
Oberösterreich 8116.1 108.2 54.7
Salzburg 9596.9 113.3 36.6
Steiermark 6774.1 180.7 40.1
Tirol 8239.1 75.4 68.2
Vorarlberg 7366.1 74.8 72.9
Wien 7142.8 121.0 47.5

Die vorhandenen Unterschiede zwischen den Medianen und den Mittelwerten deuten auf das Vorhandensein von Ausreißern hin. Mehr dazu später.

📚 Exkurs zum Thema “Warum normieren?”:
Wer sich fragen sollte, warum wir das CORONA-19 Infektionsgeschehen auf 100.000 Einwohner normiert haben: Watch this!

covidCases %>%
  group_by(bula) %>%
  summarise(avg_Anzahl_100k = mean(Anzahl_100k),
            avg_Anzahl = mean(Anzahl),
            avg_AnzahlTot_100k = mean(AnzahlTot_100k),
            avg_AnzahlTot = mean(AnzahlTot)) %>%
  knitr::kable(digits = 1)
bula avg_Anzahl_100k avg_Anzahl avg_AnzahlTot_100k avg_AnzahlTot
Burgenland 6032.2 1986.9 103.3 36.0
Kärnten 7479.9 3984.5 147.0 81.4
Niederösterreich 6478.7 4439.7 101.5 67.5
Oberösterreich 7951.2 6433.5 110.3 88.5
Salzburg 9801.6 8324.5 122.5 97.7
Steiermark 6614.6 6105.4 175.7 157.9
Tirol 8313.6 6915.8 86.7 75.8
Vorarlberg 7405.1 7392.2 75.5 75.2
Wien 7142.8 136512.0 121.0 2312.0

Der direkte Vergleich zeigt, dass die in den nicht-normierte Daten enthaltenen Größeneffekte klare die Ranggreihenfolge der Bezirke beeinflussen. Natürlich gilt: Nicht für alle Fragestellungen ist eine Normierung von Daten nötig oder gar erwünscht. Die Entscheidung für oder gegen einer solche Normierung kann damit immer nur in Hinblick auf die zu beantwortende Frage getroffen werden.

9.4 Exkurs für motivierte GeographInnen: Räumlich explizite Deskription

Für GeographInnen spielt ja auch die Frage nach dem “Wo?” oftmals eine große Rolle. In unserem Fall würde sich beispielsweise die räumliche Verteilung der COVID-19 Erkrankungen anbieten, in einer Karte verewigt zu werden. Um dies zu bewerkstelligen müssen wir

  • die Geometrien der Österreichischen Bezirke als SHP-Dateien vorliegen haben;
  • an diese Geometrien unsere COVID-19 Daten anhängen (aka “joinen”) und
  • letztlich daraus eine einfache thematische Karte basteln.

Da sich all dies in R leicht umsetzen lässt:

1. Die Geometrien der österreichischen Bezirke:

Werden uns zum Stand 2021 von der Statistik Austria unter folgender Adresse angeboten:

https://www.data.gv.at/katalog/dataset/stat_gliederung-osterreichs-in-politische-bezirke131e2/resource/d2659aca-306f-4e24-a318-bf9cfb32319f

Ich habe mir erlaubt, diesen Datensatz etwas aufzubereiten (vgl. VU “How 2 do Things with even more Numbers” aus dem WS 21-22). Er kann 👉 HIER als ZIP-Archiv gealden werden.

👉 Anmerkung: Wir gehen in dieser Einheit von folgender Verzeichnisstruktur aus:

**Projektfolder**
| skript_1.R
| ...
| skript_n.R    
+-- data
|     bez
|       | geodatensatz_1.xyz
|       | ...
|       | geodatensatz_n.xyz
|     | datensatz_1.xyz
|     | ...
|     | datensatz_n.xyz
+-- output

Mittels des Simple Features (sf) Packages können wir gängige Geodatenformate (zB SHP-Dateien) in R gelesen und beispielsweise über das Thematic Maps (tmap) Package visualisieren:

library(sf)
## Linking to GEOS 3.9.1, GDAL 3.2.1, PROJ 7.2.1; sf_use_s2() is TRUE
library(tmap)
bez <- read_sf("data/bez/bez_aut.shp")
tm_shape(bez) +
  tm_polygons()

2. Verknüpfung der Attribut- mit den Geometriedaten:

Jetzt müssen wir nur noch unsere Attributdaten - die Variablen zum COVID-19 Infektionsgeschehen aus dem covidCases-Tibble - an die Geometrien der Bezirke hängen. Wie aus der Geoinformatik bekannt, verwenden wir dazu einen Join (konkret: die left_join Funktion des dplyr Packages):

joined_bez <- left_join(bez, covidCases, by = c("id" = "GKZ"))

3. Visualisierung ausgewählter Variablen als Choroplethenkarte:

Damit können wir nun eine einfache Choroplethenkarte zu den COVID-19 Infektionen je 100.000 Einwohner in den österreichischen Bezirken erstellen:

tmap::qtm(joined_bez, fill = "Anzahl_100k")

Und wer das gerne noch mit etwas mehr 🚀 🎉 möchte:

mymap <- tm_shape(joined_bez) +
  tm_polygons("Anzahl_100k",
              title = "Erkrankte\nje 100.00 EW",
              palette = "YlOrRd",
              legend.hist = TRUE) +
  tm_scale_bar(position = c("left", "bottom")) +
  tm_legend(outside = TRUE,
            legend.outside.size = 0.15,
            hist.width = 1,
            outer.margins = 0)
mymap

Zum Abschluß dieses Exkurses: Wie kann ich solche Karten speichern (zB in den Ordner “output”)?

tmap_save(mymap, filename = "output/covid_faelle_100k_2021.png",
          units = "px", dpi = 300,
          width = 2000)

9.5 Lage- und Streuungsparameter graphisch darstellen

Um einen schnellen Überblick auf die Daten innewohnende Streuung (= Verteilung der beobachteten Werte) zu erhalten, bieten sich zwei klassische Darstellungsformen an:

9.5.1 Histogramme

Anhand von Klassen (“bins”) wird die Häufigkeitsverteilung der beobachteten Werte dargestellt:

ggplot(covidCases, aes(x = Anzahl7Tage_100k)) +
  geom_histogram(bins = 50,
                 col = "black", fill = "red")

In unserem Fall der COVID-19 Erkrankungen in den letzten 7 Tagen sehen wir, dass nur sehr wenige Bezirke mehr als 90 Erkrankungen je 100.000 Einwohner hatten. Wer diese “Ausreißer nach oben” waren, lässt sich mit einer einfachen Filterung herausfinden:

covidCases %>%
  select(Bezirk, Anzahl7Tage_100k) %>%
  filter(Anzahl7Tage_100k >= 90) %>%
  arrange(-Anzahl7Tage_100k)
## # A tibble: 5 x 2
##   Bezirk         Anzahl7Tage_100k
##   <chr>                     <dbl>
## 1 Imst                      182. 
## 2 Wels(Stadt)               115. 
## 3 Gänserndorf                98.3
## 4 Bregenz                    94.8
## 5 Innsbruck-Land             90.3

Da wir ja bereits die Vermutung haben, dass diese Verteilung in den Bundesländern unterschiedlich ausfallen könnte, lassen wir uns je Bundesland ein solches Histogramm erstellen:

ggplot(covidCases, aes(x = Anzahl7Tage_100k)) +
  geom_histogram(bins = 30, fill = "red", color = "black") +
  # geom_density(size = 1, color = "red") +
  facet_wrap(~bula)

Betrachtet man die beiden Bundesländer mit den meisten Bezirken, so zeigt sich dass in Niederösterreich am stärksten besetzten Klassen unter und in Oberösterreich über 50 Erkrankungen je 100.000 Einwohner in den letzten sieben Tagen lagen.

📚 Exkurs:
Histogramme werden gerne auch zur Abschätzung der Normalverteilung einer Variable genutzt. Warum das? Für manche Testverfahren ist es wichtig zu wissen, ob die darin verwendeten Variablen normalverteilt sind oder nicht. Mehr dazu aber in einer der späteren Einheiten. Um diese Abschätzung zu unterstützen, kann die beobachtete Dichtefunktion eingeblendet werden:

ggplot(covidCases, aes(x = Anzahl7Tage_100k, y = ..density..)) +
  geom_histogram(bins = 50,
                 col = "black", fill = "red") +
  geom_rug(aes(x = Anzahl7Tage_100k, y = NULL)) +
  geom_density(size = 1.5)

In unserem Fall spricht der rechte “tail” der beobachteten Dichtefunktion eher gegen eine Normalverteilung der CORONA-19 Erkrankungen je 100.000 Einwohner in den letzten sieben Tagen.

9.5.2 Boxplots

Boxplots ermöglichen zwar nicht die Beurteilung der Normalverteilung einer Variable, bieten aber einen sehr kompakten Überblick auf den Median und ausgewählte quartilsbasierte Streuungsparameter:

Struktur von Boxplots in R (Quelle: [Coleman, 2020](https://www.leansigmacorporation.com/box-plot-with-minitab/))

Abbildung 9.1: Struktur von Boxplots in R (Quelle: Coleman, 2020)

Insbesondere die Identifikation von Ausreißern, also einzelnen Extremwerten wird durch Boxplots sehr erleichtert:

ggplot(covidCases, aes(x = bula, y = AnzahlTot_100k)) +
  geom_boxplot()

Das geht natürlich auch wieder a little bit more shiny:

ggplot(covidCases, aes(x = forcats::fct_reorder(bula, AnzahlTot_100k, median), y = AnzahlTot_100k)) +
  geom_boxplot(fill = "azure3") +
  geom_jitter(shape=16, position=position_jitter(0.1),
              color = "red", alpha = 0.2) +
  theme_bw() +
  theme(plot.title = element_text(face = "bold", hjust = 0.5),
        plot.caption = element_text(hjust = 0.5),
        axis.text.x=element_text(angle = 45, hjust = 1),
        axis.title.x = element_text(face = "bold"),
        axis.title.y = element_text(face = "bold")) +
  labs(title = "Verteilung der COVID-19 Todesfälle\n",
       x = "\nBundesländer",
       y = "COVID-19 Todesfälle\nje 100.000 EW\n",
       caption = "\nDaten: AGES, 2021 - covid19-dashboard@ages.at")

9.6 Ein erster Blick auf mögliche Zusammenhänge

Für explorative Zugänge ist es oftmals inhaltlich zielführend, mehrere Variablen graphisch zueinander in Beziehung zu setzen. Beispielsweise könnten wir uns fragen, ob wir zwischen der Einwohnerzahl der Bezirke, deren Bundeslandzugehörigkeit, und den COVID-19 Erkrankungen sowie Verstorbenen einen Zusammenhang gibt. Dabei filtern wir den politischen Bezirk Wien aus, um die Verteilung der restlichen Bezirke besser studieren zu können:

covidCasesNoVIE <- covidCases %>%
  filter(GKZ != 900)

ggplot(covidCasesNoVIE, aes(x = AnzEinwohner, y = Anzahl, fill = bula)) +
  geom_point(aes(size = AnzahlTot), shape=21) +
  scale_x_continuous(labels = scales::label_comma(big.mark = "."), breaks = scales::breaks_extended(6)) +
  scale_y_continuous(labels = scales::label_comma(big.mark = ".")) +
  theme_bw() +
  theme(text = element_text(size = 14),
        plot.title = element_text(hjust = 0.5),
        plot.caption = element_text(hjust = 0.5),
        axis.text.x=element_text(angle = 45, hjust = 1)) +
  labs(title = "Polit. Bezirke nach Einwohnern,\nCOVID-19 Fällen und Verstorbenen\n",
       x = "\nEinwohner",
       y = "COVID-19 Fälle\n",
       caption = "\nDaten: AGES, 2021 - covid19-dashboard@ages.at",
       size = "Anzahl Verstorbene",
       fill = "Bundesland") +
  guides(fill = guide_legend(override.aes = list(size = 5)))

📚 Exkurs zum Thema Datenpunkte beschriften:
Gerade bei Scatterplots ist die Beschriftung einzelner Datenpunkte zentral, um schnell Informationen über Extremwerte zu erhalten. In unserem Fall bietet sich für eine solche Beschriftung der Name des Bezirks (Name) an:

ggplot(covidCasesNoVIE, aes(x = AnzEinwohner, y = Anzahl, fill = bula)) +
  geom_point(aes(size = AnzahlTot), shape=21) +
  geom_text(aes(label = Bezirk)) +
  scale_x_continuous(labels = scales::label_comma(big.mark = "."), breaks = scales::breaks_extended(6)) +
  scale_y_continuous(labels = scales::label_comma(big.mark = ".")) +
  theme_bw() +
  theme(text = element_text(size = 14),
        plot.title = element_text(hjust = 0.5),
        plot.caption = element_text(hjust = 0.5),
        axis.text.x=element_text(angle = 45, hjust = 1)) +
  labs(title = "Polit. Bezirke nach Einwohnern,\nCOVID-19 Fällen und Verstorbenen\n",
       x = "\nEinwohner",
       y = "COVID-19 Fälle\n",
       caption = "\nDaten: AGES, 2021 - covid19-dashboard@ages.at",
       size = "Anzahl Verstorbene",
       fill = "Bundesland") +
  guides(fill = guide_legend(override.aes = list(size = 5)))

Ja, damit hätten wir Beschriftungen eingefügt, aber nein: Alle Datenpunkte zu beschriften trägt nicht dazu bei, die Lesbarkeit des Diagramms zu verbessern. Hier kann das Package ggrepel helfen, indem es überlappende Beschriftungen vermeidet:

library(ggrepel)
ggplot(covidCasesNoVIE, aes(x = AnzEinwohner, y = Anzahl, fill = bula)) +
  geom_point(aes(size = AnzahlTot), shape=21) +
  geom_text_repel(aes(label = Bezirk),
                  size = 3,
                  color = "gray",
                  # point.padding = 5,
                  box.padding = 0.4,
                  min.segment.length = 1) +
  scale_x_continuous(labels = scales::label_comma(big.mark = "."), breaks = scales::breaks_extended(7)) +
  scale_y_continuous(labels = scales::label_comma(big.mark = ".")) +
  theme_bw() +
  theme(text = element_text(size = 14),
        plot.title = element_text(hjust = 0.5),
        plot.caption = element_text(hjust = 0.5),
        axis.text.x=element_text(angle = 45, hjust = 1)) +
  labs(title = "Polit. Bezirke nach Einwohnern,\nCOVID-19 Fällen und Verstorbenen\n",
       x = "\nEinwohner",
       y = "COVID-19 Fälle\n",
       caption = "\nDaten: AGES, 2021 - covid19-dashboard@ages.at",
       size = "Anzahl Verstorbene",
       fill = "Bundesland") +
  guides(fill = guide_legend(override.aes = list(size = 5)))


🏆 Nun wissen wir, …

  • dass wir selten “perfekte” Sekundärdaten vorfinden, die keine vorbereitenden Datenmanipulationen erfordern;
  • dass numerische Lage- und Streuungsparameter flott mittels mean, median, std etc. ermittelt werden können;
  • dass wir über eine Normierung von Daten Größeneffekte bei Vergleichen zwischen Merkmalsträgern vermeiden können;
  • dass eine ansprechende graphische Deskription metrischer Variablen oftmals etwas Feintuning erfordert;
  • dass Scatterplots eine beliebte Möglichkeit sind, mögliche Zusammenhänge zwischen metrischen Variablen graphisch zu erkunden.

Wie im Fall der kategorialen Variablen bleibt aber die Fragen, ob wir Zusammenhänge zwischen metrischen Variablen nicht auch numerisch beschreiben können.