/
stat-modeling-survey.qmd
993 lines (725 loc) · 93.9 KB
/
stat-modeling-survey.qmd
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
```{r echo = FALSE}
pacman::p_load(tidyverse, readxl, knitr, kableExtra, see)
```
# Fragebogenanalyse {#sec-modeling-survey}
*Letzte Änderung am `r format(fs::file_info("stat-modeling-survey.qmd")$modification_time, '%d. %B %Y um %H:%M:%S')`*
> *"It’s always further than it looks. It’s always taller than it looks. And it’s always harder than it looks." --- The Three Rules of Mountaineering [@story2019survey]*
Der Fragebogen. Ein kompliziertes Stück in der Gesamtbetrachtung. Zum einen ist es die Auswertung der Fragebögen, die auf verschiedenen Methoden basiert. Viele der Methoden habe ich in den vorherigen Kapiteln vorgestellt. Zum anderen können wir hier auch das Design eines Fragebogens nicht unberücksichtigt lassen. Denn ein schlechter Fragebogen wird uns auch nur schlechte Erkenntnisse bringen. Dank der heutigen Technik ist ja ein Online-Query über [Lime Survey \| LifeSurvey](https://www.limesurvey.org/de) schnell erstellt. Der Fragebogen muss dann aber dennoch die Forschungsfragen beantworten können. Da fängt dann der komplizierte Teil an sich zu Überlegen, was mache ich jetzt eigentlich mit den ganzen Fragen und möglichen Antworten. Wir auch in anderen Kapiteln bin ich kein Experte für die Erstellung eines Fragebogens geschweige denn der Durchführung der Befragung in einem entsprechenden Labor. Dafür gibt es dann andere Experten, wie im folgenden Kasten für die Angehörigen der Hochschule Osnabrück. Sicherlich gibt es an deiner Einrichtung auch die entsprechenden Stellen. Hier soll es wie immer um einen ersten Überblick über verschiedene Themen und Herausforderungen der Fragebogenanalyse gehen.
::: callout-note
## Beratung für Agrarmarketing & Fragebogenerstellung
Ich bin kein Experte für die Untiefen der Fragebogenerstellung an der Hochschule Osnabrück. Hier empfehle ich auf jeden Fall nochmal eine Beratung im Team von [Prof. Dr. Ulrich Enneking](https://www.hs-osnabrueck.de/prof-dr-ulrich-enneking) oder [Prof. Dr. Matthias Kussin](https://www.hs-osnabrueck.de/prof-dr-matthias-kussin/). Hier in diesem Kapitel kannst du dann die Einführung lesen und erste Ideen für deine Fragebogenanalyse sammeln. Ebenso bin ich kein Experte in der Fragebogenerstellung mit [Lime Survey \| LifeSurvey](https://www.limesurvey.org/de). Auch hier empfiehlt sich eine Beratung im Team von [Prof. Dr. Ulrich Enneking](https://www.hs-osnabrueck.de/prof-dr-ulrich-enneking). Dort liegen auf jeden Fall mehr Informationen zur Anwendung von Lime Survey wie auch eine Klickanleitung sowie Tipps & Tricks vor. Einfach einmal dort bitte nachfragen.
:::
Am Anfang möchte ich noch ein paar Tipps geben, wie die Auswertung leichter von der Hand geht. Ich konzentriere mich hier auf die praktische Auswertung. Natürlich macht es manchmal Sinn von den Regeln abzuweichen, wenn du einen sehr langen Fragebogen hast oder aber eine komplexere Fragestellung beantworten willst. Im Falle einer Abschlussarbeit solltest du aber schauen, das du dir das Leben nicht zu schwer machst. Wir gehen in dem Kapitel nachher noch verschiedene Punkte bei der Auswertung durch, aber es ist natürlich schöner, wenn die Probleme gar nicht erst auftreten können. Hier also eine kurze Sammlung aus anekdotischen Tipps & Tricks beim Fragenbogendesign.
Nicht zu viele Fragen mit verschiedenen Antwortmöglichkeiten!
: Wenn du immer wieder andere Antwortmöglichkeiten auf der Likert-Skala definierst, wirst du später Probleme bei der Erstellung der Abbildungen bekommen. Du kannst nämlich nur sinnvoll die gleichen Antwortmöglichkeiten in einer Abbildung kombinieren. Es empfiehlt sich nicht zwischen zu vielen Wortreihen hin und her zu springen. Klar kommt es immer auf die Fragestellung an, aber versuche die Fragen so zu bauen, dass du mit immer den gleichen Antwortmöglichkeiten klar kommst oder sehr wenigern Variationen.
Gehe von einer Antwortquote oder Rücklaufquote von unter 20% aus!
: Das ist jetzt vielleicht etwas pessimistisch, aber wie du gleich unten in der Literatur sehen wirst auch nicht unrealistisch. Es gibt Möglichkeiten die Rücklaufquote zu erhöhen, aber dazu mehr dann in der Durchführung weiter unten. Wenn du also über 100 Fragebögen auswerten möchtest, dann musst du ca. 500 Teilnehmer:innen anschreiben oder kontaktieren. Das sind sehr schnell sehr große Zahlen. Und wie du nachher in der Auswertung hier sehen wirst, sind 173 Fragebögen auch nicht so viel. Darüber hinaus dauert es natürlich auch, bis du alle Fragebögen zurück erhalten hast. Bitte beachte als Daumenregel, dass du wirklich Rücklauf von über 100 Fragebögen brauchst, damit du anständige und sinnhafte Auswertungen durchführen kannst. Das kannst du auch selber kurz über den Daumen peilen. Wenn du fünf Antwortmöglichkeiten hast, dann würden bei 100 Teilnehmer:innen bei einer Gleichverteilung jeweils 20 pro Antwortmöglichkeit herauskommen. Damit kann man dann schon arbeiten, bei weniger wird es schon nicht mehr schön bis unmöglich.
Mache deinen Fragebogen nicht zu lang!
: Wenn dein Fragebogen zu lang ist, dann wird deine Rücklaufquote noch kleiner und die Teilnehmer:innen füllen eventuell den Fragebogen zum Ende hin nicht mehr gewissenhaft aus sondern wollen nur fertig werden. Daher überlege dir genau, was deine wissenschaftliche Fragestellung ist und ob du wirklich all diese Fragen brauchst um diese zu beantworten.
Finger weg von Antworten mit einem Freifeldtext!
: Wenn Teilnehmer:innen etwas selber wo reinschreiben können, dann führt das zu einen unglaublichen Durcheinander und du musst dann im Zweifel hunderte von Freitextfeldern selber zusammenfassen. Jeder Rechtschreibfehler führt zu einem anderen erkannten Item durch einen Computer. So bist du dann gezwungen diese Textfelder selber zu sortieren. Das ist unglaublich aufwendig und selten mit Erfolg gekrönt.
Vorsicht vor der Antwortkategorie `Sontiges`!
: Hinter `Sonstiges` kann sich so einiges verbergen und dann weißt du nicht, was diese Antwortmöglichkeit aussagen soll. Am Ende ist dann die Antwort `Sonstiges` nicht mehr als ein fehlender Wert. Die Interpretation ist schwierig, da jeder etwas anderes unter `Sonstiges` versteht. Ja, es ist schwierig Antworten so zu bauen, dass `Sonstiges` nicht gebraucht wird, aber nur so kriegst du dann bessere Antworten, die du auch auswerten kannst.
Muss es `weder noch` oder `teils-teils` als Antwortkategorie sein?
: Eine neutrale Antwortmöglichkeit ist immer so eine Sache. Durch die neutrale Antwortmöglichkeit können sich dann die Teilnehmer:innen um eine klare Antwort drücken. Ich würde daher eher für eine gerade Anzahl an Antwortmöglichkeiten plädieren, so dass die Teilnehmer:innen sich für eine Seite entschieden müssen. Aber wie immer musst du schauen, was du mit dem Fragebogen erreichen willst. Im ungünstigsten Fall hast du sehr viele neutrale Antworten und kannst eigentlich mit den `egal`-Antworten nichts anfangen.
Das soll es auch schon mit der Einführung und dem allgemeinen Tenor gewesen sein. Ich liefere gleich noch einen Abschnitt für die Durchführung mit Literatur nach. Die technische Umsetzung der Fragen erfolgt hier in der Onlineumfrage [LimeSurvey \| LifeSurvey](https://www.limesurvey.org/de) und die Auswertung in R. Das hat die Gründe, dass zum einen an der Hochschule Osnabrück das Onlinetool LimeSurvey zu freien Verfügung steht und zum anderen dieses Buch sich hier auf R konzentriert. Fragebogenanalysen sind meistens im Kontext einer Abschlussarbeit sehr viele kleine Analysen, denn jede Frage wird ja häufig separat betrachtet oder mit einer anderen kombiniert. Das geht dann auch in Excel insbesondere, wenn der Fokus auch auf der deskriptiven Statistik und Visualisierung liegt.
::: callout-caution
## Ich mache das jetzt alles in Excel und PowerPoint...
Klar, kein Problem. Viele Sachen hier kannst du auch händisch mit (teilweise) bedeutend Mehrarbeit auch händisch in Excel oder PowerPoint lösen. Da spricht dann auch überhaupt nichts dagegen. Wie immer mache ich das hier aber auch aus der Perspektive der Data Science und da machen wir es dann Effizient. Teilweise gehen auch die Methoden hier nicht in Excel. Aber für die Übersichtstabellen und das Zusammenfassen kannst du auch Excel nutzen. Wenn es nicht mehr sein soll, dann reicht es meistens auch.
:::
Auch hier endet die Einführung mit einem Kasten für weitere Tutorien rund um das Thema Fragebogenauswertung. Das Thema ist so umfangreich, dass ich es hier nicht in einem Kapitel wirklich tiefgründig erklären kann. Dafür musst du dann nochmal rechts und links weitergucken. Ich habe versucht die Tutorien wieder etwas zu sortieren und die mir am meisten gefallen haben, weiter oben angeordnet. Nicht alle R Pakete machen auch wirklich Sinn, wenn du nur einen einfachen Fragebogen deskriptiv darstellen willst. Im Zweifel gerne mir mal eine Mail schreiben, dann können wir über die Sachlage sprechen.
::: callout-tip
## Weitere Tutorien für die Fragebogenanalyse
Wir immer geht natürlich mehr als ich hier Vorstellen kann. Du findest im Folgenden Tutorien, die mich hier in dem Kapitel inspiriert haben. Ich habe versucht die Tutorien etwas zu sortieren, so dass die wichtigeren am Anfang stehen. Da aber wichtig nun wirklich kontextabhängig ist, muss du mal schauen was hilft.
- [Questionnaires and Surveys: Analyses with R](https://ladal.edu.au/surveys.html#1_Introduction) ist ein elichter Einstieg in das Thema mit viel Hilfe und Gedanken zur Erstellung von Fragebögen. Begrifflichkeiten werden geklärt und Probleme und Herausforderungen diskutiert. Habe ich gerne quer gelesen. Ach ja, mit den Tortendiagrammen gehe ich nicht mit... siehe dazu auch weiter unten meine Antwort zu.
- [Using R for Social Work Research \| Survey Research](https://bookdown.org/bean_jerry/using_r_for_social_work_research/survey-research.html) ist in wunderbares Skript, was eigentlich das gesamte Konzept der Forschung in den Sozialwissenschaften zusammenfasst. Als Einstieg und Erweiterung des Wissens wirklich toll.
- [The Epidemiologist R Handbook \| Survey analysis](https://epirhandbook.com/en/survey-analysis.html) ist eine wunderbare Quelle, wenn du schon mit R programmiere kannst und dich tiefer mit der Fragestellung der Analyse von Fragebögen beschäftigen willst. Hier geht es dann auch teilweise sehr ins Detail, aber das ist ja nicht unbedingt schlecht.
- [5 Ways to Effectively Visualize Survey Data Using R](https://towardsdatascience.com/5-ways-to-effectively-visualize-survey-data-using-r-89928bf08cb2) ist eine wunderbare Ergänzung, wenn du dich fragst, wie du am besten deine Umfrageergebnisse einmal darstellen sollst. Teile davon zeige ich dir auch hier in diesem Kapitel.
- Da ja Fragebögen auch immer etwas mit den Sozialwissenschaften zu tun haben empfiehlt sich auch ein Blick in das R Paket [`{sjPlot}` - Data Visualization for Statistics in Social Science](https://strengejacke.github.io/sjPlot/index.html). Das R Paket wurde extra für die Sozialwissenschaften gebaut und deren Anwendungen sowie Herausforderungen.
- Das Tutorium [On Likert scales in R](https://jakec007.github.io/2021-06-23-R-likert/) und die [On Likert scales in R \| PDF Version](https://jakec007.github.io/assets/files/2021-06-23-R-likert.pdf) sowie [Descriptive Statistics for Likert Item Data](https://rcompanion.org/handbook/E_03.html) auf Rcompanion von Salvatore Mangiafico liefern nochmal die Betrachtung von Likertskalen und deren Auswertung.
- [Analyzing Complex Survey Data](https://www.bookdown.org/rwnahhas/RMPH/survey.html) liefert Ideen für die Analyse von komplexeren Fragebögen. Ich fand es dann teilweise zu detailiert für dieses Kapitel.
- [Analyzing Survey Data in R](https://rpubs.com/Onduma/surveydata) ist nochmal eine etwas wilde Sammlung an Ideen, wie du deine Fragebogendaten auswerten könntest. Ich empfand es eher als einen Steinbruch an Ideen aus denen man sich dann das beste Raussuchen muss. Je nachdem was du dann in deinem Fragebogen an Variablen drin hast.
- [Survey analysis in R](https://r-survey.r-forge.r-project.org/survey/) und die Vignette des [R Pakets `{survey}`](https://cran.r-project.org/web/packages/survey/) liefern nochmal mehr Informationen über die Analyse von Fragebogendaten und deren entsprechenden Datenrepräsentation. Hier geht es dann schon sehr tief in Deatil. Wenn du dich also wirklich mit der Analyse von Fragebögen auseinandersetzen willst, dann geht es dann hier in den Kaninchenbau.
:::
## Durchführung
Im Folgenden möchte ich dir einmal eine Übersicht über die Literatur zur Erstellung eines Fragebogens geben. Wir immer ist dies hier nur eine grobe Übersicht. Je nachdem wie komplex deine Fragestellung ist, musst du natürlich auch einen komplexeren Fragebogen nutzen und dann wird die Erstellung des Fragebogens um einiges komplizierter und anspruchsvoller. Wenn es gar noch weiter gehen soll in die Richtung Marktforschung mit Teilnehmer:innen in einem Labor in Präsenz, kommen noch andere Anforderungen hinzu. So weit wollen wir hier aber erstmal nicht gehen. Ich stelle dir hier Ideen und Anregungen für die Erstellung eines Fragebogens für eine Abschlussarbeit vor. Ich kann natürlich hier nicht die Arbeiten vollständig zitieren, da musst du dann nochmal selber lesen. Die Literatur ermöglicht deshalb sicherlich noch viel mehr als hier kurz vorgestellt wird. Daher kann ich dir nur empfehlen einmal die Literatur quer zu lesen.
### Wie fang ich's an? {.unnumbered}
Beginnen wir mit einer schon etwas älteren Arbeit von @watson1998primer mit Titel [A primer in survey research](https://web.archive.org/web/20170809134002id_/http://www.appstate.edu/~steelekm/classes/psy3100/Documents/PrimerOnSurveys.pdf). Die Arbeit ist zwar schon etwas älter und damit nicht auf dem neusten Stand was die Onlineumfragen angeht, das gab es ja zur der Zeit noch nicht richtig. Dafür liefert die Arbeit aber einen super Einstieg in die Grundlagen von Umfragen und was du beachten solltest. Teilweise ist es dann auch in einer Art Checkliste geschrieben.
Die Arbeit von @story2019survey mit dem Titel [Survey Research](https://pubs.asahq.org/anesthesiology/article/130/2/192/20077/Survey-Research) sticht durch die Toolboxen hervor. In der *Toolbox for Survey Researchers* findest du Tipps & Tricks für dich, wenn du einen Fragebogen erstellst. In der *Toolbox for Survey Readers* dann die umgedrehte Seite, was muss ich beachten, wenn ich Umfragen lese? Auch toll, da du ja was schreibst, was dann auch gelesen werden soll. Die Arbeit hat noch mehr Tollboxen in denen noch mehr Tipps und Anleitungen gegeben werden. Wenn ich einen Fragebogen in einer Beratung habe, dann gebe ich immer gerne diese Arbeit weiter.
Wenn du dann deine Umfrage gemacht hast kannst du dann bei @gaur2020reporting in ihrer Arbeit [Reporting Survey Based Studies – a Primer for Authors](https://pdfs.semanticscholar.org/4404/87dddb44e19046d2481df661d0352176a002.pdf) lesen wie du deine Umfrage publizieren kannst. Die Arbeit beginnt aber schon etwas früher und präsentiert in einer Liste recht aktuelle *Tools for survey-based studies* und deren Vor- und Nachteile. In dem *Algorithm for a survey construct* geben die Autoren nochmal eine Handreichung, wie eine Fragebogenstudie bis zur Publikation aufgebaut sein kann.
@synodinos2003art gibt in seinem Artikel *The “art” of questionnaire construction: some important considerations for manufacturing studies* einen sehr detailierten Überblick über die Erstellung eines Fragebogens. Die Arbeit ist interessant, aber auch nur wirklich was für jemanden, der wirklich in die Fragebogenerstellung abtauchen will. Für eine Abschlussarbeit meiner Meinung nach schon zu viel. Ich habe aber die Arbeit gerne einmal quergelesen und die ein oder andere Idee dort mitgenommen. Ich kann mich dann nur folgendem übersetzten Zitat aus seiner Arbeit anschließen.
> *In der Tat scheinen einige Forscher die Phase der Datenerhebung zu vernachlässigen und sich nur auf ausgeklügelte statistische Verfahren zu konzentrieren. Es kann eindeutig festgestellt werden, dass keine noch so ausgefeilte statistische Analyse die grundlegenden Unzulänglichkeiten eines schlecht konstruierten Fragebogens korrigieren kann. --- @synodinos2003art*
Abschließend möchte ich diese kurze Einleitung hier mit der Arbeit von @bruhlmann2020quality mit dem Titel [The quality of data collected online: An investigation of careless responding in a crowdsourced sample](https://www.sciencedirect.com/science/article/pii/S2590260120300096). Es geht im Prinzip darum, dass die Teilnehmer:innen in einem Onlinefragebogen dann schlampig antworten und irgendwie dann keine Lust mehr haben. Das solltest du beachten, wenn du selber einen Fragebogen baust. Ob du dann deine Analyse so auswerten musst wie die Autoren vorschlagen, würde ich jetzt nicht meinen. Aber habe den Gedanken im Hinterkopf, dass deine Teilnehmer:innen eine Egalhaltung einnehmen könnten während sie den Fragebogen ausfüllen. Das führt uns dann auch gleich zu dem nächsten Thema der Länge eines Fragebogens.
### Wie lang soll es sein? {.unnumbered}
Häufig stellt sich auch die Frage, wie lang soll den so ein Fragebogen sein? Du hast so viele Fragen und wenn dann schon mal einer antwortet, dann kann der doch gefälligst dreißig Seiten Fragebogen ausfüllen? Du kannst dann ja später immer noch Fragen rausschmeißen. Ja, aber das machen wir dann meistens doch nicht. Deshalb bleibt das Zitat von Steven King immer aktuell. Du musst deinen Fragebogen so kürzen, dass er deine Fragestellung beantworten kann und nicht mehr.
> *"Kill your darlings, kill your darlings, even when it breaks your egocentric little scribbler's heart, kill your darlings." --- Steven King*
@rolstad2011response haben in ihrer Arbeit mit dem Titel [Response Burden and Questionnaire Length: Is Shorter Better? A Review and Meta-analysis](https://www.sciencedirect.com/science/article/pii/S1098301511015245) sich sehr viele Zusammenhänge angeschaut. Sie versuchten die Frage zu beantworten, ob ein kurzer Fragebogen wirklich besser ist. Hierbei kam heraus, dass angesichts der schwachen Belege für einen Zusammenhang zwischen der Länge des Fragebogens und dem Beantwortungsaufwand Entscheidungen über die Wahl des Fragebogens am besten auf der Qualität des Inhalts aus der Sicht der Beantwortenden beruhen sollten und nicht auf der Länge an sich.
> *Response rates were lower for longer questionnaires, but because the P value for test of homogeneity was P = 0.03, this association should be interpreted with caution because it is impossible to separate the impact of content from length of the questionnaires. --- @rolstad2011response*
@roszkowski1990believe schreiben in ihrer etwas älteren Arbeit mit dem Titel [Believe it or not! Longer questionnaires have lower response rates](https://www.researchgate.net/profile/Michael-Roszkowski/publication/225240332_Believe_It_or_Not_Longer_Questionnaires_Have_Lower_Response_Rates/links/0c96051d1ffb9a443c000000/Believe-It-or-Not-Longer-Questionnaires-Have-Lower-Response-Rates.pdf) folgendes recht eindeutige Ergebnis.
> *Response rate for the short form averaged about 28% higher than for the long form \[...\]. A measure of course satisfaction appearing on both questionnaires showed no significant differences between the long and short form \[...\]. --- @roszkowski1990believe*
Ja, die Arbeit ist schon etwas älter, aber auch bei Fragebögen steckt dann die Würze in der Kürze. Wenn du deine Fragebögen zu lang machst, dann kann es sein, dass eben deine Teilnehmer:innen keine Lust mehr haben und am Ende nur noch raten oder eben dann den Bogen gar nicht ausfüllen. Und damit kommen wir auch schon zum nächsten Punkt, wie ist denn eigentlich die Rücklaufquote?
### Wieviele antworten mir? {.unnumbered}
Du willst ja auch, dass dir Personen auf deinen Fragebogen antworten. Der Fragebogen ist nicht zu lang und du glaubst auch die Interessen der Antwortenden berücksichtigt zu haben. Dein Fragebogen ist damit also keine Qual zu beantworten. @edwards2009methods hat sich in einer Metanalyse mit dem Titel [Methods to increase response to postal and electronic questionnaires](https://www.cochranelibrary.com/cdsr/doi/10.1002/14651858.MR000008.pub4/abstract) einmal verschiedene Möglichkeiten angeschaut, die Antwortraten zu erhöhen. Nicht überraschend konnten durch Geld die Antwortraten verdoppelt werden. Aber es gab noch andere Möglichkeiten. Weitere Punkte, die die Antwortraten verdoppelt haben, waren ein Einschreiben, ein Hinweis auf dem Umschlag - zum Beispiel mit einem Kommentar, der den Teilnehmern suggeriert, dass sie davon profitieren können, wenn sie den Umschlag öffnen oder aber ein interessanteres Thema im Fragebogen. Schau nochmal selber in die Arbeit um dir die weiteren Möglichkeiten anzusehen. @edwards2002increasing hat schon früher eine Arbeit mit dem Titel [Increasing response rates to postal questionnaires: systematic review](https://www.bmj.com/content/324/7347/1183.full.pdf+html) geschrieben. In der sehr kurzen Arbeit geht er nochmal auf verschiedene Punkte ein. Insgesamt schaut der Artikel auf 40 Strategien die Antwortraten zu erhöhen. Ich glaube, dass da auch für dich was bei sein könnte, was einfach durchzuführen ist.
### Wie soll ich's bauen? {.unnumbered}
Die Likertskala ist die häufigste Art die Antwortmöglichkeiten zu bauen. In dem Artikel [The 4,5, and 7 Point Likert Scale](https://www.formpl.us/blog/point-likert-scale) erhälst du einen guten Überblick, was die Vorteile und Nachteile von den verschiedenen Anzahlen an Antwortmöglichkeiten sind. Im Prinzip hast du die Wahl zwischen vier Antwortmöglichkeiten, so dass du dann die Teilnehmer zwingst sich für eine Seite zu entscheiden. Oder aber du hast fünf Antwortmöglichkeiten, so dass du eine neutrale Antwortmöglichkeit einfügen kannst. @friedman1999rating gibt mit seinem Artikel [Ratung the rating scales](https://rangevoting.org/RateRatingScales.html) nochmal einen wunderbaren Überblick über die Porblematik der Auswahl der richtigen Antwortmöglichkeiten im Bezug auf die Likertskala. In dem etwas längeren Artikel [Survey Response Scales: How to Choose the Right One for your Questionnaire](https://cxl.com/blog/survey-response-scales/) geht der Autor nochmal auf die verschiedenen möglichen Arten von Antworten neben der Likertskala ein. Neben der Likertskala geht natürlich auch eine "Ja/Nein"-Antwort oder eine numerische Einschätzung als mögliche Antwort. So eine ausführliche Betrachtung sprengt dann eben dieses Kapitel und deshalb schaue da nochmal in die Literatur, wenn du die Antworten für deine Fragen baust. Ich denke, dass die drei Quellen schonmal ein guter Start und Inspiration sind.
## Genutzte R Pakete
Wir wollen folgende R Pakete in diesem Kapitel nutzen.
```{r echo = TRUE}
#| message: false
pacman::p_load(tidyverse, gtsummary, janitor, FactoMineR,
factoextra, corrplot, wesanderson, naniar,
scales, likert, sjPlot, parameters, mfp,
correlation, conflicted)
```
An der Seite des Kapitels findest du den Link *Quellcode anzeigen*, über den du Zugang zum gesamten R-Code dieses Kapitels erhältst.
## Daten
Der Druck im Markt auf Bauernhöfe ist groß. Neben den bekannten Erlebnishöfen mit Spezialisierungen auf Obst und Gemüse muss sich in den Weiten Brandenburgs, Niedersachsens und Mecklenburg-Vorpommern jeder Hof was Neues einfallen lassen um Gäste zu sich zu locken. Heutzutage reicht es einfach nicht mehr Rentnern auf Elektrofahrrädern überdimensionierte Sahnetorten anzubieten. Die Enkel wollen auch was sehen. Inspiriert von der Serie [Tiger King: Großkatzen und ihre Raubtiere](https://en.wikipedia.org/wiki/Tiger_King) gibt es nun immer mehr Höfe, dich sich den einen oder anderen Tiger oder Großkatze in den Hinterhof sperren. Aufgeschreckt durch den Zwischenfall mit der [Löwin von Kleinmachnow - oder wie eine Wildsau durchs Dorf getrieben wurde](https://www.rbb24.de/panorama/beitrag/2023/07/brandenburg-kleinmachnow-suche-loewin-raubkatze-wildschwein-polizei-video.html), gab der Verband "Erlebnishöfe mit Niveau e.V." eine Umfrage mit dem Titel *Nutzung von Großkatzen zur Steigerung der Attraktivität von Erlebnishöfen* unter den Mitgliedern in Auftrag. Gleichzeitig sollte auch die Zufriedenheit der Verbandsarbeit abgefragt werden und wie die betriebswirtschaftliche Struktur der 843 Betriebe um die Erlebnishöfe im Verband eigentlich so aussieht.
```{r}
tiger_tbl <- read_excel("data/survey-serengeti-tiger-king.xlsx", na = "NA",
sheet = "results-survey-lime")
```
In der @tbl-survey-tiger sehen wir einen Auszug aus unseren Ergebnis der Umfrage des Verbandes. Wir haben insgesamt `r ncol(tiger_tbl)` Fragen gestellt und eine Rücklauf von 173 Fragebögen von den Erlebnishöfen erhalten. Das ist eigentlich gar nicht so schlecht, damit haben wir hier eine Rücklaufquote von gut $20.5\%$ der Fragebögen. Wir werden uns nun an den `r ncol(tiger_tbl)` beispielhaften Fragen verschiedene Herausforderungen anschauen.
```{r}
#| echo: false
#| message: false
#| warning: false
#| label: tbl-survey-tiger
#| tbl-cap: "Auszug von fünf Fragen aus dem Fragebogen zur Nutzung von Großkatzen zur Steigerung der Attraktivität von Erlebnishöfen. Insgesamt haben 173 Erlebnishöfe den Fragebogen zurückgesendet."
tiger_raw_tbl <- tiger_tbl |>
mutate_all(as.character) |>
select("geschlecht", "alter", "haben_Sie_tiger", "f1Soziodemografisch", "f2Soziodemografisch")
rbind(head(tiger_raw_tbl, 4),
rep("...", times = ncol(tiger_raw_tbl)),
tail(tiger_raw_tbl, 4)) |>
kable(align = "c", "pipe")
```
Wir werden jetzt den Datensatz einmal versuchen auszuwerten. Dabei gehen wir schrittweise verschiedene Analysen durch und schauen, ob wir mit den Fragebogendaten so arbeiten können. Sehr häufig müssen wir nämlich erstmal die Daten so lange bearbeiten, bis die Daten sinnvoll ausgewertet werden können.
Leider sind die Fragen in den Fragebögen sehr lang. Das macht es schwierig die Fragen sauber als Spaltennamen abzubilden. Wir erhalten zum Beispiel aus dem Online-Query Lime verkürzte Spaltennamen, die sehr wenig aussagen, aber dennoch sehr lang sind. Deshalb empfehle ich immer noch eine zusätzliche Tabelle mit Fragen-ID `ques_id`, der Lime-ID `lime_id` sowie der eigentlichen Frage `question` zu erstellen. Ich mache das meistens dann in einem zusätzlichen Tab in der Exceldatei wie in der folgenden Abbildung gezeigt. In der Exceldatei kannst du dann auch in neuen Tabs die gereinigten oder bearbeiteten Versionen des ursprünglichen Fragebogens ablegen.
![Nicht alle Änderungen müssen in R durchgeführt werden. Es empfiehlt sich aber die Tabs in Excel zu nutzen um sich neue Versionen des ursprüngliche Lime-Fragebogens anzulegen. So hast du immer das Orginal vorliegen und kannst dann schrittweise nachvollziehen, was du geändert hast.](images/survey-excel-tabs.png){#fig-survey-excel fig-align="center" width="100%"}
Ich lade dann einmal den Tab mit den Beschreibungen der Fragen.
```{r}
short_question_tbl <- read_excel("data/survey-serengeti-tiger-king.xlsx", sheet = "question-short")
```
In der @tbl-survey-tiger-short siehst du einmal die Fragen in der Langform und die entsprechenden ID's für die Kurzform hier in R und dann eben auch in Lime. Ich nutze die Kurzform `ques_id` für die Beschriftungen von Abbildungen, da es sonst sehr schnell sehr unübersichtlich wird. Finale Abbildungen können dann am Ende immer noch entsprechend beschriftet werden. Die `lime_id` brauche ich um später noch Fragen entfernen zu können und als Verbindung zu den ursprünglichen Daten.
```{r}
#| echo: false
#| message: false
#| warning: false
#| label: tbl-survey-tiger-short
#| tbl-cap: "Tabelle der abgekützen Fragen-ID, der ursprüngichen Lime-ID sowie dem vollständigen Fragetext. Auch hier habe ich den Fragetext gekürzt, später kann dann noch der vollständige Text ergänzt werden."
short_question_tbl |>
kable(align = c("cll"), "pipe")
```
## Preprocessing
Wenn wir uns mit Fragebögen beschäftigen, dann werten wir meisten *nicht* alle Fragen aus. Das macht auch meistens keinen Sinn. Denn wir stellen zwar recht viele Fragen, aber am Ende müssen wir auch schauen, ob alle Fragen sinnvoll beantwortet wurden oder aber ob wir sehr viele Nichtantworten haben. Davon hängt dann auch die weitere Analyse ab. Wir können uns auch überlegen einzelne Fragen zusammenzufassen, da wir feststellen, dass wir dann am Ende doch nicht so eine feingliedrige Aufteilung wollen.
Im Weiteren müssen wir dann auch unsere Antworten in Zahlen umwandeln. Wir können ja nur mit Zahlen rechnen. Nur so können wir mittlere Noten ausgeben. Die Umwandlung können wir entweder global wie folgt machen, oder aber wir definieren für jede Antwort die Reihenfolge der Antwortmöglichkeiten. Die automatisierte Zuordnung bewirkt dann, dass wir nicht die Antwortmöglichkeiten in der richtigen, logischen Reihenfolge haben, sondern in der alphanumerischen Ordnung. Für einen ersten Überblick über die Ergebnisse des Fragebogens ist das Vorgehen okay. Später werden wir dann natürlich noch die Fragen richtig formatieren. Aber erstmal müssen wir wissen welche Fragen wir überhaupt auswerten wollen.
```{r}
tiger_fct_tbl <- tiger_tbl |>
mutate(across(everything(), as_factor))
```
Wenn du gleich die richtige Ordnung ahben willst, dann ist es ein wenig mehr Arbeit. Hier können wir dann über die Funktion `ordered()` die richtige Ordnung der Antwortmöglichkeiten über die Option `levels` erreichen. Wir haben hier verschiedene Antwortmöglichkeiten in den verschiedenen Fragen. Daher jetzt einmal die Ordnung der Antworten in logischer Reihenfolge. Mir reicht immer der schnelle Überblick, aber das ist dann ja auch Geschmackssache.
```{r}
alter_ord <- c("18-29 Jahre", "30-39 Jahre", "40-49 Jahre", "50-59 Jahre", "Über 60 Jahre")
zustimmung_ord <- c("trifft voll zu", "trifft zu", "weder noch", "trifft nicht zu", "trifft gar nicht zu")
aktiv_ord <- c("sehr aktiv", "eher aktiv", "weder noch", "eher nicht aktiv", "gar nicht aktiv")
```
Du siehst, dass ist eine Menge an Arbeit und zu tippen. Deshalb kann ich dir empfehlen, dass nur bei den Fragen zu machen, die du dann am Ende des Daten Preprocessing auch wirklich nutzen willst. Besonders bei Fragebögen mir sehr vielen Fragen wird es sehr schnell sehr lang. Auf der anderen Seite macht man es dann auch nur einmal. Am Ende wandeln wir dann noch alle Fragen, die wir nicht händisch in einen geordneten Faktor umgewandelt haben, in einen Faktor mit der Funktion `mutate_if()` um.
```{r}
tiger_ord_tbl <- tiger_tbl |>
mutate(alter = ordered(alter, levels = alter_ord),
f1Verbandsarbeit = ordered(f1Verbandsarbeit, levels = zustimmung_ord),
f2Verbandsarbeit = ordered(f2Verbandsarbeit, levels = zustimmung_ord),
f3Verbandsarbeit = ordered(f3Verbandsarbeit, levels = zustimmung_ord),
f4Verbandsarbeit = ordered(f4Verbandsarbeit, levels = zustimmung_ord),
f5Verbandsarbeit = ordered(f5Verbandsarbeit, levels = zustimmung_ord),
f1Imagearbeit = ordered(f1Imagearbeit, levels = aktiv_ord),
f2Imagearbeit = ordered(f2Imagearbeit, levels = aktiv_ord),
f3Imagearbeit = ordered(f3Imagearbeit, levels = aktiv_ord),
f4Imagearbeit = ordered(f4Imagearbeit, levels = aktiv_ord)) |>
mutate_if(is.character, as.factor)
```
Mit unserem geordneten Objekt `tiger_ord_tbl` können wir uns jetzt einen ersten Überblick über die Antworten der Fragen geben lassen. Dann entscheiden wir, ob wir Fragen zusammenfassen oder gar entfernen wollen. Eventuell müssen wir auch Antwortmöglichkeiten zusammenfassen, wenn einige Antworten einfach nicht ausgewählt wurden. Aber das schauen wir uns jetzt einmal in einer Übersicht an.
::: callout-caution
## Achtung, `as.factor()` vs. `as_factor()` macht einen Unterschied!
Wenn du deine Wörter `<chr>` in Zahlen umwandeln willst, dann musst du ja den Umweg über eine Faktorumwandlung gehen. Hier ist es jetzt mal sehr wichtig, dass du die Funktion `as.factor()` nutzt. Eigentlich nutze ich immer die Funktion `as_factor()` aber diese Funktion hat ein Feature, was uns hier bei den Fragebögen auf die Füße fällt. Schauen wir uns die Sachlage einmal in einem Beispiel an. Wir haben folgende drei Antworten und wollen diese einmal in einen Faktor umwandeln.
```{r}
answer_vec <- c("weder_noch", "eher_zufrieden", "sehr_zufrieden")
```
Wenn wir jetzt die Funktion `as.factor()` nutzen, dann werden unsere Level alphanumerisch sortiert. Das hat den Vorteil, dass jede Frage immer die gleichen Antwortsortierungen erhält. Dadurch ist dann auch gewährleistet, dass in jeder Frage die Antwortmöglichkeiten dann nach der Umwandlung in eine Zahl mit `as.numeric()` auch wirklich das gleiche Wort bedeutet.
```{r}
answer_vec |>
as.factor()
```
Die Sortierung in `as_factor()` wird nach dem Auftreten des Wortes in dem Vektor gemacht. Das heißt, je nach Frage, hat dann eine Frage eine andere Sortierung der Antwortmöglichkeiten. Das ist unglaublich ungünstig, da wir dann ja nach einer Umwandlung der Faktorenlevel in eine Zahl mit `as.numeric()` nicht mehr die gleichen Antwortmöglichkeiten hinter jeder Zahl haben!
```{r}
answer_vec |>
as_factor()
```
:::
### Univariate Analyse
Eigentlich ist die univariate Analyse ja auch gleich ein Teil der Darstellung des Fragebogens und gehört nicht so richtig zum Preprocessing. Auf der anderen Seite sehen wir in der univariaten Analyse auch das erste Mal alle Fragen und Antworten auf einem Blick in einer Tabelle und können dann entschieden, ob wir eine Frage rausnehmen wollen oder eben nicht. Oder ob unsere Antworten zu den Fragen passen oder es auffällige Antwortmuster gibt. Nach was wollen wir nun als erstes einmal Ausschau halten?
Fehlende Werte
: Gibt es eine Frage, bei der fast keiner geantwortet hat? Haben wir also eigentlich gar keine Information in der Frage enthalten, da die Antworten fast alle `NA` also fehlend sind?
Gleiche Einträge
: Gibt es Fragen, bei denen alle das Gleiche geantwortet haben? Haben wir also gar keine Varianz in den Fragen? Wenn alle nur eine und dieselbe Antwort geben, dann ist die Aussage der Frage sehr begrenzt. Wir können dann auch keine Gruppenvergleich rechnen, da ja alle immer das gleiche angekreuzt haben.
Sehr diverse Antworten
: Gibt es Fragen, wo die Antworten sehr heterogen sind und sich somit fast nicht sinnvoll zusammenfassen lassen? Das haben wir dann häufig bei Freitextfeldern. Es kann dann sein, dass wir sehr viele verschiedene Antworten erhalten, die wir irgendwie nicht sinnvoll zusammen kriegen.
Für die univariate Analyse nutze ich das [R Paket `{gtsummary}`](https://www.danieldsjoberg.com/gtsummary/articles/tbl_summary.html) mit der Funktion `tbl_summary()`. Die Funktion baut uns über alle Spalten in dem Datensatz eine deskriptive Information mit der Anzahl und der Häufigkeit der jeweiligen Antwortkategorie. Das ist super schnell und super effizient. Innerhalb von Sekunden haben wir unsere Fragen einaml in einer Tabelle wiedergeben. Das einzige was ich hier noch angepasst habe ist, dass ich die Fragen als Text dann als Spaltennamen gesetzt ahbe. So haben wir dann die richtigen Fragen in der Tabelle stehen. Sonst brauchen wir die Langform der Fragen ja nicht in den Abbilungen. Hier in der Tabelle finde ich die richtigen Fragen sehr sinnvoll.
```{r}
#| echo: true
#| eval: false
#| message: false
#| warning: false
tiger_tbl |>
set_names(short_question_tbl$question) |>
tbl_summary()
```
Ich habe dir jetzt die Ausgabe der Funktion `tbl_summary()` einmal in dem folgenden Kasten eingeklappt. Sonst sehen wir vor lauter Tabelle nichts mehr und so kannst du hier übersichtlich lesen. Wir sehen, dass die Frage *"Haben Sie weitere Erwerbsquellen neben dem Erlebnishof außer Landwirtschaft?"* sinnlos war. Zum einen war es Freitext und zum anderen haben wir mit 139 fehlenden Werten kaum Rückmeldungen zu der Frage. In unserem Freitexten sind dann so heterogene Antworten, dass sich hier eine Auswertung nicht sinnvoll durchführen lässt. Auch das Alter hat mit nur drei unter 29 Jährigen eine ungünstige Verteilung. Hier müsste man mal die Antworten zusammenfassen. Wir sehen auch, dass wir eigentlich gar keine Teilnehmerinnen in unserer Umfrage haben. So können wir dann einmal die Fragen durchgehen und dann immer entscheiden, ob wir eine Frage ganz rausnehmen, wie die Frage zu den Erwerbsquellen, oder aber Zusammenfassen müssen.
::: {.callout-note collapse="true"}
## Univariate Ausgabe der Funktion `tbl_summary()`
```{r}
#| echo: false
#| message: false
#| warning: false
#| label: tbl-survey-tiger-summary
#| tbl-cap: "Univariate Analyse der einzelenen Fragen und deren Antwortverteilung. Anhand der Tabelle können fehlende Werte und ungleichmäßig beantwortete Fragen er kannt und dann ausgeschlossen werden."
tiger_ord_tbl |>
set_names(short_question_tbl$question) |>
tbl_summary()
```
:::
### Fehlende Werte
Warum haben wir fehlende Werte in einem Fragebogen? Wenn wir nicht die Teilnehmer:innen zwingen jede Frage zu beantworten, dann kann es sein, dass einige Fragen nicht beantworten. Warum das so ist, ist eine gute Frage. Wenn die unbeantworteten Fragen gegen Ende auftreten, dann mag es Ermüdung sein. Ab und an übersieht man eventuell auch eine Frage oder aber versteht die Frage nicht. Es gibt also eine Menge Möglichkeiten. In unserem Beispiel treten fehlende Antworten bei der Fütterung auf. Wenn ein Hof keine Tiger hat, dann muss er auch die Tiger nicht füttern. Das macht dann eher einen Block an fehlenden Daten aus. Wir wollen jetzt einmal das R Paket `{naniar}` nutzen um fehlende Werte zu visualisieren. Etwas dagegen tun, werden wir hier nicht, dazu gibt es dann ein extra Kapitel [Imputation von fehlende Werten](#sec-missing) in diesem Buch.
In der @fig-survey-miss-1 siehst du einmal die fehlenden Werte als schwarzen Balken dargestellt. Die Spalten stellen dabei die Fragen dar und die Prozente hinter den Fragen die Anteile an fehlenden Werten. Teilweise wird hier die letzte Spalte abgeschnitten und wir müssten hier dann besser mit den verkürzten Namen arbeiten. Da ich aber die Abbildungen nur für eine Übersicht für mich selber nutze, kann ich damit leben. Wir sehen einmal als Block die fehlenden Werte für die Fütterung. Das sind all die Teilnehmer:innen, die keine Tiger halten. Dann siehst du noch einige horizontale Linien. Diese Linien sind Teilnehmer, die systematisch keine Fragen beantwortet haben. Sonst haben wir eigentlich keine richtigen auffälligen Muster in den Daten. Die Imagearbeit wurde nur relativ spärlich im Vergleich zur Verbandsarbeit beantwortet.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-miss-1
#| fig-align: center
#| fig-height: 5
#| fig-width: 7
#| fig-cap: "Darstellung der fehlenden Werte in dem Tigerdatensatz. Die fehlenden Werte werden als schwarzer Balken dargstellt. Der Block fehlender Werte bei der Fütterung stellt die Teilnehmer:innen dar, die keine Tiger halten. Horizontale Linien stellen Teilnehmer dar, die systematisch keine Fragen beantwortet haben."
tiger_tbl |>
vis_miss()
```
Häufig stellt sich dann auch die Frage, wie denn die fehlenden Werte untereinander zusammenhängen. Haben viele nur eine Frage nicht beantwortet oder haben die Teilnehmer dann auch andere Fragen ebenfalls ähnlich nicht beantwortet? Diese Zusammenhänge versucht die @fig-survey-miss-2 darzustellen. Wir haben einmal für fünfzehn Kombinationen der fehlenden Werte die Anzahlen dargestellt. So sehen wir das wir bei 72 Personen keine Antwort bei der Frage `f2Soziodemografisch` haben. Sonst finden Sie bei diesen Personen aber keine weiteren fehlenden Werte. Anders sieht es dann bei den nächsten zwanzig Personen aus. Hier haben wir fehlende Werte bei der Frage `f2Soziodemografisch` und `f2Imagearbeit`. So können wir dann schauen, ob wir auch dort noch Muster erkennen. Wir sehen auch wieder die Blöcke der Fütterungsfrage. Da haben wir natürlich dann auch immer die vier Fragen zur Fütterung als fehlend.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-miss-2
#| fig-align: center
#| fig-height: 5
#| fig-width: 7
#| fig-cap: "Darstellung des Zusammenhangs der fehlenden Werte unter den Teilnehmer:innen des Fragebogens. Unter den Balkendiagramm sind die jeweiligen Kombinationen der fehlenden Werte der Fragen für diese Gruppe der Teilnehmer:innen dargestellt."
tiger_tbl |>
gg_miss_upset(nsets = 15)
```
Am Ende werten wir ja viele Fragen erstmal alleine aus. Daher schauen wir uns an, wie die Verteilung der Antworten pro Frage ist. Daher macht es dort noch nicht so viel aus, wenn du fehlende Werte hast. Wenn du dann aber Fragen miteinander in Bezug setzen willst und eventuell die Anteile der Antworten in Beziehung setzen willst, dann macht schon was aus, wie viele fehlende Werte du pro Frage hast. Aber auch hier kommt es dann sehr stark auf den Kontext und die einzelnen Fragen an. Daher kann ich dir hier keine generelle Antwort liefern. Wichtig ist erstmal, dass du das Problem der fehlenden Werte kennst und darstellen kannst.
Jetzt können wir noch ein wenig Zahlen wiedergeben lassen. Wir wollen ja auch wissen, wie viele fehlenden Werte wir dann in den Daten überhaupt haben. Dafür können wir dann die fehlenden Werte über die Funktion `n_miss()` zählen und durch die gesamte Anzahl an Beobachtungen mit `n_complete()` teilen. Wir kriegen dann raus, dass wir gut 11.3% fehlende Werte in unserem Datensatz haben.
```{r}
n_miss(tiger_tbl)/n_complete(tiger_tbl)
```
Über die Funktion `miss_case_summary()` kannst du dir dann noch mehr Informationen zu den einzelnen Beobachtungen wiedergeben lassen. Über die Funktion `print()` kannst du dir dann noch mehr Zeilen als die normalen zehn Zeilen ausgeben lassen.
```{r}
tiger_tbl |>
miss_case_summary() |>
print(n = 12)
```
Schauen wir uns mal die Personen mit sieben oder mehr fehlenden Werten einmal an. Wir nutzen dazu die Funktion `slice()`, die es uns erlaubt die Zeilen zu extrahieren, welche für die Beobachtungen stehen.
```{r}
tiger_tbl |>
slice(c(66, 158, 173, 79, 170, 31, 154, 155, 160))
```
Wir sehen dann einmal die ganzen Personen, die sehr viele fehlenden Werte bei den Antworten haben. Ich möchte jetzt ungern noch mehr Beobachtungen rauschmeißen, die keine Tiger halten. Deshalb bleiben fliegen nur die drei Tigerhalter aus den Daten und der Rest bleibt drin. Das ist jetzt eine bewusste Entscheidung von mir, du musst dann schauen, wie du das in deinen Daten machst. Dann entferne ich einmal die drei Beobachtungen mit `slice()` aus meinen Daten.
```{r}
tiger_tbl <- tiger_tbl |>
slice(-c(66, 79, 31))
```
Dann schauen wir zum Anschluss nochmal, ob wir auch das entfernt haben, was wir entfernen wollten. In der @fig-survey-miss-3 siehst du nochmal die Visualisierung der fehlenden Werte nachdem wir unsere drei Beobachtungen entfernt haben. Das sieht soweit super aus, denn wir haben jetzt schon ein etwas einheitlicheres Bild vorliegen.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-miss-3
#| fig-align: center
#| fig-height: 5
#| fig-width: 7
#| fig-cap: "Darstellung der fehlenden Werte in dem Tigerdatensatz nachdem wir unsere drei Beobachtungen entfernt haben. Die fehlenden Werte werden als schwarzer Balken dargstellt. Der Block fehlender Werte bei der Fütterung stellt die Teilnehmer:innen dar, die keine Tiger halten. Horizontale Linien stellen Teilnehmer dar, die systematisch keine Fragen beantwortet haben."
tiger_tbl |>
vis_miss()
```
::: callout-caution
## Imputation von fehlenden Werten
Eine Möglichkeit mit fehlenden Werten umzugehen ist die [Imputation von fehlende Werten](#sec-missing), die ich in einem anderen Kapitel erläutere. Ich wäre aber mit dem Einsatz der Methoden sehr vorsichtig, da diese Methoden teilweise nicht in Veröffentlichungen anerkannt werden. Die Kritik lautet dabei, dass künstliche Daten erstellt werden, die nicht den realen Hintergrund abbilden. Daher ist die Verwendung von einem Imputationsalgorithmus immer gesondert zu diskutieren und zu bewerten.
:::
### Korrelation
Warum Korrelation der Fragen? Nun es kann sein, dass wir Fragen gebaut haben, die eventuell das Gleiche abfragen. Oder aber, dass die Teilnehmer:innen unseres Fragebogen eine Frage genau so beantworten wie eine andere Frage. Das lässt sich bei der Vielzahl an Fragen kaum überblicken. Deshalb schauen wir uns einmal die Korrelation zwischen den Fragen an um zu sehen, ob wir nicht Fragen haben, die das Gleiche aussagen.
Zuerst bauen wir uns einen Datensatz `tiger_clean_num_tbl` indem alle Spalten nur noch numerisch sind. Wir können die Korrelation nur mit numerischen Spalten rechnen. Wenn du noch Wörter als Antworten in den Spalten stehen hast, dann kannst du über `as.factor()` erstmal die Antworten in Faktoren umwandeln. Das habe ich hier schon gemacht und nutze daher den Datensatz `tiger_fct_tbl`. Am Ende setze ich dann noch die Bezeichnung der Fragen auf die Abkürzungen der Fragen, sonst klappt es nicht richtig mit der Darstellung. Dafür sind dann die ursprünglichen Spaltenbezeichungen zu lang.
```{r}
tiger_clean_num_tbl <- tiger_fct_tbl |>
mutate_all(as.numeric) |>
set_names(short_question_tbl$ques_id)
```
Wenn du dir nur die Korrelation zwischen den Spalten hier anschaust, dann nutze zuerst die Option `use = "pairwise.complete.obs"`. Dann werden nur die Beobachtungen genutzt die in den jeweiligen Spalten, die verglichen werden, vorhanden sind. Ich nutze hier dann auch den Korrelationskoeffizienten nach Pearson. Da wir eigentlich keine normalverteilten Daten in den Antwortmöglichkeiten vorliegen haben, müsste ich eigentlich besser Spearman nutzen, aber Spearman neigt zu Fehlern, wenn die Daten nicht richtig passen. Da ich mir hier aber nur einen groben Überblick verschaffen möchte, kommt es auf Abweichungen in dem Korrelationskoeffizienten nicht an. Auch wenn mein Korrelationskoeffizienten verzerrt ist, wird ein hoher Korrelationskoeffizienten nach Pearson auf eine Korrelation hindeuten. Das ist ja auch nur mein Ziel hier, nämlich ähnliche Fragen zu erkennen. Den berechneten Korrelationskoeffizienten nehme ich dann aber nicht zu ernst. Am Ende nehme ich noch die Frage `f2Soziodemografisch` aus der Betrachtung, da hier zu viele fehlende Werte vorliegen.
```{r}
#| warning: false
#| message: false
cor_mat <- tiger_clean_num_tbl |>
select(-matches("Soziodemografisch")) |>
cor(use = "pairwise.complete.obs")
```
Ich könnte mir jetzt die berechnete Korrelationsmatrix `cor_mat` einmal in R als Matrix anschauen. Schöner ist es in der @fig-survey-corr-1 als Korrelationsplot. Trotz der Verwendung des Korrelationskoeffizienten nach Person konnten wir nicht für alle paarweisen Vergleiche der Fragen eine Korrelation berechnen. Wenn es nicht möglich war, dann sehen wir ein Fragezeichen in der Abbildung. Wenn wir eine zeitlang auf die Abbildung schauen, sehen wir, dass wir eigentlich keinen große Korrelation zwischen den Fragen haben. Der größte Wert ist $-0.38$ sowie $0.31$ und damit noch sehr nah an der Null und keiner Korrelation. Ich bin somit mit der Korrelation zufrieden. Wir müssen keine Fragen zusammenfassen oder entfernen, weil die Korrelation zwischen den Fragen zu groß ist und damit die Fragen das Gleiche aussagen.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-corr-1
#| fig-align: center
#| fig-height: 9
#| fig-width: 9
#| fig-cap: "Visualisierung der Korrelationsmatrix nach Pearson für alle Fragen. Teilweise konnte der Korrelationskoeffizient nicht berechnet werden. Wir haben keine Korrelation zwischen den Fragen vorliegen. Teilweise ist es sher schwer was in den Zahlen zu erkennen, da helfen dann mal wirklich die Tortendiagramme und die Elipsen weiter um die entsprechenden Korrelationen zu finden."
#| fig-subcap:
#| - "Numerische Werte."
#| - "Tortendiagramm und Ellipse"
#| layout-ncol: 1
#| column: page
corrplot(cor_mat, method = 'number',
col = rev(wes_palette("Zissou1", 8, type = "continuous")))
corrplot.mixed(cor_mat, lower = 'pie', upper = 'ellipse')
```
### Zusammenfassen
Manchmal wollen wir dann doch Fragen zusammenfassen. Irgendwie stellen wir fest, nachdem wir die Antworten gesehen haben, dass wir dann doch irgendwie nicht so eine detaillierte Fragenaufteilung wollen. Dann können wir natürlich auch Fragen zusammenfassen. Eine goldene Regel gibt es dafür nicht, ich zeige aber mal die eine oder andere Möglichkeit. Es kann auch sein, dass wir festgestellt haben, dass einzelne Fragen sehr stark miteinander korrelieren und wir deshalb die Fragen zusammenfasen wollen anstatt eine der Fragen aus der Analyse zu nehmen. Neben dem Fragen zusammenfassen, können wir auch Antwortkategorien zusammenfassen. Wir wollen dann nicht die fünf Antwortmöglichkeiten sondern eben nur drei oder zwei. Dann können wir das auch machen, müssen es nur in unserem Report oder der Abschlussarbeit berichten.
#### ...von einzelnen Fragen {.unnumbered}
Im Folgenden habe ich mich dazu entschieden, dass mich die Fütterung dann doch nicht so sehr im Detail interesiert. Ich möchte dann alle Fragen einmal zusammenfassen, die mit der Fütterung zu tun haben. Dafür nutze ich dann den folgenden Code. Die Idee ist sehr simple. Ich addiere die Spalten für Fütterung auf und erhalte die neue Spalte `Feutterung`. Dann kann ich entscheiden, wie ich mit der Spalte weiter umgehen will. Theoretisch können natürlich noch andere mathematischen Operatoren, wie Subtraktion einer Spalte von der anderen oder das Produkt genutzt werden. Da kommt es dann aber auf das konkrete Beispiel an. Der BMI ist sicherlich die bekanneste Zusammenfassung. Häufig kennen die Teilnehmer:innen ihre Größe und das Gewicht, aber selten den BMI oder wissen die entsprechende Formel.
```{r}
feed_tbl <- tiger_fct_tbl |>
select(matches("Fuetterung")) |>
mutate(across(matches("Fuetterung"), \(x) as.numeric(x)-1)) |>
mutate(Fuetterung = rowSums(across(matches("Fuetterung"))))
```
In der @tbl-survey-feed-1 siehst du dann einmal das Ergebnis unserer Summenbildung über die Spalten der Fütterung. Wir haben jetzt in der Spalte `Fuetterung` die Summen der Spalten enthalten. Je größer die Zahl, desto mehr wurde gefüttert. Wenn ich das mal so ganz allgemein formulieren will.
```{r}
#| echo: false
#| message: false
#| warning: false
#| label: tbl-survey-feed-1
#| tbl-cap: "Tabelle der Zusammenfassung der Fragen zur Fütterung unserer Großkatzen als Summe in der Spalte `Fuetterung`. Ein hoher Wert bedeutet, dass eben viel gefüttert wurde."
feed_tbl |>
select(Fuetterung, everything()) |>
head(n = 7) |>
kable(align = "c", "pipe")
```
Wir nutzen jetzt einmal die Funktion `tabyl()` um uns die prozentuale Verteilung der neuen Einträge in der Spalte `Futterung` anzeigen zu lassen. Ich empfehle immer die Spalte `valid_percent` vorzuziehen, da wir in dieser Spalte nicht die fehlenden Werte mit reingerechnet haben.
```{r}
feed_perc_obj <- feed_tbl |>
tabyl(Fuetterung) |>
round(2)
```
In der @tbl-survey-feed-2 sehen wir dann einmal die Übersicht unser Zusammenfassung. Spannenderweise füttern sechs Betriebe ihre Tiger gar nicht. Was ein spannendes Ergebnis ist. Oder aber sie füttern die Tiger nicht nach den entsprechenden Fragen. Das kann natürlich auch Auftreten. Wie wir jetzt die Zusammenfassung weiter interpretieren ist so ein Sache. Das Beispiel ist jetzt etwas konstruiert, aber wir wissen immerhin, dass die meisten Teilnehmer:innen zwei der Fütterungsfragen mit Ja beantwortet haben.
```{r}
#| echo: false
#| message: false
#| warning: false
#| label: tbl-survey-feed-2
#| tbl-cap: "Zusammenfassung der Spalte `Fuetterung` nach den neuen Einträgen und den entsprechenden prozentualen Auftreten. Die vorzuziehende Spalte `valid_percent` beschreibt das prozentuale Auftreten ohne die fehlenden Werte in der Spalte."
feed_perc_obj |>
kable(align = "c", "pipe")
```
#### ... von Antwortenmöglichkeiten {.unnumbered}
Manchmal ist es sinnvoll Antwortmöglichkeiten zusammenzulegen. In unserem Fragebogen haben wir zum Beispiel nur drei 18 bis 29 Jährige. Das ist echt wenig. Dann können wir diese drei Personen auch zu den 30 bis 39 Jährigen packen und eine neue Kategorie erschaffen. Dann fassen wir die beiden mittleren Kategorien auch noch zusammen, weil wir es können. Wir nutzen dazu die R Funktion [`case_when()`](https://dplyr.tidyverse.org/reference/case_when.html) mit der wir uns dann nach Regeln neue Werte erschaffen können. Hier einmal das Beispiel für das Alter. Ich behalte mir immer die alte Spalte mit in den Daten um im nachhinein nochmal zu schauen, ob auch alles richtig transformiert wurde.
```{r}
alter_combined_tbl <- tiger_fct_tbl |>
select(alter) |>
mutate(alter_recode = case_when(alter %in% c("Über 60 Jahre") ~ ">60 Jahre",
alter %in% c("40-49 Jahre", "50-59 Jahre") ~ "40-59 Jahre",
alter %in% c("18-29 Jahre", "30-39 Jahre") ~ "<39 Jahre")) |>
mutate(alter_recode = ordered(alter_recode, levels = c("<39 Jahre", "40-59 Jahre", ">60 Jahre")))
```
Dann wollen wir uns nochmal das Ergebnis als eine Tabelle anschauen um zu sehen, ob auch alles in der Transformation geklappt hat. Ziel soll es ja sein Kategorien zu finden, die dann auch wirklich Beobachtungen enthalten. Wenn wir uns also wieder halb leere Kategorien bauen, dann müssen wir nochmal ran.
```{r}
alter_combined_perc_obj <- alter_combined_tbl |>
tabyl(alter_recode) |>
mutate_if(is.numeric, round, 2)
```
In der @tbl-survey-age-1 siehst du dann das Ergebnis der Zusammenfassung der Antwortkategorien zum Alter. Wir haben zwar in der kleinsten Kategorie immer nur noch 14% der Beobachtungen aber das sind jetzt immerhin 25 Personen und nicht mehr 3 Teilnehmer. Das macht dann schon einen Unterschied mit dem wir dann besser rechnen könnten.
```{r}
#| echo: false
#| message: false
#| warning: false
#| label: tbl-survey-age-1
#| tbl-cap: "Zusammenfassung der Kategorien der Spalte `Alter` nach neuen, selbstdefinierten Kriterien. Ziel war es wenig belegte Kategorien zusammenzufassen."
alter_combined_perc_obj |>
kable(align = "c", "pipe")
```
Am Ende ist es natürlich wichtig, das du dann im Methodenteil deiner Arbeit oder Veröffentlichung genau beschreibst, wie du und warum du die Antwortmöglichkeiten zusammengefasst hast. Allgemein spricht nichts dagegen Antworten zusammenzufassen, es sollte nur nicht der Anschein erweckt werden, dass du dir dann am Ende die Ergebnisse zurechtbiegst.
### Flowchart
Das Flussdiagramm (eng. *flowchart*) liefert nochmal eien schönen Überblick über das Preprocessing der Daten. Du kannst damit gut zeigen, wie sich die Anzahl der Teilnehmer:innen von der Rekrutierung hin zur eigentlichen Analyse entwickelt hat. Es gibt eine große Anzahl an möglichen Darstellungsformen, wie eine [Google Suche nach `consort flowchart`](https://www.google.com/search?q=consort+flowchart&tbm=isch&ved=2ahUKEwjdx8flgcuEAxVqpf0HHf5YBrUQ2-cCegQIABAA&oq=flowchart+consort&gs_lp=EgNpbWciEWZsb3djaGFydCBjb25zb3J0KgIIADIGEAAYCBgeMgYQABgIGB5IsCJQpwVYpw9wAHgAkAEAmAF8oAGABaoBAzguMbgBAcgBAPgBAYoCC2d3cy13aXotaW1nwgIEECMYJ8ICBRAAGIAEwgIKEAAYgAQYigUYQ8ICBBAAGB7CAgcQABiABBgTwgIIEAAYCBgeGBOIBgE&sclient=img&ei=dJHdZd29BurK9u8P_rGZqAs&bih=673&biw=1590#imgrc=zO5hp91LiRP4EM) zeigt. Deshalb gibt es auch nicht *die* Flowchart für eine Fragebogenanalyse. Lasse dich einfach inspirieren und baue deine Flowchart so, dass jeder einfach sehen kann, wie sich deine Anzahl der Teilnehmer:innen geändert hat. Es kann auch sein, das diene Flowchart nur aus drei Kacheln besteht. Das ist dann auch in Ordnung und trotzdem besser als ein Fließtext.
In der @fig-flowchart siehst du dann einmal eine beispielhafte Flowchart für unseren Fragebogen zu der Haltung von Großkatzen. Ich habe die Flowchart in PowerPoint gebaut und die [PowerPoint Vorlage](https://github.com/jkruppa/jkruppa.github.io/blob/master/data/survey_flowchart.pptx) kannst du gerne selber verändern. Wie du dann so eine Flowchart aufbaust, hängt dann sehr von deinen Daten ab. In dem Kasten der entfernten Fragen, habe ich die gängigen Kriterien einmal aufgeführt. Du musst die nicht alle in der Form durchgehen. Es kann auch sein, dass du aus anderen Gründen Fragen entfernen möchtest, weil die Fragen zum Beispiel dann doch nicht mehr zur Forschunsgfrage passen. Ich habe dann noch unten die bivariaten Vergleiche für die beiden Fragen zur Haltung von Großkatzen und dem Erwerb zugefügt. Das kann man machen, muss man aber nicht. Je nachdem was du noch gemacht hast, kannst gerne noch weitere Kacheln hinzufügen oder aber Arme ergänzen.
![Beispielhafte Flowchart für unsere Tigerumfrage. Zu Beginn sind 843 Fragebögen gesendet worden von denen dann 173 als Rücklauf vorliegen. Wir haben dann dann noch die Fragen aufgereinigt und die Infromationen ebenfalls in die Flowchart geschriben. Abschließend haben wir noch für zwei Fragen eine bivariate Analyse für alle anderen Fragen durchgeführt.](images/survey-flowchart.png){#fig-flowchart fig-align="center" width="100%"}
::: callout-caution
## Geht das Ganze auch in R?
Natürlich können wir auch eine Flowchart mit etwas Aufwand in R bauen. Hier gibt es einmal das Tutorium [Building a flowchart](https://cran.r-project.org/web/packages/Gmisc/vignettes/Grid-based_flowcharts.html) sowie das R Paket `{DiagrammeR}` mit dem entsprechenden Tutorium [Data-driven flowcharts in R using `{DiagrammeR}`](https://mikeyharper.uk/flowcharts-in-r-using-diagrammer/). Eine Weitere Alternative ist das Tutorium [Introducing `{ggflowchart}`](https://nrennie.rbind.io/blog/introducing-ggflowchart/) wobei hier die Flowcharts eher sehr simple gehalten sind.
:::
### Repräsentative:r Teilnehmer:innen
Wenn ich einen Fragebogen auswerte, dann lasse ich mir gerne eine Tabelle der repräsentativen Teilnehmer rausgeben. Nicht immer funktioniert es, denn wir brauchen natürlich auch einiges an Teilnehmern. Manchmal sind die Anzahlen auch zu gering, dass ich von einem repräsentativen Teilnehmer sprechen würde. Nichtsdestotrotz, ich schaue mir das gerne einmal an. Ich schaue mir dafür die demographischen Fragen einmal an und erstelle mir dann eine Tabelle mit den Eigenschaften der häufigsten Teilnehmern. In unserem Fall möchte ich wissen, ob es Überschneidungen im Geschlecht, dem Alter sowie den Erwerb und der betrieblichen Stellung gibt. Technisch klebe ich die vier Spalten einfach mit `str_c()` zu einem String zusammen und zähle dann wie oft so ein String dann vorkommt. Dafür nutze ich die Funktion `tabyl()`, die mir sehr angenehm die Anzahlen und Prozente wiedergibt. Die Funktion [`reframe()`](https://www.tidyverse.org/blog/2023/02/dplyr-1-1-0-pick-reframe-arrange/#reframe) erlaubt es uns dann die Rückgabe von `tabyl()` in einen Datensatz.
```{r}
most_common_participant_tbl <- tiger_tbl |>
select(geschlecht, alter, f1Soziodemografisch, f3Soziodemografisch) |>
mutate(string = str_c(geschlecht, alter, f1Soziodemografisch, f3Soziodemografisch, sep = " ")) |>
na.omit() |>
reframe(janitor::tabyl(string)) |>
arrange(desc(n)) |>
mutate(percent = percent(percent))
```
In der @tbl-survey-most_common-1 findest du die tabellarische Übersicht über die vier häufigsten Teilnehmer in unserem Fragebogen nach den oben ausgewählten vier demographischen Fragen. Du siehst hier sehr schön welches Problem unsere Teilnehmer haben. Gut 50% der häufigsten Teilnehmer sind männlich und Betriebsleiter. Wir haben nur eine kleine Variation im Erwerb und im Alter. Wobei der Großteil unser Teilnehmer eben dann auch schon alt ist.
```{r}
#| echo: false
#| message: false
#| warning: false
#| label: tbl-survey-most_common-1
#| tbl-cap: "Tabellarische Übersicht über die vier häufigsten Teilnehmer in unserem Fragebogen nach vier demographischen Fragen."
most_common_participant_tbl |>
set_names("", "Anzahl", "[%]") |>
head(n = 4) |>
kable(align = c("lcr"), "pipe")
```
Musst du die Tabelle jetzt angeben? Vermutlich nicht. Aber wir wissen jetzt immerhin, wie sich unsere Population zusammensetzt. Das müssen wir natürlich beachten, wenn wir unsere Rückschlüsse aus dem Fragebogen ziehen. Das erlaubt uns dann auch eine sorgfältigere Diskussion unserer Ergebnisse.
## Visualisierung
Wie solltest du die Ergebnisse eines Fragebogens darstellen? Damit wir hier nicht immer wieder die Barplots oder Säulendiagramme aus dem Hut ziehen, zeige ich dir hier nochmal andere Möglichkeiten, die sehr ähnlich sind, aber doch anders. Prinzipiell ist es natürlich auch wieder nichts anderes als Säulendiagramme, aber dann doch in schöner. Wichtig ist nur, das du dir bewusst machst, welche Fragen du zusammen zeigen möchtest. Es macht meistens keinen Sinn *alle* Fragen in einer Abbildung darzustellen oder eben nur eine Frage zu visualisieren. Du willst ja meistens den Zusammenhang zwischen verschiedenen Fragen zeigen. Daher überlege dir, welche Fragen du zusammen in einem Block zeigen möchtest. Die Blöcke kannst du dann thematisch benennen und so dem Leser es einfacher machen deinen Gedankengang in der Auswertung zu folgen.
!["The reason to avoid pie charts" Quelle: wumo.com](images/eda/cake_chart.jpg){#fig-wumo-pie fig-align="center" width="100%"}
Eine Sache möchte ich dann aber doch noch loswerden und zwar meine tiefe Abneigung gegenüber Tortendiagrammen (eng. *pie charts*). Gerne kannst du Tortendiagramme in deiner Arbeit verwenden, ich kann dir nur sagen warum ich sie nichts nutzen würde. Neben dem wunderbarer Cartoon von Wulff & Morgenthaler gibt es aber noch andere wissenschaftlichere Gründe, die gegen die Verwendung sprechen. Barnett und Oguoma schreiben in [Here’s why you should (almost) never use a pie chart for your data](https://theconversation.com/heres-why-you-should-almost-never-use-a-pie-chart-for-your-data-214576) folgendes Fazit dem ich mich anschließen möchte.
> *Whenever we see pie charts, we think one of two things: their creators don’t know what they’re doing, or they know what they are doing and are deliberately trying to mislead. --- Barnett, A. und Oguoma V. (2024)*
Besuche gerne die Quelle und schaue dir die Visualisierungen einmal an. Beide zeigen sehr schön in dem Beitrag warum Tortendiagramme sehr verzerrend wirken und häufig nicht das mitteilen was man möchte. Die Beispiel finde ich sehr überzeugend. Es gibt mit @siirtola2019cost auch eine wissenschaftliche Veröffentlichung [The Cost of Pie Charts](https://trepo.tuni.fi/bitstream/handle/10024/117653/the_cost_of_pie_charts_2019.pdf?sequence=2) die als Fazit unter anderem folgendes Zitat hat.
> *The results show that the pie chart is slower and less accurate than the stacked bar chart, especially when the difference between the elements is small, but the participant find it slightly more pleasant to use. The participants also perceive the stacked bar chart as the most effective visualization. --- @siirtola2019cost*
Also klare Empfehlung für gestapelte Balkendiagramme für die Darstellung. Dann wollen wir uns verscheidende Pakete und deren Realisierung von der Darstellung von Likert Daten anschauen. Ich habe mir jetzt drei Pakete rausgesucht, die uns dabei behilflich sein können. Dann schauen wir uns im Folgenden einmal die Darstellung der Likert-Skala in drei R Paketen an.
1) Dem R Paket `{likert}`, dem auch irgendwie eine gute Tutoriumsseite des Paketes fehlt. Hier hilft dann das Tutorium [Survey data I/O with `{likert}`](https://graphdr.github.io/data-stories/posts/2022-02-13-survey-data-io/index.html) weiter.
2) Dem R Paket `{ggplot2}`, als Selbstbausatz in unserem universalen Visualisierungspaket.
3) Dem R Paket [`{sjPlot}`](https://strengejacke.github.io/sjPlot/) als eine weitere Möglichkeit Daten mit dem Fokus aus den Sozialwissenschaften darzustellen.
Wir immer kannst du schauen, ob du diese Pakete nutzt willst oder dann doch zu Excel umschwenkst. Prinzipiell lässt sich ja auch alles mit etwas mehr Arbeit in Excel nachbauen. Die Pakete erleichtern einem meiner Meinung nach nur die Darstellung.
### ... mit `{likert}`
Ich zeige hier nur einen Ausschnitt mit einer einzigen Abbildung. Wenn du mehr zu dem R Paket `{likert}` erfahren möchtest, dann nutze das tolle Tutorium [Survey data I/O with `{likert}`](https://graphdr.github.io/data-stories/posts/2022-02-13-survey-data-io/index.html). Wenn ich hier das gesamte Tutorium nachkoche ist ja dann auch niemanden geholfen. Was ist also die Idee des R Paketes `{likert}`? Wir können mir der Funktion `likert()` Fragen in der selben Likertskala zusammen in einer Abbildung darstellen. Wichtig ist hier, dass das Paket schon etwas älter ist und nur ein Objekt als `data.frame()` und keine `tibble()` akzeptiert.
In der @fig-survey-likert-plot-1 siehst du einmal die Darstellung der fünf Fragen zur Verbandsarbeit. Die Funktion `likert()` sortiert dabei auch nochmal sinnig deine Fragen von dem Anteil `trifft zu` und `trifft voll zu` zu den Anteilen von `trifft gar nicht zu` und `trifft nicht zu`. Diese Anteile siehst du dann auch nochmal an der rechten und linken Seite in absteigender und aufsteigender Reihenfolge abgebildet. Aus dem Grund kannst du auch nur Fragen mit den gleichen Antwortmöglichkeiten zusammenfassen. In der Mitte findest du dann die `weder noch` Angaben in Prozent. Eigentlich eine sehr schöne Form der Darstellung der Fragen. Ich musste noch die Legende etwas anpassen und die Beschreibung auf der $y$-Achse ausblenden.
Die Darstellungsform, wie das R Paket `{likert}` die Daten darstellt ist nicht unumstritten, wie das Tutorium [The case against diverging stacked bars](https://blog.datawrapper.de/divergingbars/) einmal diskutiert. Dabei wird davon abgeraten die divergierenden, gestapelten Balkendiagramme für die Darstellung von Prozentsätzen zu verwenden. Gestapelte 100%-Balkendiagramme wie in der @fig-survey-likert-plot-3 sind oft die bessere Option, vor allem, wenn es wichtig ist, den Anteil der äußersten Kategorien zu vergleichen. Daher bauen wir usn in `{ggplot}` nochmal die Darstellung anders nach.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-likert-plot-1
#| fig-align: center
#| fig-height: 5
#| fig-width: 7
#| fig-cap: "Darstellung der Antworten zu der Verbandsarbeit auf der Likertskala. Die Fragen sind nach dem Anteil `trifft zu` und `trifft voll zu` zu den Anteilen von `trifft gar nicht zu` und `trifft nicht zu` auf der rechten bzw. linken Seite der Balkendiagramme sortiert. Die mittlere graue Fläche stellt die `weder noch` Antworten dar."
tiger_ord_tbl |>
select(f1Verbandsarbeit:f5Verbandsarbeit) |>
mutate_all(fct_rev) |>
as.data.frame() |>
likert() |>
plot() +
ylab("") +
guides(fill = guide_legend(""))
```
Neben den Balkendiagrammen können wir uns mit der Option `type = "heat"` in dem `plot()`-Aufruf auch eine Heatmap der Fragen darstellen lassen. Wir haben dann eine andere Sortierung wie bei den Balkendiagrammen aber die Prozente der Antworthäufigkeiten sind dann nochmal farblich hervorgehoben. Die Sortierung entspricht dann der Reihenfolge der Fragen. Ich finde diese Art der Abbildung nochmal sehr spannend, da wir hier nochmal sehen, wo wir am meisten Antworten haben. So geht in der obigen Abbildung manchmal unter, wie viel dann eine Antwortmöglichkeit pro Frage genannt wurde. Darüber hinaus haben wir dann in den grauen Kästen noch die Durchschnittsnote dargestellt zusammen mit der Streuung.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-likert-plot-2
#| fig-align: center
#| fig-height: 4
#| fig-width: 7
#| fig-cap: "Heatmap der Häufigkeiten der Antworten pro Frage kombiniert mit der durchschnittlichen Note auf der Likertskala in den grauen Kästen."
tiger_ord_tbl |>
select(f1Verbandsarbeit:f5Verbandsarbeit) |>
mutate_all(fct_rev) |>
as.data.frame() |>
likert() |>
plot(type = "heat")
```
### ... mit `{ggplot}`
Manchmal müssen wir die Daten dann auch anders zusammenfassen oder aber keine standardisierten Antworten vorliegen. Dann hilf natürlich die ganze Abbildung einmal von Grund auf neu zu bauen. Dafür können wir dann `{ggplot}` nutzen. Im Folgenden wähle ich wieder die Fragen zur Verbandsarbeit und verwandle alle Fragen in eine numerische Variable. Dann baue ich mir für jede Frage eine zusammenfassende Tabelle über `tabyl()` und zwar über jede Frage mit der Funktion `map()`. Die Funktion `bind_rows()` liefert mir dann auch gleich einen Datensatz wieder. Am ende muss ich noch ein wenig an dem Datensatz rumarbeiten und fertig ist unser Objekt für den gestapelten Barplot.
```{r}
tiger_percent_tbl <- tiger_ord_tbl |>
select(f1Verbandsarbeit:f5Verbandsarbeit) |>
mutate_all(as.numeric) |>
map(tabyl) |>
bind_rows(.id = "id") |>
dplyr::rename(answer = ".x[[i]]") |>
mutate(answer = factor(answer, labels = zustimmung_ord))
```
In der @fig-survey-likert-plot-3 siehst du einmal das Ergebnis der Generierung in `ggplot()`. Wir immer kann man an ganz vielen Schrauben drehen, so dass ich hier noch die Prozente als Prozente habe wiedergeben lassen und auch die Farben etwas angepasst habe. Du kannst im Prinzip ja die Optionen rein und rausnehmen. Dann kannst du schauen, was passiert. Mit hat es natürlich Spaß gemacht die Abbildung nachzubauen, aber das R Paket `{likert}` liefert hier schneller was ich brauche. Ich habe hier natürlich nichts sortiert und damit bist du dann näher an den originalen Fragen dran. Beides hat dann natürlich Vor- und Nachteile. Dann hatte ich noch Probleme, dass die Prozente natürlich irgendwann in den Flächen verschwinden oder nicht mehr passen, wenn die Belegung zu klein ist. Dabei hilft dann das nächste Paket `{sjPlot}` aus.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-likert-plot-3
#| fig-align: center
#| fig-height: 4
#| fig-width: 8
#| fig-cap: "Gestapelte Balkendiagramme für die Fragen zur Vereinsarbeit. Die Fragen sind unsortiert nach der Reihenfolge des Auftretens. Teilweise sind die Flächen zu klein für die Darstellung der Prozente."
tiger_percent_tbl |>
ggplot(aes(x = fct_rev(id), y = valid_percent, fill = answer)) +
theme_minimal() +
geom_bar(position = "fill", stat = "identity", color = "black", width=0.7) +
scale_y_continuous(labels = scales::percent) +
geom_text(aes(label = scales::percent(valid_percent)),
position = position_stack(vjust = 0.5), size = 2) +
theme(legend.position = "none") +
scale_fill_manual(values = wes_palette("Zissou1", 8, type = "continuous")) +
labs(x = "" , y = "") +
coord_flip()
```
### ... mit `{sjPlot}`
Wir hatten ja eben das Problem, dass die Prozente nicht so richtig in die Kacheln passen plus wir hatten in `{ggplot}` ja auch nicht die Aufteilung wie in dem R Paket `{likert}`. Hier gibt es dann das R Paket `{sjPlot}` mit der [Funktion `plot_likert()`](https://strengejacke.github.io/sjPlot/reference/plot_likert.html). Das Paket wurde direkt für die Sozialwissenschaften gebaut und hat auch noch andere Funktionen, die eventuell von Interesse sind. Schau da doch einfach mal in die Referenz des Pakets. Wir konzentrieren uns also hier nur auf die eine Funktion. Wichtig ist hier, dass wir eigentlich nur gerade Anzahlen von Likertskalen darstellen können. Wenn wir eine ungerade Anzahl haben, dann müssen wir numerisch über die Option `cat.neutral` mitteilen, welche Position unsere neutrale Kategorie hat. In unserem Fall haben wir fünf Skalenstufen und deshalb ist unsere neutrale Stufe die dritte Stufe. Wir haben hier wiederum keine interne Sortierung der Fragen. Im Prinzip können wir hier die Zustimmung mit der Ablehnung direkt visuell vergleichen.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-likert-plot-4
#| fig-align: center
#| fig-height: 4
#| fig-width: 7
#| fig-cap: "Drastellung der Likertskala der Antworten zur Verbandsarbeit. Wir haben hier wiederum keine Sortierung in den Fragen. Die Antworten werden nach den positiven und negativen Antwortkategorien sortiert. Die neutrale Kategorie wird links an der Seite dargestellt."
tiger_ord_tbl |>
select(f1Verbandsarbeit:f5Verbandsarbeit) |>
plot_likert(cat.neutral = 3) +
theme_minimal() +
theme(legend.position = "bottom")
```
Und weil es so schön ist, dass ganze dann in der @fig-survey-likert-plot-5 nochmal für die Verbandskommunikation. Hier sieht man dann nochmal den Nachteil der neutralen Kategorie. Teilweise haben wir dann bis zur Hälfte der Teilnehmer:innen keine Angabe gemacht. Dann ist es immer schwierig daraus eine Schlussfolgerung zu ziehen. Ich würde dahwer eher auf neutrale Kategorien verzichten.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-likert-plot-5
#| fig-align: center
#| fig-height: 4
#| fig-width: 7
#| fig-cap: "Darstellung der Likertskala der Antworten zur Verbandkommunikation. Wir haben hier wiederum keine Sortierung in den Fragen. Die Antworten werden nach den positiven und negativen Antwortkategorien sortiert. Die neutrale Kategorie wird links an der Seite dargestellt."
tiger_ord_tbl |>
select(f1Imagearbeit:f4Imagearbeit) |>
plot_likert(cat.neutral = 3) +
theme_minimal() +
theme(legend.position = "bottom")
```
Neben dem R Paket `{sjPlot}` gibt es auch die Möglichkeit das R Paket `{HH}` aus dem Buch @heiberger2015statistical zu nutzen. Das Tutorium [Plot likert scale data](https://rpubs.com/Linh-LTP/1032218) stellt beide R Pakete `{sjPlot}` sowie `{HH}` einmal vor. Ich konzentriere mich hier auf das R Paket `{sjPlot}` mit der [Funktion `plot_likert()`](https://strengejacke.github.io/sjPlot/reference/plot_likert.html), da mir die Funktion irgendwie leichter von der Hand ging. Auf der anderen Seite reichen dann auch irgendwie drei Implementierungen der gleichen Darstellungsform irgendwie.
## Bivariate Analysen
Was sind bivariate Analysen? Eigentlich nichts anderes als Gruppenvergleich zwischen den kategoriellen Fragen oder aber eine Regression zwischen den kontinuierlichen Fragen. Also wir vergleichen zwei Fragen miteinander und wollen wissen, ob es in dem Antwortmuster der einen Fragen einen Unterschied gegeben der anderen Frage gibt. Eigentlich wiederholen wir hier sehr schnell, den [$\mathcal{X}^2$-Test](#sec-chi-test) für zwei kategorielle Variable, den [t-Test](#sec-ttest) oder den [Wilcoxon-Test](#sec-utest) für einen Vergleich einer kontinuierlichen Variable nach zwei Gruppen oder aber der [linearen Regression](#sec-modeling-simple-stat), wenn wir zwei kontinuierliche Variablen in Verbindung setzen wollen. Der Wahnsinn einer Fragebogenanalyse ist eigentlich, dass wir natürlich das für jede Fragenkombination machen können und uns dann vor lauert Testen gar nicht mehr wiederfinden. Deshalb kann ich nur Raten sich zu überlegen, was war nochmal meine Fragestellung und welche Fragen will ich jetzt im Bezug zu einer anderen Frage analysieren. Ich werde deshalb auch gar nicht mit der Problematik der [Adjustierung für multiple Vergleiche](#sec-statistisches-testen-alpha-adjust) beginnen, aber nur soviel, wenn du nur lange genug testest, wirst du auf jeden Fall was signifikantes finden, auch wenn in Wahrheit gar kein Unterschied zwischen den Fragen vorliegt. Siehe hierzu dann auch die tolle Arbeit von @austin2006testing mit dem Titel [Testing multiple statistical hypotheses resulted in spurious associations: a study of astrological signs and health](https://pubmed.ncbi.nlm.nih.gov/16895820/). Leider ist das PDF nicht mehr frei verfügbar, aber der Abstrakt sagt schon alles aus.
### Kategorial vs. kategoriale Frage
Was machen wir, wenn wir zwei Fragen mit Antwortmöglichkeiten mit Likertskalen miteinander verglichen wollen? Wir rechnen einen [$\mathcal{X}^2$-Test](#sec-chi-test) auf verschieden großen Kreuztabellen (eng. *cross table*). In R ist die einfachste Funktion sich eine Kreuztabelle zu erstellen die Funktion `xtabs()`. Du erhälst dann für die beiden Fragen die kreuzweisen Häufigkeiten wiedergeben. Wir machen das jetzt einmal für die beiden Spalten `haben_Sie_tiger` und dem Erwerb in der Spalte `f1Soziodemografisch`. Damit erhalten wir dann eine klassische 2x2 Kreuztabelle wieder.
```{r}
cross_tab <- xtabs(~ haben_Sie_tiger + f1Soziodemografisch, data = tiger_ord_tbl)
cross_tab
```
Mit einem schnellen Blick sehen wir eine recht gleichmäßige Verteilung der Antworten in der 2x2 Kreuztabelle. Wenn wir wirklich einen Unterschied hätten, dann wären die größeren Anzahlen dann auf einer der Diagonalen und nicht gleichmäßig verteilt. Wir können uns dass dann nochmal als relative Häufigkeiten in der Funktion `prop.table()` anschauen.
```{r}
prop.table(cross_tab) |>
round(2)
```
Und dann kommen wir auch schon zu dem Test mit der Funktion `assocstats()` aus dem R Paket `vcd()`. Die drei Koeffizienten am Ende des Ausdrucks sagen alle im Prinzip aus, wie stark die Assoziation zwischen den beiden Fragen ist. Wenn die Zahlen nahe Eins sind, dann haben die Fragen im Antwortmuster viel miteinander zu tun, wenn wir Zahlen nahe Null beobachten, dann haben wir eigentlich keinen Zusammenhang. Das deckt sich dann auch in unserem Beispiel mit dem $p$-Wert aus dem $\mathcal{X}^2$-Test nach Pearson.
```{r}
vcd::assocstats(cross_tab)
```
Jetzt müsstest du jede Frage für die Frage `f1Soziodemografisch` testen indem du dann immer wieder neu eine Kreuztablle baust. Das ist natürlich sehr aufwendig. Am Ende zeige ich dir dann nochmal wie es mit dem R Paket `{gtsummary}` sehr viel schneller geht.
### Kontinuierlich vs. kategoriale Frage
Wenn du eine kontinuierliche Antwort wie zum Beispiel auf die Frage nach der durchschnittlichen Dauer bis eine schwere Verletzung im Erlebnishof stattfindet mit einer kategoriellen Frage nach der Haltung von Tigern vergleichen willst, dann kannst du entweder den [t-Test](#sec-ttest) oder aber den [Wilcoxon-Test](#sec-utest) nutzen. Den t-Test nutzt du, wenn du annimmst das deine kontinuierliche Variable einigermaßen normalverteilt ist. Wenn das nicht der Fall ist, dann nutzt du den Wilcoxon-Test. Das ist hier natürlich stark verkürzt, aber für hier reicht es allemal. In der @fig-survey-bivariat-plot-1 siehst du dann einmal die beiden Boxplots für die beiden Gruppen der Tigerhaltung (ja/nein) und dann der Dauer bis zu einer Verletzung. Ich würde mal sagen, dass unsere Verteilungen eher schief sind und nicht sehr normalverteilt Aussehen. Wir haben einige Ausreißer in den Daten und deshalb würde ich hier eher zu dem Wilcoxon-Test raten.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-bivariat-plot-1
#| fig-align: center
#| fig-height: 4
#| fig-width: 7
#| fig-cap: "Boxplot der durschnittlichen Dauer bis zu einer schweren Verletzung eines Besuches auf einem Erlebnishof aufgeteilt nach der Haltung von Großkatzen oder eben Tigern."
ggplot(tiger_ord_tbl, aes(haben_Sie_tiger, f5dauer_verletzung,
fill = haben_Sie_tiger)) +
theme_minimal() +
geom_boxplot(show.legend = FALSE) +
scale_fill_okabeito()
```
Ich rechne dir dann aber in den beiden Tabs dann doch nochmal beide Tests durch. Dann kannst du bei dir in deinen Daten entscheiden welchen Test du nutzen willst. Wenn du später das R Paket `{gtsummary}` nutzt, dann wird meistens der Wilcoxon-Test für den Vergleich genutzt. Du kannst es aber auch umstellen auf den t-Test, ich belasse es aber meistens bei dem Wilcoxon-Test. Über alle Fragen anzunehmen, dass wir eine Normalverteilung vorliegen haben, ist dann doch eher unwahrscheinlich.
::: panel-tabset
## Der t-Test
Im Folgenden dann einmal der Code für den einfachen t-Test. Wir sehen dann auch, dass wir keinen signifikanten Unterschied nachweisen können, da unser p-Wert über dem Signifikanzniveau mit $\alpha$ gleich 5% liegt. Da ich hier nicht mit der Annahme der Normalverteilung an die Daten leben kann, ist das hier nur eine Demonstration.
```{r}
t.test(f5dauer_verletzung ~ haben_Sie_tiger, tiger_ord_tbl)
```
## Der Wilcoxon-Test
Dann einmal der Code für den Wilcoxon-Test. Wir sehen dann auch hier, dass wir keinen signifikanten Unterschied nachweisen können, da unser p-Wert über dem Signifikanzniveau mit $\alpha$ gleich 5% liegt. Der t-Test ist etwas verzerrt, da wir vermutlich keine Normalverteilung in den Daten haben. Der p-Wert beim Wilcoxon-Test ist daher erwartungsgemäß niedriger.
```{r}
wilcox.test(f5dauer_verletzung ~ haben_Sie_tiger, tiger_ord_tbl,
conf.int = TRUE)
```
:::
### Kontinuierlich vs. Kontinuierlich Frage
Am Ende dann noch den Fall, dass du dir zwei kontinuierliche Fragen anschauen möchtest und wissen willst, ob diese Fragen etwas miteinander zu tun haben. Prinzipiell ist es dann eine [simple lineare Regression](#sec-modeling-simple-stat) oder aber [nicht lineare Regression](#sec-non-linear) je nachdem, ob du an einen linearen Zusammenhang glaubst oder nicht. Wir haben uns ja in dem Abschnitt weiter oben schon die [Korrelation](#sec-lin-reg-corr) angeschaut, wenn du von einem linearen Zusammenhang ausgehst, dann dann kannst du natürlich auch die Korrelation zwischen den kontinuierliche Fragen berechnen.
Das [R Paket `{correlation}`](https://easystats.github.io/correlation/index.html) erlaubt es uns dabei auch relativ flott und einfach die Korrelation zu berechnen. Es gibt eine Menge an Korrelationskoeffizienten, die das Paket berechnen kann. Wir bleiben hier dann bei den Klassiker nach Spearman, wenn keine Normalverteilung vorliegt. In dem folgenden Tabs habe ich dir dann einmal berechnet, wie die Korrelation über alle Fragebögen aussieht und dann einmal getrennt nach der Haltung von Tigern. Ich verzichte hier auch auf eine Adjustierung für multiple Vergleiche. Ich schmeiße dann noch die Teststatistik `S` raus, dann ist es kompakter. Auch können wir mit dem Paket sehr einfach gute Abbildungen für die Korrelation erstellen, aber das wird dann hier einfach zu viel. Schaue dazu dann einfach in das Kapitel zu [Korrelation](#sec-lin-reg-corr).
::: panel-tabset
## Über alle Fragebögen
Wenn wir über alle kontinuierlichen Fragen hinweg die Korrelation rechnen wollen, dann können wir die Funktion `correlation()` aus dem gleichnamigen R Paket nutzen. Ich nutze hier die Methode nach Spearman, aber es gibt eine gewaltige Menge an möglichen [Typen von Methoden](https://easystats.github.io/correlation/reference/correlation.html) um die Korrelation zu berechnen. Wir kriegen auch gleich einen Test für die Signifikanz mitgeliefert.
```{r}
#| warning: false
#| message: false
tiger_tbl |>
select(f5dauer_verletzung, f6einkommen_jahr, f7gruppengroesse, f8eis_verkauf) |>
correlation(method = "spearman", p_adjust = "none") |>
select(-S)
```
## Gruppiert nach Tigerhaltung
Häufig wollen wir uns dann die Korrelation von kontinuierlichen Fragen auch noch aufgeteilt nach einer anderen kategoriellen Frage anschauen. In dem Fall nutzen wir einfach die Funktion `group_by()` um unseren Datensatz einmal nach einer anderen Frage zu gruppieren. Dann berechnen wir wieder die paarweise Korrelation. Auch hier erhalten wir gleich die Signifikanz mitgeliefert.
```{r}
#| warning: false
#| message: false
tiger_tbl |>
select(haben_Sie_tiger, f5dauer_verletzung, f6einkommen_jahr, f7gruppengroesse, f8eis_verkauf) |>
group_by(haben_Sie_tiger) |>
correlation(method = "spearman", p_adjust = "none") |>
select(-S)
```
:::
Ich zeige dir hier einmal den Fall für die lineare Regression und die nicht linearen Regression mit einem Polynom. Den Rest müsstest du dann dir nochmal in den entsprechenden Kapiteln anschauen, wenn du hier tiefer einstiegen willst. Meistens ist das nicht nötig und frage dich immer, brauche ich diese Analyse von zwei kontinuierlichen Fragen wirklich oder bin ich hier gerade in einem Kaninchenbau, weil es geht?
::: panel-tabset
## Lineare Regression
Die lineare Regression ist sehr schnell für zwei Variablen gerechnet. Wir wollen hier einmal sehen, in wie weit ein Zusammenhang zwischen dem Eisverkauf und der Gruppengröße vorliegt. Ich lege hier einmal den Eisverkauf auf die $y$-Achse und den die Gruppengröße auf die $x$-Achse. Wenn also die Gruppengröße ansteigt, wie verändert sich dann der Eisverkauf auf dem Hof. Aus der Korrelationsanalyse wissen wir ja schon, dass es hier einen Effekt gibt. Und wir sehen tatsächlich einen kanpp signifikanten Zusammenhang.
```{r}
#| warning: false
#| message: false
lm(f8eis_verkauf ~ f7gruppengroesse, tiger_tbl) |>
model_parameters()
```
Schauen wir uns den Zusammenhang nochmal in der @fig-survey-bivariat-plot-2 einmal an. Auch hier wäre ich dann eher vorsichtig. Der Anstieg ist eher schwach und durch ein paar Punkte an der rechten Seite getrieben. Wir könnten zwar sagen, dass wir mit jedem Besucher pro Gruppe mehr Eis verkaufen, aber das ist eher von schwacher Validität. Ich wäre hier also vorsichtig von einem echten Zusammenhang zu sprechen.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-bivariat-plot-2
#| fig-align: center
#| fig-height: 4
#| fig-width: 7
#| fig-cap: "Scatterplot des Eisverkaufs abhängig von der Gruppengröße der Besucher auf einem Erlebnishof. Eine Gerade aus einer linearen Regression wurde ergänzt."
ggplot(tiger_tbl, aes(f7gruppengroesse, f8eis_verkauf)) +
theme_minimal() +
geom_smooth(method = "lm", color = "#CC79A7", se = FALSE) +
geom_point()
```
## Nicht lineare Regression
Wir können auch eine nicht lineare Regression einmal ausprobieren. Hier hilft dann auch wieder das richtige [Kapitel zur nicht linearen Regression](#sec-non-linear) weiter. Hier rechne ich dann eine Multivariate Fractional Polynomials (abk. *mfp*) Regression. Details sind hier nicht so wichtig, die Idee ist jedoch simple. Anstatt selber zu überlegen, wie die nicht lineare Formel für unsere Regression wäre, lassen wir das den Algorithmus `mfp()` machen.
```{r}
mfp_fit <- mfp(f8eis_verkauf ~ fp(f7gruppengroesse), tiger_tbl)
```
Wir brauchen zum einen das Polynom, hier haben wir gar keins, denn die Funktion `mfp()` sagt, dass der lineare Zusammenhang am besten wäre.
```{r}
mfp_fit$formula
```
Gut, dann eben noch die Koeffizienten für unsere Geradengleichung.
```{r}
mfp_fit$coefficients
```
Und dann können wir auch schon alles zusammenbauen. Wenn du dir jetzt die Funktion eine Minute länger ansiehst, dann kommt im Prinzip das gleiche wie bei der linearen Regression raus. Wir können die Gleichung auch auflösen, da unser Polynom ja nur 1. Grades ist.
$$
weight \sim 19.55 + 2.76 \cdot \left(\cfrac{f7gruppengroesse}{10}\right)^{1}
$$
Wir bauen uns dann noch die Geradengleichung diesmal händisch über eine selber erstellte Funktion mit `\(x)` nach. Es gibt wie immer verschiedene Möglichkeiten, diese hier ist dann die etwas einfachere.
```{r}
f7gruppengroesse_func <- \(x) {19.55 + 2.76 * (x/10)^1}
```
Dann können wir uns auch schon den Zusammenhang nochmal in der @fig-survey-bivariat-plot-3 anschauen. Es ist der gleiche Zusammenhang wie dann schon in der linearen Regression. Die Funktion `mfp()` hat kein besseres Polynom gefunden.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-bivariat-plot-3
#| fig-align: center
#| fig-height: 4
#| fig-width: 7
#| fig-cap: "Scatterplot des Eisverkaufs abhängig von der Gruppengröße der Besucher auf einem Erlebnishof. Eine Gerade aus einer nicht linearen Regression wurde ergänzt."
ggplot(tiger_tbl, aes(f7gruppengroesse, f8eis_verkauf)) +
theme_minimal() +
geom_function(fun = f7gruppengroesse_func, color = "#CC79A7") +
geom_point()
```
:::
### Mit `tbl_summary()`
Wenn du einmal schnell über alle Fragen aus deinem Fragebogen wissen willst, ob es einen Zusammenhang zu einer anderen kategoriellen Frage gibt, dann nutze das R Paket `{gtsummary}`. Das Paket hat über die Funktion `tbl_summary()` die Möglichkeit die Ausgabe für eine andere kategorielle Frage aufzuspalten und zu testen. Damit haben wir dann gleich sehr viel weniger Arbeit. Wir machen das jetzt einmal exemplarisch für die Frage *Halten Sie aktuell Tiger oder andere Großkatzen auf Ihrem Erlebnishof?*.
```{r}
#| eval: false
tiger_ord_tbl |>
set_names(short_question_tbl$question) |>
tbl_summary(by = "Halten Sie aktuell Tiger oder andere Großkatzen auf Ihrem Erlebnishof?") |>
add_p()
```
Ich habe dir wie immer die Ausgabe einmal zusammengeklappt, damit hier nicht die gesamte Tabelle alles überlappt. Wir sehen, dass wir einige Unterschiede zwischen den Höfen mit und ohne Großkatzen über alle Fragen in den Antwortmustern finden. Beachte immer, dass die Prozente bei den kategoriellen Fragen getestet werden und nicht die absoluten Anzahlen direkt. Auch gibt es keine Richtung des Effekts. Du musst dann selber schauen wo in den Antworten der Unterschied zu finden ist. Kontinuierliche Antworten werden dann entsprechend auch über einen t-Test oder einer ANOVA getestet. Teilweise dann auch über einen Wilcoxon-Test, wenn die Normalverteilung nicht gegeben ist. Daher macht es einem diese Funktion schon sehr einfach die Fragen flott auszuwerten.
::: {.callout-note collapse="true"}
## Bivariate Analyse mit der Funktion `tbl_summary()` für die Tigerhaltung
```{r}
#| echo: false
#| message: false
#| warning: false
#| label: tbl-survey-tiger-summary_by
#| tbl-cap: "Bivariate Analyse der einzelenen Fragen und deren Antwortverteilung aufgeteilt nach der Frage zur der Haltung von Tigern. Anhand der Tabelle können fehlende Werte und ungleichmäßig beantwortete Fragen erkannt und dann ausgeschlossen werden."
tiger_ord_tbl |>
set_names(short_question_tbl$question) |>
tbl_summary(by = "Halten Sie aktuell Tiger oder andere Großkatzen auf Ihrem Erlebnishof?") |>
add_p()
```
:::
## Multivariate Analysen
Kommen wir am Ende noch zu den [multivariate Verfahren](#sec-pca-main). Also eigentlich etwas, was in den meisten Abschlussarbeiten dann nicht mehr gemacht wird. Auch hier gebe ich dann keine Übersicht über die Methoden und was alles geht, sondern konzentriere mich auf die Hauptkomponentenanalyse oder auch PCA genannt. Wenn du mehr lesen willst, dann besuche einfach das entsprechende Kapitel hier in dem Buch zu den [multivariate Verfahren](#sec-pca-main). Die Idee ist eigentlich ganz simple, wir wollen uns alle Fragen und alle Antworten gemeinsame anschauen und herausfinden, ob es eine Korrelation zwischen den Fragen oder den Teilnehmern gibt. Wir betrachten dabei nicht einzelne Fragen sondern die *gesamte* Fragenmatrix. Diese Korrelation zwischen allen Fragen simultan wollen wir dann einmal visualisieren. Auch hier stellt sich natürlich die Frage, ob es so sinnvoll ist wirklich alles in die PCA zu schmeißen. Vermutlich ist eine thematische Auswahl über `select()` besser. Hier machen wir aber einmal alles zusammen.
Wir brauchen auf jeden Fall nur numerische Daten. Daher wandele ich meinen Faktordatensatz `tiger_fct_tbl` einmal in einen numerischen Datensatz um indem ich jede Spalte auf numerisch setze. Dann möchte ich noch die Kurznamen der Fragen haben, da ich sonst nichts mehr in den Abbildungen erkenne.
```{r}
tiger_num_tbl <- tiger_fct_tbl |>
mutate_all(as.numeric) |>
set_names(short_question_tbl$ques_id)
```
Ich lasse dann einmal die Funktion `PCA()` auf den Daten laufen. Das wichtige ist hier noch, dass ich gerne die Antworten alle über die Option `scale.unit` skalieren möchte. Damit haben dann alle Antworten den gleichen numerischen Bereich. Das ist natürlich eine künstliche Maßnahme, die aber die PCA verbessert. Dann schaue ich mi nur die ersten beiden Hauptkomponenten mit der Option `ncp = 2` an.
```{r}
#| warning: false
#| message: false
pca_tiger <- PCA(tiger_num_tbl, scale.unit = TRUE,
ncp = 2, graph = FALSE)
```
In der @fig-survey-pca-1 schaue ich mir einmal die Effekt der Fragen, also der Spalten, an. Die ersten beiden Dimensionen der Hauptkomponentenanalyse werden dargestellt. Leider erklären beide Hautkomponenten nur sehr wenig der Varianz, so dass die Aussagekraft der Hauptkomponentenanalyse schwach ist. Daher möchte ich wissen, ob irgendwelche Fragen ähnliche Korrelationen zusammen haben. Je größer der `cos2`-Wert ist, desto mehr Einfluss auf die erklärte Varianz haben die Variablen. Fragen die in unterschedliche Richtungen zeigen, haben ein gegensätzliches Antwortmuster.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-pca-1
#| fig-align: center
#| fig-height: 7
#| fig-width: 7
#| fig-cap: "Betrachtung der einzelnen Fragen zueinander. Die ersten beiden Dimensionen der Hauptkomponentenanalyse werden dargestellt. Leider erklären beide Hauptkomponenten nur sehr wenig der Varianz, so dass die Aussagekraft der Hauptkomponentenanalyse schwach ist."
fviz_pca_var(pca_tiger, col.var = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE)
```
In der @fig-survey-pca-2 schauen wir einmal auf die Individuen, also den Zeilen, gegeben der Fragen. Auch hier sehen wir, dass wir eigentlich keine großen Auffäligkeiten haben. Eventulle zwei der Teilnehmer:innen in der Zeile 131 und 172 könnten wir nochmal anschauen.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-pca-2
#| fig-align: center
#| fig-height: 7
#| fig-width: 7
#| fig-cap: "Betrachtung der einzelnen Individuen zueinander. Die ersten beiden Dimensionen der Hauptkomponentenanalyse werden dargestellt. Leider erklären beide Hauptkomponenten nur sehr wenig der Varianz, so dass die Aussagekraft der Hauptkomponentenanalyse schwach ist."
fviz_pca_ind(pca_tiger,
col.ind = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE) +
scale_x_continuous(expand = expansion(add = c(0.5, 1))) +
scale_y_continuous(expand = expansion(add = c(0.5, 0.5)))
```
Mit `slice()` könnten wir uns jetzt die Zeilen für die Individuen 131 und 172 einmal anschauen. Oder wir gehen dann in den Exceldatensatz und schauen in die entsprechenden Zeilen. Aber Achtung, in Excel zählt die Überschrift immer als eine Zeile. Daher musst du dann in Excel in die Zeile 132 und 173 für die entsprechenden Einträge schauen. Ich habe das mal gemacht und ich finde keine Besonderheiten, die jetzt einen Ausschluss rechtfertigen würden. Aber nochmal, die Hauptkomponenten erklären auch nur sehr wenig der Varianz, daher ist die Aussagekraft eben vage.
Abschließend können wir nochmal schauen, ob wir Cluster in unseren Daten wiederfinden. Ich nutze dazu den `kmeans()`-Algorithmus und möchte mal sehen, ob ich auf den Individuen etwas finden kann.
```{r}
ind_tiger <- get_pca_ind(pca_tiger)
grp_tiger_ind <- kmeans(ind_tiger$coord, centers = 2, nstart = 25) %>%
pluck("cluster") %>%
as_factor()
```
Abschließend siehst du dann einmal die beiden Cluster mit `centers = 2` auf der PCA der Individuen. Ich habe dann die Individuen nach der Haltung der Tiger gelabelt. Wie du siehst, sehen wir zwar zwei Cluster, die sich auch recht stark überlappen, und auch nicht die Tigerhaltung widerspiegeln. Wir schon oben gesagt, die Hauptkomponenten erklären zu wenig der Varianz um hier etwas sinniges zu finden.
```{r}
#| warning: false
#| message: false
#| label: fig-survey-pca-3
#| fig-align: center
#| fig-height: 7
#| fig-width: 7
#| fig-cap: "Clusteranalyse mit dem $k$-means Algorithmus auf dem gesamten Fragebogen. Die Teilnehmer sind nach der Haltung der Tiger gelabelt. Es findet sich jedoch kein Zusammenhang zwischen den gefunden Clustern und der Tigerhaltung."
fviz_pca_ind(pca_tiger,
geom.ind = "point",
col.ind = grp_tiger_ind,
palette = c("#0072B2", "#CC79A7"),
addEllipses = TRUE,
legend.title = "Groups", mean.point = FALSE) +
geom_label(aes(label = tiger_num_tbl$s1))
```
## Referenzen {.unnumbered}