forked from CorrelAid/lernplattform
-
Notifications
You must be signed in to change notification settings - Fork 0
/
04_daten-verstehen-mit-r.Rmd
546 lines (468 loc) · 38.5 KB
/
04_daten-verstehen-mit-r.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
## **Daten verstehen mit R**
[![License: CC BY 4.0](https://img.shields.io/badge/License-CC%20BY%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by/4.0/deed.de)
*"Daten verstehen mit R" von Sylvi Rzepka in "R Lernen - der Datenkurs von und für die Zivilgesellschaft" von CorrelAid e.V. Lizensiert unter [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0/deed.de).*
![*Video: Daten mit R verstehen (30min)*](https://youtu.be/nEbiJ4EZ3OE)
### **Kernaussagen**
#### Grundlagen der Datenanalyse
- Konzeptionell sollten wir uns von **Fragen zur Exploration, möglichen Plausibilitätschecks und Fallentscheidungen** leiten lassen, die während der Analyse beantwortet werden
- Bei einer Datenanalyse nutzen wir zunächst niedrigschwellige **tabellarische Formate** wie `summary()` und `str()`, um uns einen Überblick über die Daten zu verschaffen
- Danach helfen uns **einfache Datenvisualisierungen**, die Ausprägungen von Variablen zu untersuchen (und Extremwerte zu identifizieren)
- Um weitere Operationen durchführen zu können, berechnen wir im Anschluss **statistische Kennzahlen**, Lage- und Verteilungsparameter, die für uns spannende Informationen enthalten und die Grundlage für weitere Analysen bilden
#### Visuelle Exploration
- **`ggplot2`** ist ein Paket für vielseitige **Graphiken** in R
- Die wichtigsten Schichten (Bestandteile) eines ggplots sind:
1. `data` - der **Datensatz**
2. `aes()` - die **"ästhetischen Attribute"** wie die x- oder y-Achse und Darstellungsoptionen
3. `geom_*()` - die **geometrische Form**, mit welcher die Werte dargestellt werden, z.B. geom_point() für Punktediagramme oder geom_bar() für Bardiagramme
- Einzelne Bestandteile werden mit einem **"+" verknüpft**
- **Boxplots** stellen visuell die **fünf Punkte der Verteilung (Minimum, 25%-Quartil, Median, 75%-Quartil, Maximum)** dar
Im Kapitel "Datenvisualisierung" lernt Ihr, wie ihr Graphen in R erstellen könnt.
#### Statistische Kennzahlen
- Mittels statistischer Kennzahlen lassen sich **Datensätze zusammenfassen** und Fragen an den Datensatz zu beantworten
- Besonders oft werden folgende Kennzahlen genutzt:
- Lagemaße:
- **Modus**: häufigste Ausprägung einer Variable (auch: Modalwert)
- `median()`: **Median**, der "wahre" Mittelpunkt (50% der Ausprägungen sind kleiner oder größer)
- `mean()`: arithmetische Mittel, Durchschnitt oder schlicht **Mittelwert**
- Streuungsmaße:
- `var()`: **Varianz**, die Streuung um den Mittelwert
- `sd()`: **Standardabweichung**, standardisiertes Maß für die Streuung um den Mittelwert in der selben Maßeinheit wie die Variable (auch: mittlere Abweichung), das der Wurzel aus der Varianz entspricht
- **Spannweite**: Differenz zwischen `min()`, der **minimalen Ausprägung** einer Variablen, und `max()`, der **maximalen Ausprägung** einer Variablen
- **Quantil**: Anteil der Werte, die kleiner oder gleich einem bestimmten Wert sind (z.B. 25%-Quantil: 25% aller beobachteten Werte sind kleiner gleich dieser Wert)
- `IQR()`: Im **Interquartilsabstand**, der zwischen dem 25%- und 75%-Quantil verortet ist, liegen 50% aller Messwerte
- Andere nützliche Funktionen:
- `n()`: **Anzahl** bzw. absolute Häufigkeiten der Ausprägungen
- `sum()`: **Summe** numerischer Variablen
- Darüber hinaus möchten wir schon folgende **`tidyverse`** Operationen hervorheben:
- `dplyr::summarize()` - **Zusammenfassung von Werten** zur Vereinfachung des Informationsgehalts
- `dplyr::group_by()` - **Gruppierung von Zeilen** (Beobachtungen) nach Kriterien
- Diese sind eine Art **Power-Duo**. Denn mit `dplyr::group_by()` & `dplyr::summarize()` können statistische Kennzahlen **pro Variablenkategorie** (z.B. Land) ausgegeben werden
- Verknüpft werden Operationen von *`dplyr`* mit dem **Pipe-Operator "%>%"** (zu dt. Rohrbetreiber), der eine ähnliche Funktion wie das "+" in `ggplot2` erfüllt. Für den Anfang könnt ihr euch den **Pipe-Operator "%>%"** bildlich gesprochen als **"und-dann"** vorstellen. Nehme den Input (Datensatz) von links "und-dann" wende die Funktion auf der rechten Seite an.
Im Kapitel "Datenbereinigung" lernt Ihr diese Funktionen des tidyverse in R noch ausführlicher kennen.
Für diese Lektion benötigt Ihr also zwei Packages: `dplyr`und `ggplot2` (beide Teil des `tidyverse`)
```{r pakete_ersteanalysen, exercise = TRUE}
# install.packages("dplyr")
# install.packages("ggplot2")
library(dplyr)
library(ggplot2)
```
### **Quiz**
```{r quiz_ersteanalyseninr}
quiz(caption = NULL,
question("Welche Aussagen sind wahr?",
answer("Es ist ausreichend statistische Kennzahlen zu berechnen, um Aussagen über die Bedeutung erhobener Daten zu treffen."),
answer("Es sind ausreichend Visualisierungen zu erstellen, um Aussagen über die Bedeutung erhobener Daten zu treffen."),
answer("Kontext ist bei rigoroser Datenanalyse nicht so wichtig."),
answer("Die Berechnung statistischer Kennzahlen, die Visualisierung und die Kontextualisierung sind eine wichtige Grundlage (!) für die Interpretation von Daten und komplexere Analysen.", correct = TRUE),
correct = "Richtig!",
incorrect = "Leider falsch. Die Berechnung statistischer Kennzahlen, die Visualisierung und die Kontextualisierung sind eine wichtige Grundlage (!) für die Interpretation von Daten und komplexere Analysen.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
),
question("Welche der folgenden sind Lagemaße einer Verteilung?",
answer("25%-Quantil - 25% der Werte der Verteilung sind kleiner oder gleich, der Rest ist größer. ", correct = TRUE),
answer("Median - die wahre Mitte der Ausprägungen", correct = TRUE),
answer("Mittelwert - der Durchschnitt", correct = TRUE),
answer("Maximum - der höchste Wert"),
answer("Minimum - der niedrigste Wert"),
correct = "Richtig!",
incorrect = "Leider falsch: Mit Maximum und Minimum berechnen wir lediglich die Spannweite, die selbst ein Streuungsmaß ist.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
),
question("Der Mittelwert ist robust gegen Ausreißer.",
answer("Wahr"),
answer("Unwahr", correct = TRUE),
correct = "Richtig!",
incorrect = "Leider falsch: Der Mittelwert kann durch Ausreißer stark verzerrt werden. Robuster ist der Median.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
),
question("Der Mittelwert der Zufallsvariable beträgt 5, die Spannweite 10 und die Standardabweichung 2. Um wie viel weichen Beobachtungen im Mittel von dem Wert 5 ab?",
answer("2", correct = TRUE),
answer("5"),
answer("10"),
correct = "Richtig!",
incorrect = "Leider falsch: Die Standardabweichung sagt aus, um wie viel im Mittel eine Beobachtung von dem Mittelwert abweicht (hier 2). Die Einheit entspricht dabei der Maßeinheit der Variable.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
),
question("Mit dem Package ggplot2 können...",
answer("Daten visualisiert werden.", correct = TRUE),
answer("Statistische Kennzahlen und Übersichtstabellen berechnet werden."),
answer("Daten importiert werden."),
answer("Daten bereinigt werden."),
correct = "Richtig! Die Datenbereinigung und die Berechnung von statistischen Kennzahlen und Übersichtstabellen erfolgen mit dplyr. Für den Import gibt es ganz viele Möglichkeiten, aber dazu in späteren Kapiteln mehr...",
incorrect = "Leider falsch: Visualierungen erstellen wir u.a. mit ggplot2. Die Datenbereinigung und die Berechnung von statistischen Kennzahlen und Übersichtstabellen erfolgen mit dplyr. Für den Import gibt es ganz viele Möglichkeiten, aber dazu in späteren Kapiteln mehr...",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
)
)
```
### **Interaktive Übung**
#### Fragen
Am Anfang jeder Datenanalyse steht etwas, dass zunächst gar nichts mit Daten zu tun haben muss: Fragen. Da Daten letztlich Informationen formalisieren, nutzen wir die Ergebnisse einer Datenanalyse in der Regel für den **Erkenntnisgewinn**. Möchten wir Daten erheben oder liegen uns diese bereits vor vor, hilft es, sich auf bestimmte Fragestellungen zu fokussieren, die sich aus strategischen Überlegungen ergeben.
Der [Datensatz](https://github.com/rfordatascience/tidytuesday/tree/master/data/2021/2021-01-26){target="_blank"} von **"Break Free From Plastic"** stammt aus den Jahren 2019 und 2020. Da es in dieser Einheit darum geht, in den **Analyse-Spirit** zu kommen und R als Analysetool kennenzulernen, haben wir den Datensatz "Break Free from Plastic" bereits **bereinigt** und in **zwei Datensätze** aufgeteilt: der Community Datensatz (als `community` hinterlegt) enthält alle Variablen, welche für Fragestellungen rund um die Community-Perspektive nützlich sind und der Audit Datensatz (als `audit` hinterlegt) umfasst jene Variablen, die für Fragen zur Audit-Perspektive nützlich sind. Da 2020 auch für die Initiative ein besonderes Jahr war, konzentrieren wir uns auf 2019.
Versetzen wir uns die Rolle der Organisator:innen. Sie fragen sich bestimmt, wie erfolgreich ihre Aktivitäten im Jahre 2019 waren:
1. Wie viel Plastik wurde insgesamt gesammelt? <br>
2. Wie viel Plastik wurde durchschnittlich je Kontinent gesammelt? <br>
3. Welche Faktoren beeinflussen möglicherweise diese Unterschiede? <br>
#### Datenstruktur
Um diese Fragen zu beantworten, schauen wir nun auf die Informationen, die uns vorliegen: Wir analysieren die dazu vorliegenden Daten und interpretieren die Ergebnisse.
Mit der Funktion **`dplyr::glimpse()`** erhaltet Ihr einen Überblick über die Struktur des Datensatzes (Anzahl der Beobachtungen, Anzahl der Variablen, Name und Datentyp der Variablen). Der `community` Datensatz enthält geographische und zeitliche Variablen sowie Daten zur gesammelten Plastikmenge, Veranstaltungen und Freiwilligen. Eine Zeile (auch: Beobachtung) entspricht einem Land.
```{r exercise_community, exercise = TRUE}
# Überblick über die Community verschaffen
dplyr::glimpse(community)
```
```{r quiz_kurzstatistik}
quiz(caption = NULL,
question(
"Wie viele Variablen hat der `community`-Datensatz?",
answer("Das kann man anhand des Outputs nicht sagen."),
answer("51"),
answer("6", correct = TRUE),
answer("7"),
correct = "Richtig!",
incorrect = "Leider falsch: 6 Variablen sind enthalten.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen",
random_answer_order = TRUE
),
question(
"Welche Variablen gibt die Anzahl an gesammelten Plastikstücken an?",
answer("Das kann man anhand des Outputs nicht sagen."),
answer("n_volunteers"),
answer("n_pieces", correct = TRUE),
answer("n_events"),
correct = "Richtig!",
incorrect = "Leider falsch: n_pieces gibt die Anzahl an Plastikstücken, die in einem Land gesammelt wurden an.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen",
random_answer_order = TRUE
)
)
```
Wir sehen, dass die Variablen, die Spalten in unserem Datensatz, unterschiedliche Formate haben. `continent` und `country` haben die Class "character", weil sie aus Text/ Buchstaben bestehen. Statistisch gesehen sind sie **nominal skalierte** Variablen, da sie Kategorien sind, ohne Ranking und ohne numerischen Wert. Alle anderen Variablen `n_...` sind **metrisch skalierte** Variablen. Wir können sie der Größe nach sortieren und mit ihnen ganz natürlich rechnen. Zwar nicht in unserem Datensatz aber zur Vollständigkeit: es gibt auch noch **ordinal skalierte** Variablen, z.B. Schulnoten, diese haben eine Rangreihenfolge, die Abstände zwischen den Rängen können wir aber nicht sinnvoll interpretieren. Es ist wichtig sich dieser Skalenniveaus bewusst zu sein, um die richtigen statistischen Kennzahlen für eine Variable zu finden.
Bei der Interpretation der Daten müssen wir zudem die **Aggregationsebene** betrachten. In der Datenwissenschaft verweist man auf die **Granularität der Daten**: Je aggregierter Daten vorliegen, desto schwerer wird es Zusammenhänge korrekt zu bestimmen. Idealerweise wäre in unserem Datensatz ein Event - und nicht ein Land - eine Beobachtung ("Zeile"). Wir können in unserem Datensatz also lediglich zwischen den Ländern vergleichen und müssen beachten, warum diese Schwankungen existieren. So weichen auch die Anzahl durchgeführter Events und die Anzahl involvierter Freiwilliger stark voneinander ab. Wie genau diese Unterschiede zu werten sind, ob beide Zahlen von anderen Variablen (sog. Störfaktoren, engl. *confounding variables*) beeinflusst werden und ob eine Bewertung auf Basis der Daten möglich ist, müssen wir noch herausfinden. Ein Schlagwort welches häuftig in Verbindung mit der Aggregation von Daten fällt, ist der **"Ökologische Fehlschluss**. Dieser beschreibt wie auf der Basis von Aggregatdaten unzulässigerweise auf die Individualebene geschlossen wird. Mehr dazu findet ihr natürlich auf [Wikipedia](https://de.wikipedia.org/wiki/%C3%96kologischer_Fehlschluss).
#### Erster Überblick
Nun kennen wir den Grundaufbau des Datensatzes schon und möchten die Variablen, die für unsere Fragestellungen interessant sind besser verstehen. Dazu geben wir uns mit `summary()` **erste (statistische) Eigenschaften** der Variablen aus.
```{r summary_community, exercise = TRUE}
# Zusammenfassung anzeigen lassen
summary(community)
```
```{r quiz_plausibilisierung}
quiz(
caption = NULL,
question(
"Was ist der niedrigste Wert, den die Variable n_pieces annimmt?",
answer("Das kann man anhand des Outputs nicht sagen."),
answer("68.5"),
answer("1.0", correct = TRUE),
answer("120646.0"),
correct = "Richtig!",
incorrect = "Leider falsch: 1 Plastikstück ist der niedrigste Wert.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen",
random_answer_order = TRUE
),
question(
"Die Spannweite gibt die Differenz zwischen dem größten und dem kleinsten Wert einer Variable an. Wie plausibel findet ihr die Spannweite der Variable n_pieces?",
answer("Das kann man anhand des Outputs nicht sagen."),
answer("Viel zu groß."),
answer("Plausibel", correct = TRUE),
answer("Viel zu klein"),
correct = "Richtig! Wir sehen keine negativen Werte und auch die Größenordnung erscheint nicht unplausibel.",
incorrect = "Leider falsch: Die Spannweite erscheint plausibel: wir sehen keine negativen Werte und auch die Größenordnung ist vorstellbar ",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen",
random_answer_order = TRUE
)
)
```
Auch die Gesamtanzahl an gesammelten Plastikstücken, Events und Freiwilligen können wir bestimmen:
```{r berechnung_summen, exercise = TRUE}
# Berechnung der Summen
sum(community$n_pieces)
sum(community$n_events)
sum(community$n_volunteers)
```
#### Datenvisualisierung
Erstellen wir zur Betrachtung der Kontinente nun ein Punktediagramm (*engl. Scatterplot*), genauer: Einen Beeswarmplot (*dt. Bienenschwarmdiagramm*). Diese Visualisierung stellt sowohl die Verteilung als auch die Häufigkeit von Beobachtungen über die Verteilung dar. Nehmt Euch einen Moment und beschreibt die Graphik in Euren Worten. Wo würdet Ihr den Mittelwert verorten? Markiert ihn gedanklich auf der Visualisierung. <br>
```{r geom_point_n_pieces_bericht, exercise = TRUE}
# Erstellung eines Boxplots mit Punktewolke zur Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(x = continent, y = n_pieces, fill = continent)) + # Initialisierung des ggplots mit Variablen
ggbeeswarm::geom_beeswarm(size = 3, alpha = 0.5, color = "darkgrey") + # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Punktegröße, Transparenz und Farbe zur Verdeutlichung der Anzahl
labs(
title = "Auch die Anzahl gesammelter Plastikstücke von 'Break Free From Plastic' ..." ,
subtitle = "... unterscheidet sich nach Kontinent.",
y = "Anzahl gefundener Plastikstücke",
x = "Kontinent",
caption = glue::glue("n = {nrow(community)} \nDatenquelle: TidyTuesday und BFFP")) + # Festlegung der Achsenbezeichungen, Überschriften und Titel
theme_minimal() + # Festlegung des Layout-Designs
theme(legend.position="none") + # Ausblenden der Legende
scale_fill_manual(values = c("#C9DFE6", "#94C0CD", "#4E97AC", "#366978", "#2E5A67")) # Anwendung der BFFP-Farben
```
```{r quiz_scatterplot}
quiz(caption = NULL,
question(
"In welchen Kontinenten beobachten wir extreme Werte, sogenannte 'Ausreißer'?",
answer("Afrika und Amerika"),
answer("Afrika und Europa"),
answer("Afrika und Asien", correct = TRUE),
answer("Afrika und Ozeanien"),
correct = "Richtig!",
incorrect = "Leider falsch: in Afrika und Asien sehen wir einige sehr große Werte, die weit von den anderen Datenpunkten entfernt sind.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen",
random_answer_order = TRUE
),
question(
"Aufsteigend von klein nach groß, wie schätzt ihr die Spannweite der Plastikstückzahl über die Kontinente hinweg ein?",
answer("Ozeanien, Afrika, Amerika, Europa, Asien"),
answer("Ozeanien, Europa, Amerika, Afrika, Asien", correct = TRUE),
answer("Europa, Ozeanien, Amerika, Afrika, Asien"),
correct = "Richtig!",
incorrect = "Leider falsch. die gesuchte Reihenfolge ist: Ozeanien, Europa, Amerika, Afrika, Asien.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen",
random_answer_order = TRUE
)
)
```
Fügen wir nun das **arithmetische Mittel pro Kontinent** (als Dreieck gekennzeichnet) in die Visualisierung ein. Hattet Ihr den Mittelwert an dieser Stelle erwartet?
```{r geom_point_n_pieces_bericht_mittelwertsd, exercise = TRUE}
# Visualisierung der Verteilung mit Mittelwert und Standardabweichung
ggplot(data = community, aes(x = continent, y = n_pieces, fill = continent)) + # Initialisierung des ggplots mit Variablen
ggbeeswarm::geom_beeswarm(size = 3, alpha = 0.5, color = "darkgrey") + # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen
# Mittelwert hinzufügen
geom_point(data = community %>%
# Berechnung der Mittelwerte pro Kontinent
dplyr::group_by(continent) %>%
dplyr::summarise(mean = mean(n_pieces)),
# Zuordnung der Mittelwerte zu der gewünschten Darstellungsform
mapping = aes(x = continent, y = mean),
size = 3, color = "#366978", shape = 17) +
labs(
title = "Die Anzahl gesammelter Plastikstücke von 'Break Free From Plastic' ..." ,
subtitle = "... unterscheidet sich nach Kontinent.",
y = "Anzahl gefundener Plastikstücke",
x = "Kontinent",
caption = glue::glue("n = {nrow(community)}\n Einige Ausreißer wurden zur Lesbarkeit des Graphen ausgeklammert. \nDatenquelle: TidyTuesday und BFFP")) + # Festlegung der Achsenbezeichungen, Überschriften und Titel
theme_minimal() + # Festlegung des Layout-Designs
theme(legend.position="none") + # Ausblenden der Legende
scale_fill_manual(values = c("#C9DFE6", "#94C0CD", "#4E97AC", "#366978", "#2E5A67")) # Anwendung der BFFP-Farben
```
```{r quiz_Mittelwert}
quiz(caption = NULL,
question(
"Wie gut bringt der Mittelwert die Verteilung der in den verschiedenen Ländern gesammelten Plastikstücken auf den Punkt?",
answer("Gut: er ist einfach zu interpretieren"),
answer("Gut: er passt visuell gut in die Punktewolke."),
answer("Nicht so gut: nur wenige Beobachtungen sind größer, Ausreißerwerte haben eine großen Einfluss. ", correct = TRUE),
answer("Nicht so gut: genau dieselbe Anzahl Plastikstücke wurde in nur einem Land gesammelt."),
correct = "Richtig!",
incorrect = "Leider falsch: der Mittelwert wird stark von Ausreißern beeinflusst.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen",
random_answer_order = TRUE
)
)
```
#### Häufige Fehler bei der Betrachtung von statistischen Kennzahlen
Obwohl er das wohl am häufigsten genutzte statistische Maß ist: Das arithmetische Mittel (auch: Mittelwert) darf **nur für metrisch skalierte Variablen** berechnet werden (!) und muss aufgrund der **fehlenden Robustheit gegenüber Ausreißern** oft genauer betrachtet werden, um aus den Daten keine falschen Schlüsse zu ziehen. Klarer wird das, wenn der Mittelwert visualisiert oder mit anderen statistischen Kennzahlen betrachtet wird: Wie stark streuen die beobachteten Werte um den Mittelwert, wie hoch sind Standardabweichung und Varianz? Gibt es Ausreißer? Ihr solltet in Euren Analysen also verschiedene statistische Kennzahlen miteinander vergleichen. Nutzen wir nun das Power-Duo **`dplyr::group_by()` und `dplyr::summarize()`**, um mehr statistische Kennzahlen pro Kontinent zu berechnen.
```{r ueberblick_statistische_kennzahlen, exercise = TRUE}
# Tabelle mit statistischen Kennzahlen
community %>%
group_by("Kontinent" = continent) %>%
summarise("Anzahl Beobachtungen" = n(),
"Anzahl Events" = sum(n_events),
"Anzahl Freiwillige" = sum(n_volunteers),
"Anzahl Plastikstücke" = sum(n_pieces),
"Mittelwert" = mean(n_pieces),
"Standardabweichung" = sd(n_pieces),
"Varianz" = var(n_pieces),
"Median" = median(n_pieces),
"Quartil (25%)" = quantile(n_pieces, .25),
"Quartil (75%)" = quantile(n_pieces, .75),
"Interquartilsabstand (IQR)" = IQR(n_pieces),
"Spannweite" = max(n_pieces) - min(n_pieces))
```
Varianz und Standardabweichung geben die **Streuung um den Mittelwert** an, wobei die Standardabweichung leichter zu interpretieren ist, da sie die **gleiche Einheit** wie unsere Variable (also ein Plastikstück) hat. Hohe Werte können auf eine weit gestreute Verteilung aber auch auf die Existenz von Ausreißern hinweisen. Das solltet Ihr unbedingt immer überprüfen! Für Asien ist die Standardabweichung mit 29424 doppelt so groß wie der Mittelwert. Dies liegt in diesem Fall an den Ausreißern, die wir bereits in der Visualisierung sehen konnten.
```{r quiz_standardabweichung}
quiz(caption = NULL,
question("Warum gibt R für die Standardabweichung für Ozeanien (eng. Oceania) 'NA' aus?",
answer("Weil keine Plastikstücke gefunden wurden."),
answer("Weil Ozeanien nur drei Stück Plastik registriert hat."),
answer("Weil nur ein Land in Ozeanien mitgemacht hat.", correct = TRUE),
answer("Kann eigentlich nicht sein. Deutet auf einen Fehler hin."),
correct = "Richtig!",
incorrect = "Leider falsch: In Ozeanien hat nur ein Land mitgemacht, weshalb es zwischen einzelnen Beobachtungen auf Länderebene natürlich keine Standardabweichung geben kann.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen",
random_answer_order = TRUE
)
)
```
Der **Median** stellt die **wahre Mitte der Verteilung** dar. Er ist gleichzeitig auch das 50%-Quantil. Stellt Euch die Beobachtungen als Punkte (also die einzelnen Länder mit ihrer Plastikstückanzahl) der Reihe nach aufsteigend vor. Das 50%-Quantil, der Median, ist die Beobachtung, die diese Reihe genau in zwei Hälften teilt: In Asien haben 17 Länder an **Break Free From Plastic** teilgenommen. Die Anzahl an Plastikstücken des neunte Land in der imaginären Aufreihung ist der Median. Hier beträgt er 3.459 Plastikstücke, soviel wie in China gesammelt wurden. Bei hohen Unterschieden zwischen Mittelwert und Median ist davon auszugehen, dass Ausreißer die Werte verzerren.
Besonders häufig wird zudem das **25%-Quantil** und das **75%-Quantil** genutzt, die gemeinsam den **Interquartilsabstand** (IQR) bilden: 50% der Beobachtungen liegen in diesem Bereich. In Asien wäre das 25%-Quantil die Plastikstückanzahl von Japan, mit 84 Stücken dem fünften Land in aufsteigender Reihenfolge, und das 75%-Quantil Malaysia, mit 4.880 Plastikstücken dem dreizehnten Land in der Reihe. In Asien fällt es besonders leicht Quantile zu erklären, da wir eine *ungerade* Anzahl an Beobachtungen haben sind das 25%, 50%, und 75%-Quantil die Ausprägungen von konkreten Beobachtungen. Hätten wir eine *gerade* Anzahl, zum Beispiel 18 Länder, dann wären diese Quantilswerte die Mittelwerte zwischen Beobachtungen. Für den Median zum Beispiel der Mittelwert aus dem Land an Position 9 und 10.
Die **Spannbreite** ist die Differenz aus Minimum und Maximum: 100% oder schlicht "alle" beobachten Werte liegen darin. Allein hat sie nur eine geringe Aussagekraft. Allerdings könnt Ihr über das Minimum und Maximum sehr gut die Datenqualität überprüfen. Gibt es negative Beobachtungen, obwohl die Variable einen natürlichen Nullpunkt hat? Ist das Maximum ein Wert wie "99999", der eventuell auf eine Codierung hinweist? Leider schleichen sich durch mit Zahlen codierte Werte, z.B.99999 für fehlende Werte, immer wieder Fehler in Analysen ein.
#### Boxplots und ihre besondere Funktionsdualität
**Boxplots** stellen die Verteilung von Variablen inklusive wichtiger statistischer Eigenschaften dar. Sie fassen die **fünf Punkte der Verteilung (Minimum, 25%-Quartil, Median, 75%-Quartil, Maximum)** zusammen und geben damit einen sehr guten Überblick über Daten. Deshalb fügen wir sie nun zum Graphen hinzu:
```{r boxplot_plastik, exercise = TRUE}
# Erstellung eines Boxplots mit Punktewolke zur Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(x = continent, y = n_pieces, fill = continent)) + # Initialisierung des ggplots mit Variablen
ggbeeswarm::geom_beeswarm(size = 3, alpha = 0.5, color = "darkgrey") + # # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Punktegröße, Transparenz und Farbe zur Verdeutlichung der Anzahl
geom_boxplot(alpha = 0.6) + # Hinzufügen des Boxplots
coord_cartesian(ylim = c(0, median(community$n_pieces) + 2 * IQR(community$n_pieces))) + # Festlegung der Achsenlänge der y-Achse abhängig von Median und Standardabweichung
labs(
title = "Die Anzahl gesammelter Plastikstücke von 'Break Free From Plastic' ..." ,
subtitle = "... unterscheidet sich nach Kontinent.",
y = "Anzahl gefundener Plastikstücke",
x = "Kontinent",
caption = glue::glue("n = {nrow(community)}\n Einige Ausreißer wurden zur Lesbarkeit des Graphen ausgeklammert. \nDatenquelle: TidyTuesday und BFFP")) + # Festlegung der Achsenbezeichungen, Überschriften und Titel
theme_minimal() + # Festlegung des Layout-Designs
theme(legend.position="none") + # Ausblenden der Legende
scale_fill_manual(values = c("#C9DFE6", "#94C0CD", "#4E97AC", "#366978", "#2E5A67")) # Anwendung der BFFP-Farben
```
Die Außenkanten der Box sind das 25%- und 75%-Quantil. Die Länge der Box gibt den **Interquartilsabstand** (IQR) an und enthält **50% der Beobachtungen**. Der Strich innerhalb der Box markiert den **Median**. Die **"Antennen" des Boxplots** (engl.: whiskers) erweitern die Box um das 1,5-fache des Interquartilsabstand. Alle Punkte, die außerhalb der Whisker liegen, sind Ausreißer.
```{r quantile}
quiz(caption = NULL,
question("Was trifft nicht auf das 50%-Quantil zu?",
answer("Auch als Median bekannt."),
answer("Nicht so sensibel Ausreißern gegenüber wie das arithmetische Mittel."),
answer("Entspricht stets dem arithmetischem Mittel.", correct = TRUE),
answer("50% aller Werte sind kleiner (gleich) diesem Wert."),
correct = "Richtig!",
incorrect = "Leider falsch: Median und Mittelwert können bei symmetrischen Verteilungen identisch sein, in der Regel unterscheiden sie sich aber.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen",
random_answer_order = TRUE
),
question("Was trifft auf Boxplots zu?",
answer("Wir können daraus den Mittelwert ablesen."),
answer("Alle Beobachtungen liegen innerhalb der 'Box'."),
answer("Sie fassen 5 Punkte einer Verteilung zusammen.", correct = TRUE),
answer("Boxplots kann man auch auf nominalskalierte Variablen wie Kontinente anwenden."),
correct = "Richtig!",
incorrect = "Leider falsch: Boxplot ist nur auf mindestens ordinalskalierte Variablen anwendbar und geben den Median aus. Ausreißer können auch außerhalb der Whisker abgetragen sein.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen",
random_answer_order = TRUE
),
question("Was sind die fünf Punkte einer Verteilung, welche im Boxplot immer dargestellt werden?",
answer("Minimum", correct = TRUE),
answer("25%-Quantil", correct = TRUE),
answer("Mittelwert"),
answer("Median", correct = TRUE),
answer("75%-Quantil", correct = TRUE),
answer("Maximum", correct = TRUE),
correct = "Richtig!",
incorrect = "Leider falsch: nur wenn Mittelwert und Median identisch sind, wird auch der Mittelwert erfasst.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen",
random_answer_order = TRUE
)
)
```
Fassen wir kurz zusammen: Wir wissen nun, dass im Datensatz einige Ausreißer enthalten sind. Daher sollten wir in der statistischen Zusammenfassung den Median und nicht das arithmetische Mittel nutzen. Außerdem empfiehlt sich bei Achsenabschnitten in graphischen Darstellungen die extremen Werte auszuklammern, um die Graphiken leserlich zu halten.
#### Beziehungen zwischen Variablen
Bisher haben wir uns vor allem der **univariaten** (= eine Variable) Verteilung von Plastikstücken gewidmet. Nun möchten wir die Daten weiter nutzen, um **bivariat** (= zwei Variablen) herauszuarbeiten: Welche Faktoren beeinflussen möglicherweise die Unterschiede in der Anzahl an Plastikstücken, die gesammelt wurden? Vielleicht die Zahl an Events?
```{r scatter_plot_n_events}
# Optional: Erstellung eines Punktediagramms mit der Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(n_events, n_pieces, label = country)) + # Initialisierung des ggplots mit Variablen
geom_point(position = position_jitter(seed = 3), size = 3, alpha = 0.5, color = "darkgrey") + # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Positionierung, Punktegröße, Transparenz und Farbe
geom_vline(xintercept=mean(community$n_events), color= "darkgray") +
geom_hline(yintercept=mean(community$n_pieces), color= "darkgray") +
geom_line(stat="smooth", method = "lm", colour = "darkred", alpha= 0.5, size=1.5) + # Trendlinie hinzufügen
#stat_smooth(colour = "darkred", method = "lm", alpha=0.6) + # Trendlinie hinzufügen
coord_cartesian(xlim = c(0, median(community$n_events) + 2 * IQR(community$n_events)), ylim = c(0, median(community$n_pieces) + 2 * IQR(community$n_pieces))) + # Festlegung der Achsenlänge der y-Achse abhängig von Median und Interquartilabstand
geom_text(size = 2) +
labs(
title = "Anzahl gesammelter Plastiksstücke bei 'Break Free From Plastic' ..." ,
subtitle = "... in Abhängigkeit von der Eventanzahl.",
x = "Events",
y = "Anzahl gefundener Plastikstücke",
caption = glue::glue("n = {nrow(community)}\n Einige Ausreißer wurden zur Lesbarkeit des Graphen ausgeklammert. \nDatenquelle: TidyTuesday und BFFP")) + # Festlegung der Achsenbezeichungen, Überschriften und Titel
theme_minimal() # Festlegung des Layout-Designs
```
In diesem Scatterplot haben wir zwei Hilfslinien eingezogen, welche jeweils den Mittelwert erfassen. Durch die Hilflinien entstehen vier Quadranten. Würden im Quadranten links unten und rechts oben die meisten Punkte liegen, würde ein **positiver statistischer Zusammenhang** vorliegen. Denn dies würde bedeuten: je größer die Anzahl an Events desto größer oftmals auch die Anzahl an gesammelten Plastikstücken. Im Graphen sehen wir allerdings, dass vor allem links unten viele Punkte geballt auftreten. Die meisten Länder haben tatsächlich nur ein oder zwei Events veranstaltet. Dies bedeutet auch, es gibt in der Variable `n_events` nur wenig Streuung/Variation.
Der Korrelationskoeffizient, der den statistischen Zusammenhang zwischen zwei metrisch skalierten Variablen erfasst, beträgt `r cor(community$n_pieces, community$n_events)`.
**Überblick über den Korrelationskoeffizienten:**
```{r korrelation_tabelle, results='asis'}
tabelle <- "
Wert: | Interpretation:
----------------|-------------------------
0 ≤ r ≤ 0,3 | schwache Korrelation
0,3 < r ≤ 0,7 | moderate Korrelation
0,7 < r ≤ 1 | starke Korrelation
"
cat(tabelle)
```
Er ist zwar positiv, aber sehr nah bei Null. Die Trendlinie im Graphen ist ebenso nahezu waagerecht.
```{r scatterplot_interpretation}
quiz(caption = NULL,
question("Welche Art Zusammenhang vermutet ihr?",
answer("eindeutig kein Zusammenhang"),
answer("eindeutig negativ"),
answer("eindeutig positiv"),
answer("Das kann nicht aus dem Schaubild nicht eindeutig ablesen." , correct = TRUE),
correct = "Richtig!",
incorrect = "Leider falsch: Mit Augenmaß ist der Zusammenhang nicht klar ersichtlich.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen",
random_answer_order = TRUE
),
question(
"Welche Anzahl an Events beobachten wir am meisten?",
answer("4"),
answer("1", correct = TRUE),
answer("3"),
answer("2"),
correct = "Richtig!",
incorrect = "Leider falsch: Die meisten Länder haben genau ein Event veranstaltet.",
allow_retry = TRUE,
try_again_button = "Nochmal versuchen"
)
)
```
Wenn wir uns das Punktediagramm ansehen, dass die Anzahl an Plastikstücken der Anzahl an Freiwilligen gegenüberstellt, ist ein etwas deutlicherer Zusammenhang erkenntlich. Der Korrelationskoeffizient bringt diesen statistischen Zusammenhang auf den Punkt in einer Zahl. Berechnet ihn für diese beiden Variablen.
```{r korrelation_pieces_volunteers, exercise=TRUE}
# Berechnung Korrelation
cor(community$n_pieces, community$n_volunteers)
```
0.81 bestätigt, dass wir einen positiven und recht starken statistischen Zusammenhang zwischen der Anzahl an Plastikstücken und Freiwilligen auf Länderebene beobachten. Aber Vorsicht: der Korrelationskoeffizient allein bietet **keinerlei Möglichkeit** einer **kausalen Aussage**. Weder unser Diagramm noch der Koeffizient lassen den Schluss zu, dass mehr Freiwillige die Ursache für mehr gesammelte Plastikstücken sind. Wir beobachten sie lediglich gleichzeitig. Außerdem muss auch hier wieder beachtet werden, dass die Aussage nur auf Länderebene getroffen werden kann: es kann nicht geschlossen werden, dass Events mit mehr Freiwilligen mehr Plastikstücke sammeln. Wir erinnern uns an das Stichwort "Ökologischer Fehlschluss" von oben.
```{r scatter_plot_n_volunteers}
# Optional: Erstellung eines Punktediagramms mit der Anzahl gesammelter Plastikstücke pro Kontinent
ggplot(data = community, aes(n_volunteers, n_pieces, label = country)) + # Initialisierung des ggplots mit Variablen
geom_point(position = position_jitter(seed = 3), size = 3, alpha = 0.5, color = "darkgrey") + # Hinzufügen der Datenpunkte (Scatterplot) inkl. Stylingoptionen zur Positionierung, Punktegröße, Transparenz und Farbe
geom_vline(xintercept=mean(community$n_volunteers), color= "darkgray") +
geom_hline(yintercept=mean(community$n_pieces), color= "darkgray") +
geom_line(stat="smooth", method = "lm", colour = "darkred", alpha= 0.5, size=1.5) + # Trendlinie hinzufügen
coord_cartesian(xlim = c(0, median(community$n_volunteers) + 3 * IQR(community$n_volunteers)), ylim = c(0, median(community$n_pieces) + 3 * IQR(community$n_pieces))) + # Festlegung der Achsenlänge der y-Achse abhängig von Median und Interquartilabstand
geom_text(size = 2) +
labs(
title = "Anzahl gesammelter Plastiksstücke bei 'Break Free From Plastic' ..." ,
subtitle = "... in Abhängigkeit von der Freiwilligenzahl pro Land",
x = "Anzahl Freiwillige",
y = "Anzahl gefundener Plastikstücke",
caption = glue::glue("n = {nrow(community)}\n Einige Ausreißer wurden zur Lesbarkeit des Graphen ausgeklammert. \nDatenquelle: TidyTuesday und BFFP")) + # Festlegung der Achsenbezeichungen, Überschriften und Titel
theme_minimal() # Festlegung des Layout-Designs
```
Was nehmen wir aus dieser bivariaten Analyse mit? Die Anzahl an Events korreliert nur sehr schwach positiv mit der Anzahl gesammelter Plastikstücke. Die Anzahl der Freiwilligen korreliert stark positiv mit der Anzahl an gesammelten Plastikstücken. Für diesen Zusammenhang kann es viele Ursachen geben, die wir in unseren Daten überhaupt nicht betrachten, zum Beispiel die Bevölkerungsanzahl oder auch die Zeit, welche einzelene Freiwillige investiert haben. Welche "Störfaktoren" fallen Euch noch ein?
### **Und jetzt Ihr**
Diese Woche möchten wir die Präsenzzeit nutzen, um die folgenden Übungen zu besprechen. Ergänzt unseren Input gerne zudem mit Euren **Ideen, Fragen, Anregungen oder Kommentaren**. Es ist nicht schlimm, falls diese Woche noch gar nichts (komplexes) klappt, da wir das Gelernte in den nächsten Wochen wiederholen und vertiefen werden.
1. Beantwortet anhand der präsentierten Datenanalyse die vorgestellten **Fragen**: <br>
- Wie viel Plastik wurde insgesamt gesammelt? <br>
- Wie viel Plastik wurde durchschnittlich je Kontinent gesammelt? <br>
- Welche Faktoren beeinflussen möglicherweise diese Unterschiede? <br>
2. Überlegt: Mit welchen Daten und Datenanalysen könnte die Frage "Wie erfolgreich war der Audit?" noch beantwortet werden? Wie könnte eine Visualisierung oder eine zusammenfassende Statistik dabei helfen? Skizziert Eure Fragen gerne schriftlich.
3. Versucht, das zugehörige **R Markdown: 04_daten-verstehen-mit-r-uebung.Rmd** (im [Übungsordner](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/CorrelAid/lernplattform/tree/main/uebungen){target="_blank"} unter 04_daten-verstehen-mir-r) zum Laufen zu bringen und es nachzuvollziehen.
4. In der ersten Einheit haben wir uns bei der Visualisierung vor allem der **n_pieces Variable** gewidmet. Nun blicken wir auf die **n_volunteers**: Wie sehr unterscheiden sich die Freiwilligenzahlen nach Kontinenten? Erstellt in dem heruntergeladenen RMarkdown ein **Punktediagramm** (Scatterplot) mit dem Datensatz `community` für diesen Blickwinkel auf den Erfolg der "Break Free from Plastic" Aktion. Die Graphik soll `n_volunteers`, die **Anzahl der Freiwilligen** auf der y-Achse und die **Kontinente** auf der x-Achse zeigen.
*Hinweis: Versucht dazu im RMarkdown in der finalen Version der Graphik die entsprechenden Variablen auszutauschen (und sonst erstmal nichts).*
5. Interpretiert die Graphik. Was könnt Ihr ablesen?
### **Zusätzliche Ressourcen**
- Die kostenlosen Kurse des [Statistischen Bundesamts](https://www.destatis.de/DE/Service/Statistik-Campus/E-Learning/eLearning-statistik.html;jsessionid=63AE25DDABD8853990FBE83F354C8911.live722?nn=206328){target="_blank"}
- Stocker T. C. und Steinke I. (2017): Statistik – Grundlagen und Methodik [verfügbar z.B. hier](https://www.beck-shop.de/stocker-steinke-de-gruyter-studium-statistik/product/32926361){target="_blank"}
- [R for Data Science (engl.)](https://r4ds.had.co.nz/){target="_blank"}
- [Statistics Fundamentals in R](https://app.dataquest.io/course/statistics-fundamentals-r){target="_blank"} auf DataQuest (engl.)
- [Lernvideos](https://www.youtube.com/watch?v=RRIsBFW8ovc){target="_blank"} zur Inferenzstatistik (dt.)