-
Notifications
You must be signed in to change notification settings - Fork 0
/
solutions_stat.Rmd
1604 lines (1201 loc) · 58.2 KB
/
solutions_stat.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
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Daten laden
Laden Sie die Data Frames `ai` und `asp` vom IPS-Server:
```{r}
url <- "http://www.phonetik.uni-muenchen.de/~jmh/lehre/Rdf"
ai <- read.table(file.path(url, "ai.txt"))
asp <- read.table(file.path(url, "asp.txt"))
```
# Q & A's
## 1. Basics
- **Q1.1**: *Erstellen Sie einen Vektor namens `num`, der diese Elemente enthält: 3, 10.15, -39.*
```{r}
num <- c(3, 10.15, -39.)
```
- **Q1.2**: *Summieren Sie mittels einer Funktion alle Elemente des Vektors `num`.*
```{r}
sum(num)
```
- **Q1.3**: *Multiplizieren Sie jedes Element des Vektors `num` mit 10 und speichern Sie das Ergebnis in einer Variable namens `x`.*
```{r}
x <- num * 10
x
```
- **Q1.4**: *Erstellen Sie die Schriftzeichen-Variable `name`, die Ihren Namen enthält.*
```{r}
name <- "floooo"
```
- **Q1.5**: *Nutzen Sie eine Funktion, um den Inhalt der Variable `name` drei Mal auszugeben.*
```{r}
rep(name, times = 3)
```
- **Q1.6**: *Erstellen Sie mit den Funktionen `c()` und `rep()` einen Vektor namens `buchstaben` mit dem Inhalt: "a" "a" "a" "b" "b" "b" "c" "c" "c" "d" "d" "d" "e" "e" "e".*
```{r}
buchstaben <- rep(c("a", "b", "c", "d", "e"), each = 3)
buchstaben
```
- **Q1.7**: *Lassen Sie sich mittels einer Funktion nur die einzigartigen Elemente des Vektors `buchstaben` ausgeben (d.h. entfernen Sie die Duplikate).*
```{r}
unique(buchstaben)
```
- **Q1.8**: *Überprüfen Sie, ob "b" und "f" im Vektor `buchstaben` vorkommen.*
```{r}
c("b", "f") %in% buchstaben
```
- **Q1.9**: *Erstellen Sie mittels einer Funktion einen Vektor mit dem Inhalt: "10.Z" "11.Z" "12.Z" "13.Z" "14.Z" "15.Z" "16.Z" "17.Z" "18.Z" "19.Z" "20.Z".*
```{r}
paste(c(10:20), "Z",sep=".")
paste(10:20, "Z", sep = ".")
```
- **Q1.10**: *Erstellen Sie mittels einer Funktion einen Vektor namens `z`, der folgende Elemente enthält: 1 1 3 3 6 6 1 1 3 3 6 6 1 1 3 3 6 6 1 1 3 3 6 6.*
```{r}
z <- rep(c(1,3,6), each=2, times=4)
z <- rep(c(1, 3, 6), each = 2, times = 4)
```
- **Q1.11**: *Überprüfen Sie, wie häufig die Zahlen 1, 3, und 6 im Vektor `z` vorkommen.*
```{r}
table(z)
```
- **Q1.12**: *Erstellen Sie mittels einer Funktion eine Zahlensequenz aus 15 Zahlen, die bei 1 beginnen und bei 35 aufhören.*
```{r}
seq(from = 1, to = 35, length.out = 15)
```
- **Q1.13**: *Erstellen Sie mittels einer Funktion eine Zahlensequenz von 100 beginnend rückwärts bis 50, wobei die Zahlen jeweils einen Abstand von 3.5 haben sollen. Speichern Sie das Ergebnis in der Variable `zahlen` ab.*
```{r}
zahlen <- seq(from = 100, to = 50, by = -3.5)
zahlen
```
- **Q1.14**: *Ziehen Sie die Quadratwurzel aus allen Zahlen im Vektor `zahlen`.*
```{r}
sqrt(zahlen)
```
- **Q1.15**: *Überprüfen Sie, welche Elemente des Vektors `zahlen` größer oder gleich 75 sind.*
```{r}
zahlen >= 75
```
## 2. Arbeit mit Data Frames
- **Q2.1**: *Lassen Sie sich die Dimensionen (Zeilen- und Spaltenzahl) des Data Frames `ai` ausgeben.*
```{r}
dim(ai)
```
- **Q2.2**: *Lassen Sie sich die Spaltennamen von `ai` ausgeben.*
```{r}
colnames(ai)
```
- **Q2.3**: *Recherchieren Sie, wie Sie sich den maximalen F1-Wert in `ai` ausgeben lassen können.*
```{r}
max(ai$F1)
```
- **Q2.4**: *Addieren Sie die Spalten `Lippe` und `Kiefer` aus dem Data Frame `ai` für jede Beobachtung.*
```{r}
ai$Lippe + ai$Kiefer
```
- **Q2.5**: *Subtrahieren Sie 100 von jedem F1-Wert in `ai`.*
```{r}
ai$F1 - 100
```
- **Q2.6**: *Lassen Sie sich die ersten Zeilen des Data Frames `asp` mittels einer Funktion ausgeben.*
```{r}
head(asp)
```
- **Q2.7**: *Verwenden Sie eine Funktion, um herauszufinden, wie oft die einzelnen Konsonanten in der Spalte `Kons` des Data Frames `asp` vorkommen.*
```{r}
table(asp$Kons)
```
# Daten & Packages laden
Laden Sie die folgenden Packages und Data Frames:
```{r}
library(tidyverse)
library(magrittr)
url <- "http://www.phonetik.uni-muenchen.de/~jmh/lehre/Rdf"
dip <- read.table(file.path(url, "dip.txt"), stringsAsFactors = T)
preasp <- read.table(file.path(url, "preasp.txt"), stringsAsFactors = T)
```
# Q & A's
## 1. Basics
- **Q1.1**: *Bestätigen Sie, dass die Variable `V` im Data Frame `dip` ein Faktor ist.*
```{r}
class(dip$V)
```
- **Q1.2**: *Was sind die Stufen von diesem Faktor?*
```{r}
levels(dip$V)
```
- **Q1.3**: *Wieviele einzigartige Elemente gibt es in der Variable `Vpn` im Data Frame `dip`?*
```{r}
length(unique(dip$Vpn))
```
- **Q1.4**: *Lassen Sie sich mittels einer Funktion die Vorkommenshäufigkeit der verschiedenen Vokale `V` im Data Frame `dip` anzeigen.*
```{r}
table(dip$V)
```
- **Q1.5**: *Finden Sie mittels `table()` heraus, wie viele Tokens pro Vokalkategorie `V` pro Versuchsperson `Vpn` es im Data Frame `dip` gibt.*
```{r}
table(dip$V, dip$Vpn)
dip %>% select(V, Vpn) %>% table()
```
## 2. Filtering & Selecting
- **Q2.1**: *Lassen Sie sich vom Data Frame `dip` die Beobachtungen 1-10 ausgeben.*
```{r}
dip %>% slice(1:10)
```
- **Q2.2**: *Lassen Sie sich vom Data Frame `dip` die Beobachtungen 15, 18, 20 der Variable `V` ausgeben.*
```{r}
dip %>%
slice(15, 18, 20) %>%
select(V)
```
- **Q2.3**: *Lassen Sie sich vom Data Frame `dip` die Variablen `d` und `V` für die zehn Beobachtungen mit den höchsten `d`-Werten ausgeben.*
```{r}
dip %>%
select(d, V) %>%
slice_max(d, n = 10)
```
- **Q2.4**: *Lassen Sie sich vom Data Frame `dip` die letzten vier Beobachtungen ausgeben.*
```{r}
dip %>% slice_tail(n = 4)
```
- **Q2.5**: *Lassen Sie sich vom Data Frame `dip` alle ungeraden Zeilen ausgeben. Tipp: Mit der Funktion `seq()` können Sie einen Vektor von ungeraden Ganzzahlen erzeugen.*
```{r}
dip %>% slice(seq(1, nrow(dip), by = 2))
```
- **Q2.6**: *Lassen Sie sich alle Beobachtungen aus `dip` ausgeben, wo die Versuchsperson `Vpn` 67 ist und `d` höher als 190. (Ergebnis hat 5 Zeilen und 3 Spalten)*
```{r}
dip %>% filter(Vpn == 67 & d > 190)
```
- **Q2.7**: *Lassen Sie sich die fünf Beobachtungen mit den niedrigsten `d`-Werten aus `dip` ausgeben, wo der Vokal `V` nicht "aU" und nicht "OY" ist.*
```{r}
dip %>%
filter(!V %in% c("aU", "OY")) %>%
slice_min(d, n = 5)
```
- **Q2.8**: *Lassen Sie sich die Variable `d` aus dem Data Frame `dip` als Vektor ausgeben.*
```{r}
dip %>%pull(d)
# or
c(dip$d)
```
- **Q2.9**: *Lassen Sie sich aus dem Data Frame `preasp` die ersten drei Beobachtungen für alle Variablen ausgeben, deren Spaltennamen auf "dur" endet.*
```{r}
preasp %>% select(ends_with("dur")) %>% slice(1:3)
preasp %>%
select(ends_with("dur")) %>%
slice_head(n = 3)
```
- **Q2.10**: *Lassen Sie sich aus dem Data Frame `preasp` die erste Beobachtung der Variablen `spk` bis `vc` ausgeben.*
```{r}
preasp %>%
select(spk:vc) %>%
slice(1)
```
## 3. Mutating & Renaming
- **Q3.1**: *Benennen Sie die Variablen im Data Frame `dip` dauerhaft um in `Dauer`, `Vokal`, `Versuchsperson`.*
```{r}
dip %<>% rename(Dauer=d, Vokal=V, Versuchsperson=Vpn)
```
- **Q3.2**: *Hängen Sie an den Data Frame `dip` temporär eine Spalte namens `Index` an, die die Zahlen von 1 bis 186 enthält.*
```{r}
dip %>% mutate(Index = 1:186)
```
- **Q3.3**: *Hängen Sie an den Data Frame `dip` dauerhaft eine Spalte namens `Länge` an, die den Wert "lang" enthält, wenn die Dauer höher ist als 200, "kurz" für Dauerwerte unter 100, und "mittel" für alle anderen Dauerwerte.*
```{r}
dip %<>% mutate(Länge = case_when(Dauer > 200 ~ "lang",
Dauer < 100 ~ "kurz",
Dauer > 100 & Dauer < 200 ~ "mittel"))
dip %>% head()
```
- **Q3.4**: *Hängen Sie an den Data Frame `dip` dauerhaft eine Spalte namens `Region` an, die den Wert "Bayern" enthält für die Versuchsperson 67 und "Berlin" für die Versuchsperson 68.*
```{r}
dip %<>% mutate(Region = ifelse(Versuchsperson == 67, "Bayern", "Berlin"))
dip %>% head()
```
# Daten & Packages laden
Laden Sie die folgenden Packages und Data Frames:
```{r}
library(tidyverse)
library(magrittr)
url <- "http://www.phonetik.uni-muenchen.de/~jmh/lehre/Rdf"
rating <- read.table(file.path(url, "rating.txt"))
preasp <- read.table(file.path(url, "preasp.txt"))
asp <- read.table(file.path(url, "asp.txt"))
vdata <- read.table(file.path(url, "vdata.txt"))
```
# Q & A's
## 1. Datenmanipulation mit `dplyr`
- **Q1.1**: *Benennen Sie die Spalten `vdur`, `clodur`, `vtype` im Data Frame `preasp` dauerhaft um in `vowelDuration`, `closureDuration` und `vowelType`, und lassen Sie sich die Spaltennamen des Data Frames anzeigen.*
```{r}
preasp %<>% rename(vowelDuration = vdur,
closureDuration = clodur,
vowelType = vtype)
preasp %>% colnames()
```
- **Q1.2**: *Finden Sie heraus, welche Vokale (`vowelType`) im Data Frame `preasp` mit den fünf höchsten Vokaldauern (`vowelDuration`) assoziiert sind. (Ergebnis ist ein Vektor mit 5 Elementen)*
```{r}
preasp %>%
slice_max(vowelDuration, n = 5) %>%
pull(vowelType)
```
- **Q1.3**: *Berechnen Sie für die drei verschiedenen Konsonanten (`cplace`) im Data Frame `preasp` die maximale, minimale und durchschnittliche Verschlussdauer (`closureDuration`) und sortieren Sie das Ergebnis nach absteigender durchschnittlicher Verschlussdauer. (Ergebnis hat 3 Zeilen und 4 Spalten)*
```{r}
preasp %>%
group_by(cplace) %>%
summarise(minimum = min(closureDuration),
maximum = max(closureDuration),
mittel = mean(closureDuration)) %>%
arrange(desc(mittel))
```
- **Q1.4**: *Berechnen Sie für alle Beobachtungen, wo der Vokal "a" und die Region ungleich "C" ist, die Standardabweichung der Vokaldauer pro Region und Stadt. (Ergebnis hat 12 Zeilen und 3 Spalten)*
```{r}
preasp %>%
filter(vowelType == "a" & region != "C") %>%
group_by(region, city) %>%
summarise(stdabw = sd(vowelDuration))
```
- **Q1.5**: *Berechnen Sie pro Versuchsperson (`Vpn`) das erste und dritte Quartil des Ratings im Data Frame `rating`. (Ergebnis hat 26 Zeilen und 3 Spalten)*
```{r}
rating %>%
group_by(Vpn) %>%
summarise(Q1 = quantile(Rating, 0.25),
Q3 = quantile(Rating, 0.75))
```
- **Q1.6**: *Berechnen Sie für die ersten 100 Beobachtungen im Data Frame `rating` den Median und den Mittelwert der Ratings pro Sprache (`Lang`). (Ergebnis hat 2 Zeilen und 3 Spalten)*
```{r}
rating %>%
slice(1:100) %>%
group_by(Lang) %>%
summarise(med = median(Rating),
mit = mean(Rating))
```
- **Q1.7**: *Finden Sie heraus, wie viele Beobachtungen es pro Versuchsperson (`Vpn`) im Data Frame `rating` gibt. (Ergebnis hat 26 Zeilen und 2 Spalten)*
```{r}
rating %>%
group_by(Vpn) %>%
summarise(count = n())
```
- **Q1.8**: *Finden Sie heraus, wie viele einzigartige Sprecher `spk` es pro Stadt, Region und Konsonant (`cplace`) im Data Frame `preasp` gibt (Ergebnis hat 45 Zeilen und 4 Spalten). Lassen Sie sich anschließend ausgeben, für welche Kombination(en) aus Stadt, Region und Konsonant es die wenigsten einzigartigen Sprecher gibt. Tipp: Hierfür müssen Sie sicherstellen, dass das Ergebnis des ersten Teils ein ungruppierter Data Frame ist.*
```{r}
preasp %>%
group_by(city, region, cplace) %>%
summarise(count = n_distinct(spk)) %>%
ungroup() %>%
slice_min(count, n = 1)
# Alternative:
preasp %>%
group_by(city, region, cplace) %>%
summarise(count = n_distinct(spk), .groups = "drop") %>%
slice_min(count, n = 1)
```
## 2. Abbildungen mit `ggplot2`
- **Q2.1**: *Zeigen Sie mittels eines Barplots mit dem Data Frame `asp`, inwiefern der Konsonantentyp (`Kons`) von der Betonung (`Bet`) beeinflusst wird. Auf der x-Achse soll die Betonung angezeigt werden, die Füllfarbe der Balken soll sich nach dem Konsonantentyp richten. Die Balken sollen Proportionen anzeigen. Schreiben Sie unter Ihrem Code Ihre Einschätzung zu der Fragestellung als Kommentar auf.*
```{r}
ggplot(asp) +
aes(x = Bet, fill = Kons) +
geom_bar(position = "fill")
# Ihre Einschätzung:
# Der Konsonant k kommt deutlich häufiger in betonter Position vor,
# während der Konsonant t deutlich häufiger in unbetonter Position vorkommt.
```
- **Q2.2**: *Erstellen Sie ein Histogramm über die Ratings im Data Frame `rating`, wobei die Balken eine Breite von 0.5 haben und weiß umrandet sein sollen.*
```{r}
ggplot(rating) +
aes(x = Rating) +
geom_histogram(binwidth = 0.5,
color = "white")
```
- **Q2.3**: *Erstellen Sie die Abbildung aus Q2.2 erneut, aber diesmal mit der Wahrscheinlichkeitsdichte auf der y-Achse.*
```{r}
ggplot(rating) +
aes(x = Rating, y = ..density..) +
geom_histogram(binwidth = 0.5,
color = "white")
```
- **Q2.4**: *Erstellen Sie einen Scatterplot über alle Beobachtungen des Data Frames `vdata`, bei denen der Vokal (`V`) entweder "A" oder "I" oder "U" ist. F1 soll auf der y- und F2 auf der x-Achse sein.*
```{r}
vdata %>%
filter(V %in% c("A", "I", "U")) %>%
ggplot() +
aes(x = F2, y = F1) +
geom_point()
```
- **Q2.5**: *Erstellen Sie einen Boxplot für F2 pro Versuchsperson (`Subj`) im Data Frame `vdata`. Fügen Sie dem Boxplot außerdem noch eine horizontale Linie bei 1500 Hz hinzu.*
```{r}
ggplot(vdata) +
aes(x = Subj, y = F2) +
geom_boxplot() +
geom_hline(yintercept = 1500)
```
- **Q2.6**: *Erstellen Sie einen Barplot mit dem Data Frame `preasp`, bei dem die Region auf der x-Achse liegt und die Füllfarbe den Vokaltyp (`vowelType`) angibt. Es sollen hier nur Beobachtungen verwendet werden, für die die Vokaldauer `vowelDuration` zwischen 0.09 und 0.18 liegt. Die Balken sollen außerdem nebeneinander liegen.*
```{r}
preasp %>%
filter(vowelDuration > 0.09 & vowelDuration < 0.18) %>%
ggplot() +
aes(x = region, fill = vowelType) +
geom_bar(position = "dodge")
```
# Daten & Packages laden
Laden Sie die folgenden Packages und Data Frames:
```{r}
library(tidyverse)
library(magrittr)
url <- "http://www.phonetik.uni-muenchen.de/~jmh/lehre/Rdf"
rating <- read.table(file.path(url, "rating.txt")) %>% as_tibble()
preasp <- read.table(file.path(url, "preasp.txt")) %>% as_tibble()
vcv <- read.table(file.path(url, "vcvC.txt")) %>% as_tibble()
vdata <- read.table(file.path(url, "vdata.txt")) %>% as_tibble()
hp_looks <- read.csv(file.path(url, "hp_looks.txt"), sep="") %>% as_tibble()
hp_measures <- read.csv(file.path(url, "hp_measures.txt"), sep="") %>% as_tibble()
hp_meta <- read.csv(file.path(url, "hp_meta.txt"), sep="") %>% as_tibble()
hp_names <- read.csv(file.path(url, "hp_names.txt"), sep="") %>% as_tibble()
hp_wiz <- read.csv(file.path(url, "hp_wiz.txt"), sep="") %>% as_tibble()
p <- read.table(file.path(url, "param.txt"), stringsAsFactors = F) %>%
dplyr::filter(nchar(Vpn) > 4) %>%
as_tibble()
```
# Q & A's
## 1. Datenmanipulation mit `dplyr` & `tidyr`
- **Q1.1**: *Benennen Sie die Spalten `x`, `y` und `z` im Data Frame `diamonds` (wird automatisch mit dem tidyverse geladen) um in `laenge`, `breite` und `tiefe`. Erstellen Sie dann durch pivoting eine neue Spalte `measure` aus den drei umbenannten Spalten und eine neue Spalte `value`, die deren Werte enthält.*
```{r}
diamonds %>%
rename(laenge = x,
breite = y,
tiefe = z) %>%
pivot_longer(cols = c(laenge, breite, tiefe),
names_to = "measure",
values_to = "value")
```
- **Q1.2**: *In der Spalte `Vpn` des Data Frames `p` befinden sich drei Informationen: Alter, Region und Staat, getrennt durch Unterstriche. Teilen Sie die Informationen dauerhaft in drei neue, sinnvoll benannte Spalten auf.*
```{r}
p %<>%
separate(col = "Vpn",
into = c("age", "region", "country"),
sep = "_")
```
- **Q1.3**: *Lassen Sie sich aus dem Data Frame `p` alle Beobachtungen ausgeben, wo die Versuchsperson zwischen 85 und 90 Jahren alt, der Context `Cont` "mie" und der Messwert `slopes` größer oder gleich 1.0 ist. (Ergebnis hat 2 Zeilen und 6 Spalten)*
```{r}
p %>% filter(age > 85 & age < 90 &
Cont == "mie" &
slopes >= 1.0)
```
- **Q1.4**: *Wählen Sie aus dem Data Frame `vdata` die Spalten `F1` bis `Cons` aus sowie alle Beobachtungen, für die die Versuchsperson `Subj` nicht "bk" oder "hp" oder "ta" ist; formen Sie den Data Frame dann so um, dass die Formanten F1 und F2 in einer neuen Spalte `formant` und die F1- und F2-Werte in einer neuen Spalte `value` erscheinen. (Ergebnis hat 3424 Zeilen und 6 Spalten)*
```{r}
vdata %>%
filter(!Subj %in% c("bk", "hp", "ta")) %>%
select(F1:Cons) %>%
pivot_longer(cols = c(F1, F2), names_to = "formant", values_to = "value")
```
- **Q1.5**: *Finden Sie die durchschnittliche Reaktionszeit `RT` pro Versuchsperson `Subject`, Vokal `Vowel` und Sprache `Lang` im Data Frame `vcv` heraus. Fügen Sie dem daraus resultierenden Data Frame eine Spalte namens `tempo` hinzu, die folgende Werte enthält: "schnell" für alle mittleren Reaktionszeiten unter 500 ms, "mittel" für Reaktionszeiten zwischen 500 und 575 ms, "okay" für Reaktionszeiten zwischen 575 und 650 ms, "langsam" für Reaktionszeiten zwischen 650 und 800 ms, und "sehr langsam" für alle Reaktionszeiten über 800 ms. Finden Sie anschließend heraus, wie häufig jeder Wert der Variable `tempo` vorkommt. (Ergebnis hat 5 Zeilen und 2 Spalten)*
```{r}
vcv %>%
group_by(Subject, Vowel, Lang) %>%
summarise(mean_rt = mean(RT)) %>%
mutate(tempo = case_when(mean_rt < 500 ~ "schnell",
mean_rt > 500 & mean_rt < 575 ~ "mittel",
mean_rt > 575 & mean_rt < 650 ~ "okay",
mean_rt > 650 & mean_rt < 800 ~ "langsam",
mean_rt > 800 ~ "sehr langsam")) %>%
group_by(tempo) %>%
summarise(count = n())
```
## 2. Magical Joining mit `dplyr`
- **Q2.1**: *Verbinden Sie die beiden Data Frames `hp_names` und `hp_meta` so miteinander, dass alle Beobachtungen und alle Spalten aus beiden Data Frames im Ergebnis erhalten bleiben. Nutzen Sie die Spalte `id` als key. Es gibt hier verschiedene Lösungswege.*
```{r}
inner_join(hp_names, hp_meta, by = "id")
full_join(hp_names, hp_meta, by = "id")
left_join(hp_names, hp_meta, by = "id")
right_join(hp_meta, hp_names, by = "id")
```
- **Q2.2**: *Verbinden Sie die Data Frames `hp_names` und `hp_wiz` über die Spalte `id`, sodass nur Zeilen aus `hp_wiz` erhalten bleiben und das Ergebnis die Spalten beider Data Frames enthält. Es gibt hier verschiedene Lösungswege.*
```{r}
inner_join(hp_names, hp_wiz, by = "id")
right_join(hp_names, hp_wiz, by = "id")
left_join(hp_wiz, hp_names, by = "id")
```
- **Q2.3**: *Verbinden Sie die Data Frames `hp_names` und `hp_wiz` über die Spalte `id`, sodass alle Zeilen aus `hp_names` erhalten bleiben und das Ergebnis die Spalten beider Data Frames enthält. Fehlende Werte sollen als `NA` im Ergebnis erscheinen. Es gibt hier verschiedene Lösungswege.*
```{r}
right_join(hp_wiz, hp_names, by = "id")
left_join(hp_names, hp_wiz, by = "id")
full_join(hp_names, hp_wiz, by = "id")
```
- **Q2.4**: *Verbinden Sie die Data Frames `hp_names` und `hp_looks` über die Spalte `id`, sodass alle Beobachtungen und alle Spalten aus beiden Data Frames erhalten bleiben und die Spalten notfalls mit `NA` gefüllt werden. Hier gibt es nur eine Lösung.*
```{r}
full_join(hp_names, hp_looks, by = "id")
```
- **Q2.5**: *Finden Sie mittels eines filtering joins über die Spalte `id` heraus, für welche Beobachtungen in `hp_looks` es keinen Match in `hp_names` gibt. Hier gibt es nur eine Lösung.*
```{r}
anti_join(hp_looks, hp_names, by = "id")
```
- **Q2.6**: *Finden Sie mittels eines filtering joins über die Spalte `id` heraus, für welche Beobachtungen in `hp_names` es keinen Match in `hp_looks` gibt. Hier gibt es nur eine Lösung.*
```{r}
anti_join(hp_names, hp_looks, by = "id")
```
- **Q2.7**: *Verbinden Sie die Data Frames `hp_names` und `hp_looks` über die Spalte `id`, sodass alle Beobachtungen und alle Spalten aus beiden Data Frames erhalten bleiben, für die es einen Match in beiden Data Frames gibt (keine neu erzeugten `NA`-Werte im Ergebnis). Hier gibt es nur eine Lösung.*
```{r}
inner_join(hp_names, hp_looks, by = "id")
```
- **Q2.8**: *Finden Sie mittels eines filtering join über die Spalte `id` heraus, für welche Personen in `hp_names` es Messwerte in `hp_measures` gibt. Hier gibt es nur eine Lösung.*
```{r}
semi_join(hp_names, hp_measures, by = "id")
```
## 3. Abbildungen mit `ggplot2`
Bei allen folgenden Plots dürfen Sie gerne mit den `ggplot2` Spezifikationen spielen: Verändern Sie die Farben, Punkt-Shapes, Linientypen, Schriftgröße, Achsenbeschriftungen...
- **Q3.1**: *Erstellen Sie einen Density Plot anhand des Data Frames `rating`. Auf der x-Achse soll das Rating angezeigt werden. Trennen Sie Panels nach Familiarität `Fam` in Zeilen und Sprache `Lang` in Spalten.*
```{r}
ggplot(rating) +
aes(x = Rating) +
geom_density() +
facet_grid(Fam~Lang)
```
- **Q3.2**: *Zeigen Sie anhand des Data Frames `preasp` mit einem Boxplot den Einfluss von Artikulationsstelle `cplace` auf die Verschlussdauer `clodur`. Farbkodieren Sie die Boxplots nach Artikulationsstelle und erstellen Sie verschiedene Panels für die Variable Region. Schreiben Sie unter Ihrem Code Ihre Einschätzung zu der Fragestellung als Kommentar auf.*
```{r}
ggplot(preasp) +
aes(x=cplace, y =clodur, fill=cplace) +
geom_boxplot()+
facet_wrap(~region)
ggplot(preasp) +
aes(x = cplace, y = clodur, fill = cplace) +
facet_wrap(~region) +
geom_boxplot()
# Ihre Einschätzung:
# Die Verschlussdauer ist am kürzesten in kk und am längsten in tt.
# Die Regionen unterscheiden sich diesbezüglich kaum.
```
- **Q3.3**: *Erstellen Sie ein Histogramm über die Reaktionszeiten `RT` im Data Frame `vcv` mit einer Balkenbreite von 75. Stellen Sie die drei Vokale in getrennten Panels dar.*
```{r}
ggplot(vcv) +
aes(x=RT) +
facet_wrap(~Vowel)+
geom_histogram(binwidth = 75)
ggplot(vcv) +
aes(x = RT) +
facet_wrap(~Vowel) +
geom_histogram(color = "green", binwidth = 100)
```
- **Q3.4**: *Erstellen Sie einen Lineplot mit allen Beobachtungen aus dem Data Frame `billboard` für die folgenden Künstler `artist`: "No Doubt", "Spears, Britney", "TLC", "Aguilera, Christina", "Backstreet Boys, The", "Pink", "Destiny's Child". Auf der y-Achse soll das Ranking und auf der x-Achse die Kalenderwoche aufgetragen werden -- dazu müssen Sie die Spalten `rank` und `week` mittels pivoting erstellen. Nutzen Sie außerdem die Funktion `factor()` innerhalb von `mutate()`, um die Werte in der Spalte `week` in einen Faktor mit den Levels 1 bis 32 umzuwandeln. Die Linien sollen nach dem Künstler farbkodiert werden. Da es pro Künstler zum Teil mehrere Songs in den Charts gibt, müssen Sie den aesthetic mappings noch `group = track` hinzufügen.*
```{r}
billboard %>%
filter(artist %in% c("No Doubt", "Spears, Britney", "TLC", "Aguilera, Christina",
"Backstreet Boys, The", "Pink", "Destiny's Child")) %>%
pivot_longer(cols = starts_with("wk"),
names_to = "week",
values_to = "rank",
names_prefix = "wk",
values_drop_na = TRUE) %>%
mutate(week = factor(week, levels = 1:32)) %>%
ggplot() +
aes(x = week, y = rank, col = artist, group = track) +
geom_line()
```
- **Q3.5**: *Erstellen Sie einen traditionell-phonetischen Formantplot (d.h. einen Scatterplot) mit dem Data Frame `vdata`. Wählen Sie zuerst nur die Zeilen aus dem Data Frame aus, wo der Vokal `V` entweder "A" oder "I" oder "U" ist. F2 gehört auf die x- und F1 auf die y-Achse. Farbkodieren Sie die Abbildung nach Vokal und erstellen Sie verschiedene Panels für die einzelnen Versuchspersonen `Subj`. Sorgen Sie zuletzt dafür, dass die Achsen jeweils umgedreht werden, also von hohen zu niedrigen Werten; nutzen Sie dafür die folgenden zwei Funktionen: `scale_x_reverse()` und `scale_y_reverse()`.*
```{r}
vdata %>%
filter(V %in% c("A", "I", "U")) %>%
ggplot() +
aes(x = F2, y = F1, col = V) +
facet_wrap(~Subj) +
scale_x_reverse() +
scale_y_reverse() +
geom_point()
```
- **Q3.6**: *Just for fun: Nutzen Sie die `hp...` Data Frames, um sich ein paar magische Plots auszudenken!*
```{r}
hp <- inner_join(hp_names, hp_measures, by = "id") %>%
left_join(hp_looks, by = "id") %>%
left_join(hp_meta, by = "id") %>%
left_join(hp_wiz, by = "id")
hp %>%
filter(year != "2016") %>%
ggplot() +
aes(x = year, y = f0, col = name) +
geom_line(size = 2)
hp %>%
mutate(year = factor(year, levels = c(1991:1997, 2016))) %>%
filter(!is.na(f0)) %>%
ggplot() +
aes(x = year, y = f0, group = name) +
geom_line(size = 1.2) +
facet_wrap(~name)
hp %>%
filter(!is.na(eyeColour) & !is.na(house)) %>%
ggplot() +
aes(x = house, fill = eyeColour) +
geom_bar(position = "fill")
hp %>%
filter(!is.na(house) & !is.na(f0)) %>%
ggplot() +
aes(y = f0, fill = house) +
geom_boxplot()
hp %>%
filter(!is.na(house) & !is.na(f0)) %>%
ggplot() +
aes(x=house, y = f0, fill = gender) +
geom_boxplot()
```
# Daten & Packages laden
Laden Sie die folgenden Packages und Data Frames:
```{r}
library(tidyverse)
url <- "http://www.phonetik.uni-muenchen.de/~jmh/lehre/Rdf"
flights <- read.table("https://raw.githubusercontent.com/Rdatatable/data.table/master/vignettes/flights14.csv",
sep = ",", header = T, stringsAsFactors = T) %>% as_tibble()
vcv <- read.table(file.path(url, "vcv.txt")) %>% as_tibble()
lose <- read.table(file.path(url, "lose.txt"), header = T) %>% as_tibble()
vlax <- read.table(file.path(url, "vlax.txt")) %>% as_tibble()
```
# Q & A's
## 1. Grundlagen Wiederholung
- **Q1.1**: *Der Data Frame `flights` enthält Daten über Flüge, die im Jahr 2014 zwischen Januar und Oktober an einem der New York City Flughäfen starteten. Wählen Sie nur Zeilen für den Monat Januar aus. Finden Sie pro Fluggesellschaft `carrier` heraus, was die minimale, maximale und durchschnittliche Verpätung beim Abflug `dep_delay` war. Sortieren Sie nach absteigender durchschnittlicher Verspätung. (Ergebnis hat 13 Zeilen und 4 Spalten)*
```{r}
flights %>%
filter(month == 1) %>%
group_by(carrier) %>%
summarise(minDelay = min(dep_delay),
maxDelay = max(dep_delay),
meanDelay = mean(dep_delay)) %>%
arrange(desc(meanDelay))
```
- **Q1.2**: *Erstellen Sie im Data Frame `flight` eine neue Spalte namens `date`, die die Werte aus den Spalten `year`, `month` und `day` durch einen Bindestrich getrennt enthält. Finden Sie heraus, an welchem Datum die höchste und niedrigste Verspätung bei Ankunft `arr_delay` vorkam.*
```{r}
flights %>%
mutate(date = paste(year, month, day, sep = "-")) %>%
filter(arr_delay %in% range(arr_delay)) %>%
select(date, arr_delay)
```
- **Q1.3**: *Erstellen Sie einen Boxplot, der die Flugzeit `air_time` für die verschiedenen Fluggesellschaften `carrier` zeigt und färben Sie die Boxplots nach den drei NYC Flughäfen `origin`.*
```{r}
ggplot(flights) +
aes(x = carrier, y = air_time, fill = origin) +
geom_boxplot()
# Alternative
ggplot(flights) +
aes(x = origin, y = air_time, fill = origin) +
facet_wrap(~carrier) +
geom_boxplot()
```
- **Q1.4**: *Erstellen Sie einen Scatterplot, der den Einfluss von Länge der Strecke `distance` auf die Flugzeit `air_time` für alle Flüge zwischen 1500 und 2000 Meilen zeigt.*
```{r}
flights%>%
filter(distance >1500 & distance<2000) %>%
ggplot()+
aes(x=distance, y=air_time)+
geom_point()
flights %>%
filter(distance > 1500 & distance < 2000) %>%
ggplot() +
aes(x = distance, y = air_time) +
geom_point()
```
## 2. Normalverteilung
- **Q2.1**: *Testen Sie mit allen Ihnen zur Verfügung stehenden Mitteln, ob die Reaktionszeit `RT` im Data Frame `vcv` normalverteilt ist und geben Sie abschließend Ihre Einschätzung dazu ab.*
```{r}
# Überlagerung der Normalverteilung:
# großer Unterschied zwischen empirischer und theoretischer Verteilung
ggplot(vcv) +
aes(x = RT) +
geom_density() +
stat_function(fun = dnorm,
args = list(mean = mean(vcv$RT), sd = sd(vcv$RT)),
color = "yellow")
# Q-Q-Plot:
# Abweichungen der Datenpunkte von der Linie, vor allem im hohen Wertebereich
ggplot(vcv) +
aes(sample = RT) +
stat_qq() +
stat_qq_line() +
ylab("samples") +
xlab("theoretical quantiles")
# Shapiro-Wilk-Test:
# p < 0.001, d.h. nicht normalverteilt
shapiro.test(vcv$RT)
# Ihre Einschätzung:
# Die Reaktionszeit ist eindeutig nicht normalverteilt. Wie man am Q-Q-Plot sehen kann, sind vor allem im
# hohen Wertebereich die gemessenen Reaktionszeiten deutlich höher als sie es bei normalverteilten Daten wären.
```
- **Q2.2**: *Auf der Kirmes gibt es einen ganz besonderen Losstand, bei dem auf jedem der insgesamt 5000 Lose eine Ganzzahl steht; die Ganzzahlen auf den Losen folgen einer Normalverteilung, d.h. es gibt deutlich mehr Lose, auf denen einen Zahl in der Nähe vom Mittelwert steht, als Lose mit sehr niedrigen oder sehr hohen Werten. Einen Preis kann man an dem Losstand nur gewinnen, wenn man ein Los mit einer Zahl unter 333 oder über 3333 zieht. Berechnen Sie das 95%-Konfidenzintervall für die Normalverteilung, die den Losen im Data Frame `lose` entspricht. Schätzen Sie anhand dessen, wie gut die Chancen stehen, an diesem Losstand einen Preis zu gewinnen.*
```{r}
mittel <- mean(lose$wert)
stdabw <- sd(lose$wert)
qnorm(0.025, mittel, stdabw)
qnorm(0.975, mittel, stdabw)
# Ihre Einschätzung,
# Da sowohl 333 als auch 3333 außerhalb des Konfidenzintervalls liegt, stehen die Chancen schlecht.
```
- **Q2.3**: *Berechnen Sie jetzt, wie hoch genau die Wahrscheinlichkeit ist, dass Sie bei den Losen einen Wert unter 333 oder über 3333 ziehen.*
```{r}
(pnorm(333, mittel, stdabw) + (1 - pnorm(3333, mittel, stdabw))) * 100
# Die Wahrscheinlichkeit liegt bei ca. 0.41%.
```
- **Q2.4**: *Berechnen Sie, wie hoch die Wahrscheinlichkeit ist, ein Los zu ziehen, auf dem eine Ganzzahl zwischen 1500 und 2500 steht.*
```{r}
(pnorm(2500, mean = mittel, sd = stdabw) - pnorm(1500, mean = mittel, sd = stdabw)) * 100
# Die Wahrscheinlichkeit liegt bei ca. 68.5%.
```
## 3. Einfache lineare Regression
- **Q3.1**: *Berechnen Sie für den Data Frame `vlax` die Korrelation zwischen F1 und F2 und erläutern Sie das Ergebnis.*
```{r}
cor(vlax$F1, vlax$F2)
# Es gibt eine moderate negative Korrelation, d.h. je höher F1, desto niedriger F2 (oder andersherum --
# der kausale Zusammenhang ist hier unklar).
```
- **Q3.2**: *Berechnen Sie für den Data Frame `vlax` die Korrelation zwischen F1 und F3 und erläutern Sie das Ergebnis.*
```{r}
cor(vlax$F1, vlax$F3)
# Es gibt keine Korrelation zwischen F1 und F3.
```
- **Q3.3**: *Erstellen Sie eine Abbildung samt Regressionslinie für den Zusammenhang zwischen F1 und F2 im Data Frame `vlax`.*
```{r}
ggplot(vlax) +
aes(x = F1, y = F2) +
geom_point() +
geom_smooth(method = "lm", se = F)
```
- **Q3.4**: *Nennen Sie drei Eigenschaften von Regressionslinien der linearen Regression.*
```{r}
# Die Regressionslinie einer linearen Regression ist per definitionem gerade und unendlich lang.
# Die Regressionslinie schneidet den Mittelwert der beiden Variablen.
# Die Regressionslinie wird per least squares Verfahren berechnet, d.h. so, dass alle Punkte den geringst möglichen Abstand zur Linie haben.
```
# Daten & Packages laden
Laden Sie die folgenden Packages und Data Frames:
```{r}
library(tidyverse)
library(broom)
url <- "http://www.phonetik.uni-muenchen.de/~jmh/lehre/Rdf"
vlax <- read.table(file.path(url, "vlax.txt")) %>% as_tibble()
v.df <- read.table(file.path(url, "v.df.txt"))
```
# Q & A's
## 1. Grundlagen Wiederholung
- **Q1.1**: *Zeigen Sie anhand einer Abbildung mit dem Data Frame `vlax`, ob sich die beiden Versuchspersonen `Vpn` in ihrer Grundfrequenz `f0` unterscheiden. Notieren Sie Ihre Einschätzung zu dieser Frage.*
```{r}
ggplot(vlax) +
aes(x = Vpn, y = f0) +
geom_boxplot()
# Die Versuchsperson V67 hat eine deutlich niedrigere Grundfrequenz als V68.
```
- **Q1.2**: *Erstellen Sie einen klassischen Formantplot mit dem Data Frame `vlax`. Farbkodieren Sie die verschiedenen Vokale `V` und erstellen Sie verschiedene Panels für die Versuchspersonen.*
```{r}
ggplot(vlax) +
aes(x = F2, y = F1, col = V) +
geom_point() +
facet_wrap(~Vpn) +
scale_x_reverse() +
scale_y_reverse()
```
- **Q1.3**: *Wählen Sie aus dem Data Frame `vlax` alle Zeilen aus, bei denen der Vokal entweder "I" oder "O" ist und bei denen die Grundfrequenz ungleich Null ist. Zeigen Sie mittels einer Abbildung für diese Zeilenauswahl, ob es einen linearen Zusammenhang zwischen Grundfrequenz `f0` und Schalldruck `dB` gibt (farbkodiert nach Vokal `V`). Notieren Sie kurz Ihre Einschätzung zu dieser Fragestellung und begründen Sie, weshalb Sie welche Variable auf die x- bzw. y-Achse gesetzt haben.*
```{r}
vlax %>%
filter(V %in% c("O", "I") & f0 != 0) %>%
ggplot() +
aes(x = dB, y = f0, col = V) +
geom_point() +
geom_smooth(method = "lm", se = F)
# Je höher der Schalldruck, desto höher die Grundfrequenz --
# d.h. je lauter die Versuchspersonen sprachen, desto höher wurden ihre Stimmen.
# Deshalb gehört f0 als die abhängige Variable auf die y-Achse.
# Der lineare Zusammenhang ist nur bei "I" zu sehen.
```
## 2. Einfache lineare Regression (1)
- **Q2.1**: *Berechnen und interpretieren Sie die Korrelation* $r$ zwischen Grundfrequenz `f0` und Schalldruck `dB` im Data Frame `vlax`, getrennt für die Vokale "I" und "O" für alle Zeilen, bei denen f0 ungleich Null ist.
```{r}
vlax %>%
filter(V %in% c("O", "I") & f0 != 0) %>%
group_by(V) %>%
summarise(r = cor(f0, dB))
# Es gibt eine starke positive Korrelation zwischen f0 und Schalldruck für "I",
# d.h. je lauter das "I", desto höher die Grundfrequenz. Die Korrelation für "O"
# ist hingegen schwach und negativ.
```
- **Q2.2**: *Erstellen Sie einen neuen Data Frame namens `df`, der alle Zeilen aus `vlax` enthält, für die der Vokal `V` "I" ist und f0 ungleich Null. Finden Sie durch eine einfache lineare Regression heraus, ob die Grundfrequenz vom Schalldruck abhängig ist. Berichten Sie das Ergebnis.*
```{r}
df <- vlax %>% filter(V == "I" & f0 != 0)
df.lm <- lm(f0 ~ dB, data = df)
summary(df.lm)
# Es besteht eine signifikante lineare Beziehung zwischen dem Schalldruck in dB und der
# Grundfrequenz f0 ($R^2$ = 0.35, $F$[1, 145] = 77.8, $p$ < 0.001).
#F-statistic: 77.81 on 1 and 145 DF, p-value: 3.294e-15
```