626 156 10MB
German Pages 382 Year 2020
5. Auflage
Luhmann
R für Einsteiger Einführung in die Statistik-Software für die Sozialwissenschaften Online-Material
Luhmann R für Einsteiger
Maike Luhmann
R für Einsteiger Einführung in die Statistik-Software für die Sozialwissenschaften Mit Online-Material 5., überarbeitete Auflage
Prof. Dr. Maike Luhmann Ruhr-Universität Bochum Fakultät für Psychologie Psychologische Methodenlehre Universitätsstr. 150 Raum IB E4/185 - Postfach 17 44780 Bochum E-Mail: [email protected]
Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Jede Verwertung ist ohne Zustimmung des Verlags unzulässig. Das gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronische Systeme.
Dieses Buch ist erhältlich als: ISBN 978-3-621-28790-6 Print ISBN 978-3-621-28791-3 E-Book (PDF) 5., überarbeitete Auflage 2020 © 2020 Programm PVU Psychologie Verlags Union in der Verlagsgruppe Beltz · Weinheim Basel Werderstraße 10, 69469 Weinheim Alle Rechte vorbehalten Lektorat: Salome Fabianek Coverbild: IconicBestiary/iStock/Getty Images Plus; R-Logo © 2016 The R Foundation, unter CCBY-SA 4.0 modifiziert Herstellung: Lelia Rehm Satz: Reproduktionsfähige Vorlagen der Autorin Gesamtherstellung: Beltz Grafische Betriebe, Bad Langensalza Printed in Germany Weitere Informationen zu unseren Autor_innen und Titeln finden Sie unter: www.beltz.de
Powered by TCPDF (www.tcpdf.org)
5
Inhaltsübersicht
Inhaltsübersicht Vorwort zur fünften Auflage
12
1
Einleitung
13
2
Installation
17
3
Ein erster Überblick
19
4
Einführung in die Programmiersprache
36
5
Objekte
45
6
Daten importieren
63
7
Datenaufbereitung
71
8
Univariate deskriptive Statistik
113
9
Bivariate deskriptive Statistik
126
10 Datenvisualisierung
137
11
Wahrscheinlichkeitsverteilungen
183
12
Mittelwertsvergleiche mit t-Tests
189
13
Varianzanalyse ohne Messwiederholung
204
14 Varianzanalyse mit Messwiederholung
221
15
Grundlagen der Regressionsanalyse
238
16
Spezielle Regressionsmodelle
256
17
Nonparametrische Verfahren
285
18
Verfahren für die Testkonstruktion
294
19
Lineare Strukturgleichungsmodelle
309
6
Inhaltsübersicht
20 Mehrebenenanalyse
327
21
343
Poweranalysen und Stichprobenumfangsplanung
22 Ausgaben exportieren
346
23 Tipps für den Workflow
353
24 Troubleshooting
355
Anhang A: Datensätze
358
Anhang B: Pakete
360
Hinweise zum Online-Material
361
Literatur
362
Sachwortverzeichnis
367
7
Inhalt
Inhalt Vorwort zur fünften Auflage
12
1 1.1 1.2 1.3 1.4 1.5
Einleitung Warum R? Für wen ist dieses Buch? Wie benutzt man dieses Buch? Weiterentwicklungen und Aktualität des Buchs Verwendete Schriftarten
13 14 14 15 15 16
2 2.1 2.2
Installation Download und Installation von R Download und Installation von RStudio
17 17 18
3 3.1 3.2 3.3 3.4
Ein erster Überblick RStudio im Überblick Zusätzliche Pakete Hilfe zu R Die wichtigsten Funktionen im Überblick
19 19 27 31 35
4 4.1 4.2 4.3 4.4 4.5 4.6
Einführung in die Programmiersprache R als Taschenrechner Logische Abfragen Funktionen Kommentare Ein paar Stilregeln Übungen
36 36 37 38 43 43 44
5 5.1 5.2 5.3 5.4 5.5 5.6 5.7
Objekte Neue Objekte anlegen Objekttypen Elemente aus Objekten auswählen Der Workspace Objekte speichern und öffnen Die wichtigsten Funktionen im Überblick Übungen
45 45 48 53 56 58 61 62
8
Inhalt
6 6.1 6.2 6.3 6.4 6.5 6.6
Daten importieren Daten aus Textdateien einlesen Andere Datenformate einlesen Daten betrachten Daten speichern Die wichtigsten Funktionen im Überblick Übungen
63 63 68 68 69 70 70
7 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 7.10
Datenaufbereitung Klassische und moderne Datenaufbereitung Variablen erstellen und bearbeiten Data Frames reduzieren Data Frames sortieren Data Frames zusammenfügen Data Frames umstrukturieren Fortgeschrittene Datenaufbereitung Funktionen aus den R-Basispaketen im Überblick tidyverse-Funktionen im Überblick Übungen
71 71 74 89 95 97 101 107 109 110 111
8 8.1 8.2 8.3 8.4 8.5
Univariate deskriptive Statistik Häufigkeitstabellen Deskriptive Kennwerte Gruppenvergleiche Die wichtigsten Funktionen im Überblick Übungen
113 113 117 122 124 125
9 9.1 9.2 9.3 9.4 9.5
Bivariate deskriptive Statistik Kontingenztabellen Zusammenhangsmaße für metrische Variablen Zusammenhangsmaße für nicht-metrische Variablen Die wichtigsten Funktionen im Überblick Übungen
126 126 129 134 135 136
10 10.1 10.2 10.3
Datenvisualisierung Einführung in die klassischen Grafik-Funktionen Einführung in ggplot2 Ausgewählte Diagramme
137 138 150 159
Inhalt
10.4 10.5 10.6 10.7 10.8
Die wichtigsten klassischen Grafik-Funktionen im Überblick Zusätzliche Argumente für klassische Grafik-Funktionen Die wichtigsten ggplot2-Funktionen im Überblick Zusätzliche Argumente für ggplot2-Funktionen Übungen
180 180 181 181 182
11 11.1 11.2 11.3 11.4 11.5 11.6
Wahrscheinlichkeitsverteilungen Grafische Darstellung der Wahrscheinlichkeitsverteilung Berechnung von Quantilen Berechnung von Flächenanteilen bzw. p-Werten Tests für die Prüfung der Normalverteilungsannahme Die wichtigsten Funktionen im Überblick Übungen
183 184 186 186 187 188 188
12 12.1 12.2 12.3 12.4 12.5
Mittelwertsvergleiche mit t-Tests Einstichproben-t-Test t-Test für unabhängige Stichproben t-Test für abhängige Stichproben Die wichtigsten Funktionen im Überblick Übungen
189 189 194 199 202 203
13 13.1 13.2 13.3 13.4
Varianzanalyse ohne Messwiederholung Einfaktorielle Varianzanalyse ohne Messwiederholung Mehrfaktorielle Varianzanalyse ohne Messwiederholung Die wichtigsten Funktionen im Überblick Übungen
204 204 211 219 220
14 14.1 14.2 14.3 14.4 14.5
Varianzanalyse mit Messwiederholung Datenstruktur Einfaktorielle Varianzanalyse mit Messwiederholung Mehrfaktorielle gemischte Varianzanalyse Die wichtigsten Funktionen im Überblick Übungen
221 221 222 228 237 237
15 15.1 15.2 15.3 15.4
Grundlagen der Regressionsanalyse Einfache lineare Regression Multiple Regression Hierarchische Regression Modellannahmen prüfen
238 238 243 245 249
9
10
Inhalt
15.5 15.6
Die wichtigsten Funktionen im Überblick Übungen
254 255
16 16.1 16.2 16.3 16.4 16.5 16.6 16.7
Spezielle Regressionsmodelle Kategoriale Prädiktoren Kovarianzanalyse Moderierte Regression Nicht-lineare Regression Logistische Regression Die wichtigsten Funktionen im Überblick Übungen
256 256 260 263 275 278 283 284
17 17.1 17.2 17.3 17.4 17.5
Nonparametrische Verfahren Der χ²-Test Der Wilcoxon-Test Der Kruskal-Wallis-Test Die wichtigsten Funktionen im Überblick Übungen
285 285 288 292 293 293
18 18.1 18.2 18.3 18.4
Verfahren für die Testkonstruktion Exploratorische Faktorenanalyse Itemanalyse und interne Konsistenz Die wichtigsten Funktionen im Überblick Übungen
294 294 304 308 308
19 19.1 19.2 19.3 19.4 19.5 19.6 19.7 19.8
Lineare Strukturgleichungsmodelle Multiple Regression mit lavaan Pfadmodell mit Mediatorvariable Konfirmatorische Faktorenanalyse Kombination von Mess- und Strukturmodell Erstellen eines Pfaddiagramms Weitere Funktionen und ergänzende Pakete Die wichtigsten Funktionen im Überblick Übungen
309 309 311 317 322 324 325 325 326
20 20.1 20.2 20.3
Mehrebenenanalyse Das Nullmodell Das Random-Intercept-Modell Das Random-Slopes-Modell
327 327 330 335
11
Inhalt
Powered by TCPDF (www.tcpdf.org)
20.4 20.5 20.6
Modelle mit Ebene-2-Prädiktoren Die wichtigsten Funktionen im Überblick Übungen
338 341 342
21 21.1 21.2 21.3
Poweranalysen und Stichprobenumfangsplanung Poweranalysen mit dem pwr-Paket Simulationsbasierte Poweranalysen Übungen
343 343 344 345
22 22.1 22.2 22.3 22.4 22.5
Ausgaben exportieren Daten exportieren Tabellen exportieren Diagramme exportieren Kommentierte Ausgaben mit R Markdown erstellen Die wichtigsten Funktionen im Überblick
346 346 347 348 349 352
23 23.1 23.2 23.3
Tipps für den Workflow Ordner- und Dateienstruktur RStudio-Projekte und relative Pfade Aufbau eines R-Skripts
353 353 353 354
24 24.1 24.2 24.3 24.4
Troubleshooting Typische Tippfehler Häufige Fehlermeldungen Vorgehen bei der Fehlersuche Probleme mit der Darstellung von R-Skripten
355 355 356 356 357
Anhang A: Datensätze
358
Anhang B: Pakete
360
Hinweise zum Online-Material
361
Literatur
362
Sachwortverzeichnis
367
12
Vorwort zur fünften Auflage
Vorwort zur fünften Auflage
In den fünf Jahren seit Erscheinen der letzten Auflage dieses Buchs ist R zu einem der beliebtesten Statistik-Programme in Lehre und Forschung und auch außerhalb der Hochschulen geworden. Auch die Ressourcen für R haben stark zugenommen. Habe ich in der letzten Auflage noch auf wenige einschlägige Webseiten zu R verweisen können, ist das Angebot an kostenlos verfügbaren Video-Tutorials, eBooks, Webinaren und Kurzanleitungen mittlerweile fast unüberschaubar. Wozu dann noch ein klassisches Lehrbuch zu R? Ich gebe mittlerweile seit vielen Jahren Kurse zur Einführung in R. In diesen Kursen wird immer wieder deutlich, dass das große Angebot an Ressourcen für Einsteigerinnen und Einsteiger häufig überfordernd ist. Ziel dieses Buchs ist es daher, den Einstieg in R zu strukturieren und damit den Leserinnen und Lesern ein Grundverständnis von R zu vermitteln, mit dem sie anschließend die zahlreichen großartigen Online-Angebote effizient nutzen können. In diesem Buch werden die statistischen Verfahren behandelt, die in den Sozialwissenschaften am häufigsten gelehrt und angewandt werden. Für die fünfte Auflage wurden alle Kapitel aktualisiert und teilweise komplett neu geschrieben (z. B. die Kapitel zu Datenaufbereitung und Datenvisualisierung). Zudem sind einige kleinere Kapitel dazugekommen, z. B. zu Workflow und Troubleshooting. Eine solche umfassende Überarbeitung des Buchs war nur möglich durch tatkräftige Unterstützung. Ich möchte mich besonders bei Peter Hähner, Flavio Schröder, Marie von Rogal und Merle Widlok bedanken, die intensiv die Texte und Befehle der vorherigen und der neuen Auflage geprüft und korrigiert haben. Ein großer Dank geht auch an die R Community auf Twitter, über die ich immer wieder neue Tipps und Updates zu R erhalte und die meine Fragen zu R schnell und hilfreich beantwortet haben. Zudem bedanke ich mich herzlich bei meinem Team, meinen Studierenden, Workshop-Teilnehmerinnen und -Teilnehmern, Kolleginnen und Kollegen und natürlich bei allen Leserinnen und Lesern, deren Fehlermeldungen, konstruktive Verbesserungsvorschläge und positive Rückmeldungen diese neue Auflage möglich gemacht haben. Für alle verbleibenden Unklarheiten und Fehler bin ich natürlich allein verantwortlich. Bitte kontaktieren Sie mich, wenn Sie Fehler entdecken sollten oder Vorschläge zur Verbesserung des Buchs machen möchten. Köln, im Sommer 2020
Powered by TCPDF (www.tcpdf.org)
Maike Luhmann
1
1
Einleitung
Einleitung
In den letzten Jahren hat die Statistik-Software R (R Core Team, 2019b) deutlich an Beliebtheit gewonnen. Nicht nur an den meisten Universitäten wird R mittlerweile in Lehre und Forschung eingesetzt, sondern auch in vielen Unternehmen (Bhalla, 2016). Die Vorteile von R sind schon lange bekannt – warum also jetzt dieser rasante Aufstieg? Dafür gibt es mindestens zwei Gründe. Zum einen leben wir in einem Daten-Zeitalter, d. h., Daten werden kontinuierlich und von in großen Mengen gesammelt. Die Nutzung dieser Daten nimmt sowohl in der Forschung als auch in der freien Wirtschaft einen immer größeren Stellenwert ein, und unter dem Stichwort »Data Science« hat sich mittlerweile eine ganze Berufsgruppe etabliert, deren Spezialität das Aufbereiten und Auswerten großer Datenmengen ist. Eines der in diesem Feld am häufigsten eingesetzten Statistik-Programme ist R (Dataflair Team, 2019). Zum anderen findet in der sozialwissenschaftlichen Forschung, besonders in der Psychologie, derzeit ein Umbruch statt. Immer mehr Forscherinnen und Forscher, wissenschaftliche Institutionen und Fachzeitschriften verschreiben sich den OpenScience-Prinzipien (z. B. Schönbrodt et al., 2017). Zu Open Science gehört unter anderem, dass man Daten und Auswertungsskripte zur Verfügung stellt, damit andere die veröffentlichten Ergebnisse reproduzieren können. Damit wirklich alle Menschen, egal woher sie kommen oder wie viel Geld sie haben, diese Dateien nutzen können, müssen diese in nicht-proprietärer Software erstellt worden sein – also in einer Software, die nicht kommerziell vetrieben wird. Ehemals beliebte kommerzielle Statistik-Programme wie SPSS oder Stata erfüllen dieses Kriterium nicht. R schon. Es gibt also eine Menge Gründe, R zu lernen. Allerdings ist R nicht die intuitivste Software. Das Ziel dieses Buchs ist es, Ihnen den Einstieg in R zu erleichtern. Sie werden sehen: Wenn Sie die ersten Kapitel gemeistert haben, wird es sehr viel einfacher. Ich wünsche Ihnen beim Einstieg in R viel Erfolg und hoffentlich auch etwas Spaß!
13
14
1 Einleitung
1.1
Warum R?
Es gibt viele Gründe, die für R sprechen. Hier sind die wichtigsten: R kann mehr. Die Software enthält viele Funktionen, die man bei kommerziellen Statistik-Programmen vergeblich sucht. R ist aktuell. Das Programm wird ständig weiterentwickelt, sodass viele neue statistische Methoden zuerst in R und erst Jahre später in anderen Programmen implementiert sind. R ist ansprechbar. Die Programmierer der einzelnen Pakete sind über E-Mail erreichbar und reagieren meiner Erfahrung nach innerhalb weniger Tage. So können Fragen schnell geklärt und eventuelle Programmierfehler behoben werden. R schläft nicht. R-Nutzer gibt es auf der ganzen Welt, und viele von ihnen sind in den einschlägigen Foren und in den sozialen Medien aktiv. So kann man seine Fragen rund um die Uhr klären. R ist nachgefragt. Wenn Sie R-Kenntnisse nachweisen können, stehen Ihnen viele Jobmöglichkeiten offen – in und außerhalb der Wissenschaft. R ist kostenlos!
1.2
Für wen ist dieses Buch?
Dieses Buch richtet sich sowohl an Einsteiger, die zum ersten Mal mit einer StatistikSoftware arbeiten, als auch an Umsteiger, die R als eine Alternative zu anderen Statistik-Programmen ausprobieren möchten. Besondere Computer- oder gar Programmierkenntnisse brauchen Sie nicht. Da dieses Buch aber keine Statistik-Einführung ist, sollten Sie die Grundlagen der hier behandelten statistischen Tests kennen. Dafür empfehle ich das Lehrbuch von Eid et al. (2017), an dem auch die Gliederung dieses Buchs orientiert ist. Ich bin selbst Psychologin und habe daher Datenbeispiele aus psychologischen Studien gewählt. Darüber hinaus behandle ich einige Funktionen und statistische Verfahren, die besonders für Psychologinnen und Psychologen von Interesse sind, z. B. die Berechnung von Skalenwerten (Kap. 7) oder Verfahren für die Testkonstruktion wie Itemanalysen und Faktorenanalysen (Kap. 18). Grundsätzlich richtet sich das Buch jedoch an Interessierte aus allen Fachrichtungen der Sozialwissenschaften. In einem Einführungsbuch ist natürlich kein Platz, alle speziellen statistischen Verfahren detailliert zu besprechen. Sie werden jedoch bald in der Lage sein, sich in die Funktionen und Pakete, die Sie für solche Verfahren brauchen, selbst einzuarbeiten. Weitere Hinweise dazu finden Sie im Anhang B: Pakete.
1.4
1.3
Weiterentwicklungen und Aktualität des Buchs
Wie benutzt man dieses Buch?
Den Umgang mit einer Statistik-Software lernt man am besten durch Ausprobieren. Daher empfehle ich, bei der Lektüre dieses Buchs immer einen Computer mit R dabeizuhaben. So können Sie die beschriebenen Funktionen direkt ausprobieren. Die Datensätze dafür können Sie von der Webseite zu diesem Buch herunterladen: http://www.beltz.de/r-fuer-einsteiger. Dort finden Sie auch die Skripte für jedes Kapitel, die oftmals noch weitere Beispiele enthalten, sowie zahlreiche Zusatzmaterialien. Hinweise für Einsteiger Ich habe mich bemüht, dieses Buch so zu schreiben, dass auch Einsteiger ohne jegliche Erfahrung mit Statistik-Software mit R zurechtkommen können. In diesem Buch stelle ich die statistischen Verfahren in der Reihenfolge vor, in der sie typischerweise gelehrt werden. Wenn Sie dieses Buch also in Begleitung zu einer Statistik-Vorlesung in Psychologie oder anderen sozialwissenschaftlichen Fächern lesen, können Sie die Kapitel einfach von vorne nach hinten durcharbeiten. Hinweise für Umsteiger Als Umsteiger haben Sie bereits Erfahrung mit anderen Statistik-Programmen und interessieren sich möglicherweise nur für bestimmte Funktionen in R. In diesem Fall brauchen Sie natürlich nicht das Buch von vorne bis hinten durchzuarbeiten, sondern können sich auf die Funktionen konzentrieren, die Sie benötigen. Beginnen Sie aber auf jeden Fall mit den Kapiteln 2 bis 5, in denen die Grundlagen von R vermittelt werden.
1.4
Weiterentwicklungen und Aktualität des Buchs
R wird ständig weiterentwickelt. Sowohl die Basisversion als auch die zusätzlichen Pakete werden regelmäßig aktualisiert, und fast wöchentlich werden neue Pakete zur Verfügung gestellt. Wenn Sie regelmäßig mit R arbeiten, werden Sie vermutlich immer wieder neue Pakete entdecken, die Ihnen die statistischen Analysen noch leichter machen. Für die Erstellung dieses Buchs habe ich mich bemüht, immer die aktuellsten Versionen zu verwenden (Stand April 2020). Dieses Buch verwendet die R Version 3.6.2. Die hier vorgestellten Funktionen und Pakete sollten jedoch auch mit neueren Versionen funktionieren. Wenn Sie trotzdem veraltete Funktionen oder gar Fehler finden, lassen Sie mich dies bitte wissen. Aktualisierungen und Fehlerkorrekturen werden regelmäßig unter http://www.beltz.de/r-fuer-einsteiger und unter
15
16
1 Einleitung
dem Twitter-Account @RfuerEinsteiger veröffentlicht. Und noch ein Tipp: Die aktuellsten Hinweise zu den Funktionen und den entsprechenden Argumenten finden Sie in der dazugehörigen Hilfe-Datei (s. Abschn. 4.3.3).
1.5
Verwendete Schriftarten
Um die Übersichtlichkeit des Texts zu erhöhen, werden in diesem Buch verschiedene Schriftarten verwendet (s. Tab. 1.1). Tabelle 1.1 Verwendung von Schriftarten im Buch
Powered by TCPDF (www.tcpdf.org)
Text
Beispiel
Menübefehle
DATEI → SPEICHERN
Namen von Paketen
psych-Paket
Namen von Funktionen
mean-Funktion
Befehle und Ausgaben
> c(1, 2, 3)
2.1
2
Download und Installation von R
Installation
Um gut mit R arbeiten zu können, installieren wir zwei Programme: R (R Core Team, 2019b) und RStudio (RStudio Team, 2019). R ist die eigentliche Software, die zwar schon alles kann, was uns interessiert, aber leider optisch wenig ansprechend ist. Daher verwenden wir zusätzlich die Benutzeroberfläche RStudio. Wir installieren zunächst R und anschließend RStudio. Beide Programme sind kostenlos.
2.1
Download und Installation von R
Die Internetseite http://cran.r-project.org ist der Ausgangspunkt für die Arbeit mit R. Die Abkürzung CRAN steht für Comprehensive R Archive Network. Hier werden sowohl die Software als auch verschiedene Pakete (s. Abschn. 3.2) und Dokumente zur Verfügung gestellt. Direkt auf der Startseite befindet sich die Option Download and Install R. Hier kann man R für die Betriebssysteme Linux, MacOS X und Windows herunterladen. Windows Zum Download der Windows-Version gelangt man über den Link Download R for Windows. Auf der neuen Seite wählen wir den Link base. Auf der folgenden Seite klicken wir auf den Link Download R X.X.X for Windows. Damit laden wir die Setup-Datei herunter. (Das X steht für die aktuelle Versionsnummer. Auf der CRANSeite wird immer nur die neueste R-Version angeboten.) Wir starten die Installation von R, indem wir die heruntergeladene Set-up-Datei öffnen. Als erstes müssen wir die Sprache für das Set-up auswählen. Danach öffnet sich der Set-up-Assistent. Folgende Schritte werden bei der Installation durchlaufen: (1) Der Lizenztext wird angezeigt und sollte durchgelesen werden. (2) ZIELORDNER AUSWÄHLEN. Wir wählen den Ordner, in dem das Programm installiert wird. Standardmäßig wird der Ordner C:\Programme\R\R-X.X.X vorgeschlagen. (3) KOMPONENTEN AUSWÄHLEN. Hier wählen wir die Dateien aus, die installiert werden sollen. Für die meisten Leser wird die Option BENUTZERINSTALLATION geeignet sein. Dabei werden alle Dateien installiert. (4) STARTOPTIONEN ANPASSEN. Wählen wir die Option JA , können wir im Folgenden bestimmte Einstellungen von R bei der Installation festlegen. Dazu zählen der
17
18
2 Installation
Anzeigemodus (Darstellung der einzelnen Fenster), der Hilfestil (Hilfe-Dateien als PDF oder im Windows-Format) sowie der Internetzugang. Wählen wir NEIN , werden die einzelnen Schritte übersprungen und die Standardeinstellungen für R übernommen. Wir wählen die letztere Option. (5) STARTMENÜORDNER AUSWÄHLEN . Hier kann man entscheiden, ob ein Ordner im Startmenü erstellt werden soll und den Namen im Startmenü ändern. (6) ZUSÄTZLICHE AUFGABEN AUSWÄHLEN . Wir entscheiden nun, ob zusätzliche Symbole auf dem Desktop oder in der Schnellstartleiste angelegt werden sollen. Außerdem legen wir hier die Art der Verknüpfung von R mit Windows fest (Speicherung der Versionsnummer, R mit .RData-Dateien verknüpfen). Für die meisten Leser sind die Standardeinstellungen ausreichend. (7) Fertig! MacOS Zum Download der Mac-Version gelangt man über den Link Download R for MacOS X. Wir gelangen nun auf die Seite R for MacOS X, wo wir die Datei R-X.X.X.pkg auswählen und herunterladen. Wenn wir diese Datei öffnen, startet der Set-up-Assistent. Dieser Assistent führt uns Schritt für Schritt durch die Installation. Bei der Installation werden die folgenden Schritte durchlaufen: (1) Wichtige Informationen lesen und zustimmen. (2) Software-Lizenzvereinbarungen lesen und akzeptieren. (3) Zielvolume wählen: Soll die Software für alle Benutzer oder nur auf einem bestimmten Laufwerk installiert werden? (4) Installationstyp: Hier kann der Ort der Installation verändert werden. (5) Durchführung der Installation. (6) Fertig! An dieser Stelle noch ein allgemeiner Hinweis: Dieses Lehrbuch wurde mit Windows erstellt. Die Benutzeroberfläche sieht auf dem Mac manchmal etwas anders aus. Grundsätzlich lassen sich aber alle Funktionen an denselben Stellen wiederfinden. Alle Pakete lassen sich auch auf MacOS verwenden.
2.2
Download und Installation von RStudio
Nachdem die Installation von R erfolgreich abgeschlossen ist, laden wir die Benutzeroberfläche RStudio von der Seite http://www.rstudio.com/ide/ herunter und installieren sie. Nach der Installation steht RStudio als eigenes Programm zur Verfügung. R muss zwar installiert sein, aber nicht gestartet werden, um RStudio zu nutzen. Ab jetzt arbeiten wir immer direkt in RStudio!
Powered by TCPDF (www.tcpdf.org)
3.1
3
RStudio im Überblick
Ein erster Überblick
Wenn wir R und RStudio erfolgreich installiert haben, können wir loslegen. Wir öffnen immer direkt RStudio. R muss und sollte nicht zusätzlich gestartet werden, sondern läuft automatisch im Hintergrund mit. In diesem Kapitel verschaffen wir uns einen ersten Überblick über das Programm (Abschn. 3.1) und besprechen, wie man zusätzliche Pakete installieren und laden kann (Abschn. 3.2). Wenn man mal nicht weiter weiß, kann man sich an verschiedenen Stellen Hilfe zu R holen (Abschn. 3.3).
3.1
RStudio im Überblick
Die Benutzeroberfläche von RStudio setzt sich üblicherweise aus vier nebeneinander angeordneten Fenstern zusammen (Abb. 3.1): das Skript-Fenster oben links, die Konsole unten links, das Environment-Fenster oben rechts, und ein Fenster mit einer ganzen Reihe von Reitern unten rechts. Bei der ersten Nutzung von RStudio wird das Skript-Fenster nicht immer sofort angezeigt. Wie man es öffnet, wird in Abschn. 3.1.2 beschrieben. In den folgenden Abschnitten gehen wir die Fenster einzeln durch.
Abbildung 3.1 RStudio
19
20
3 Ein erster Überblick
3.1.1
Die Konsole
Die Konsole bietet eigentlich alles, was wir für die Arbeit mit R brauchen. Hier können wir sowohl Befehle eingeben als auch Ausgaben betrachten. Wenn wir RStudio öffnen, steht in der Konsole ein kurzer Begrüßungstext (s. Abb. 3.1), der u. a. angibt, welche R Version gerade geladen ist (hier: Version 3.6.2, veröffentlicht am 12.12.2019 unter dem Spitznamen »Dark and Stormy Night«). Unter dem Begrüßungstext erscheint das folgende Symbol: >
Bei diesem Symbol handelt es sich um ein Eingabesymbol, d. h., dahinter können wir einen Befehl eingeben. In der R-Sprache wird dieses Symbol als »Prompt« (deutsch: Eingabeaufforderung) bezeichnet. Um einen Befehl in der Konsole auszuführen, drücken wir die Enter-Taste. Die Ausgabe erscheint dann direkt unter dem Befehl in einer anderen Farbe. Wenn alles gut gegangen ist, erwartet uns darunter schon wieder das nächste Eingabesymbol. Wir probieren das mal mit dem folgenden Befehl aus: > 1+2 [1] 3 >
In diesem Beispiel haben wir eine kleine Rechenaufgabe lösen lassen. R kann man nämlich auch als Taschenrechner verwenden (mehr dazu in Abschn. 4.1). Das Ergebnis erscheint in der Zeile unter dem Befehl. Diesen Teil bezeichnet man auch als Ausgabe oder Output. Die Ausgabe beginnt mit [1]. Das eigentliche Ergebnis steht dahinter. Das Zeichen [1] hat nichts mit dem Ergebnis der Rechenaufgabe zu tun, sondern wird verwendet, um bei langen Ausgaben, die über mehrere Zeilen gehen, die Elemente zu nummerieren. Das klingt jetzt noch sehr abstrakt, wird aber klarer, wenn wir später Beispiele für solche Ausgaben betrachten (s. Abschn. 5.4). Unter der Ausgabe erscheint erneut das Eingabesymbol. Das ist ein gutes Zeichen, denn es bedeutet, dass der Befehl vollständig ausgeführt wurde und die Konsole jetzt bereit für den nächsten Befehl ist. Wurde der Befehl dagegen nicht vollständig ausgeführt (z. B. weil eine Klammer nicht geschlossen wurde), fügt die Konsole automatisch eine zweite Zeile ein, die mit einem + beginnt. Das + zeigt an, dass diese Zeile mit der vorhergehenden Zeile verknüpft ist. Im Folgenden sind zwei Befehle dargestellt. Der erste Befehl geht über eine Zeile, daher folgt die Ausgabe direkt in der zweiten Zeile. In den zweiten Befehl wurde dagegen ein Zeilenumbruch eingefügt, sodass dieser Befehl über zwei Zeilen geht. Das
3.1
RStudio im Überblick
+ am Anfang der zweiten Zeile ist hier kein mathematisches Symbol, sondern es ver-
knüpft lediglich die beiden Befehlszeilen miteinander. Die Ausgabe folgt in der dritten Zeile: > (3+7+2)/3 [1] 4 > (3+7+2)/ + 3 [1] 4
Tipp
Bevor man einen neuen Befehl ausführt, sollte man immer sicherstellen, dass die unterste Zeile in der Konsole mit > beginnt. Beginnt sie stattdessen mit + , so ist dies ein Zeichen, dass der vorangegangene Befehl unvollständig eingegeben und daher noch nicht beendet wurde. Das passiert z. B., wenn man vergisst, Klammern oder Anführungszeichen zu schließen. Diese und weitere typische Fehlerquellen werden in Kapitel 24 behandelt.
Konsole aufräumen Nach einer längeren R-Sitzung ist die Konsole meistens ziemlich voll und unübersichtlich. Wenn uns das stört, können wir die Konsole mit der Tastenkombination STRG + L (Windows) bzw. CMD + L (Mac) aufräumen. Damit werden alle Inhalte der Konsole gelöscht. Inhalt der Konsole speichern Die Konsole enthält alle Befehle und Ausgaben, die in einer Sitzung angefordert wurden. Und damit ist wirklich alles gemeint – also auch alle Befehle mit Tippfehlern, mehrfach ausgeführte Befehle und Fehlermeldungen. Daher wird der Inhalt der Konsole üblicherweise nicht gespeichert. Stattdessen kann man bestimmte Ausgaben (z. B. Tabellen oder Diagramme) gezielt in externe Dateien zu exportieren oder eine sog. R Markdown-Datei anlegen (s. Kap. 22). Wenn man trotzdem den Inhalt der Konsole speichern möchte, kann man diesen markieren, kopieren und in ein einfaches Textdokument einfügen.
21
22
3 Ein erster Überblick
3.1.2
Das Skript-Fenster
Zwar könnte man theoretisch alle Befehle direkt in die Konsole eingeben, wie im vorherigen Abschnitt gezeigt, aber wir lassen das lieber bleiben. Der Nachteil an der Konsole ist nämlich, dass die Befehle immer wieder neu eingegeben werden müssen und nicht gut gespeichert werden können. Deshalb geben wir Befehle ab jetzt immer in das Skript-Fenster ein. Falls dieses Fenster noch nicht zu sehen ist, können wir es über FILE → NEW FILE → R SCRIPT öffnen. Befehle im Skript-Fenster eingeben und ausführen Im Skript-Fenster erscheint kein Eingabesymbol, sondern der Befehl wird direkt eingegeben. Ein Befehl kann über eine oder mehrere Zeilen gehen. Bei langen Befehlen mit vielen Argumenten (s. Abschn. 4.3) ist es übersichtlicher, wenn man den Befehl durch Zeilenumbrüche auf verschiedene Zeilen aufteilt. Dazu setzen wir den Cursor an die Stelle, wo der Zeilenumbruch eingefügt werden soll, und drücken die ENTER Taste. RStudio rückt alle folgenden Zeilen etwas ein, sodass man schnell erkennen kann, wo ein Befehl anfängt und aufhört. So wird die Rechenaufgabe aus dem vorherigen Abschnitt im Skript-Fenster dargestellt, wenn wieder ein Zeilenumbruch eingefügt wird: (3+7+2) / 3
Wie führt man nun diesen Befehl aus? Anders als in der Konsole reicht hier die ENTER -Taste nicht aus, denn damit würde nur ein Zeilenumbruch eingefügt werden. Wir können stattdessen auf ein Symbol klicken oder eine spezielle Tastenkombination verwenden. Zunächst müssen wir aber festlegen, welche Befehle genau ausgeführt werden sollen. Dazu gibt es mehrere Möglichkeiten: (1) Wir setzen den Cursor irgendwo in den Befehl, der ausgeführt werden soll. Es wird dann genau dieser Befehl von Anfang bis Ende ausgeführt. (2) Wir markieren den Befehl mit der Maus. Dann wird alles ausgeführt, was markiert ist. Wir können damit mehrere Befehle gleichzeitig ausführen. Aber Vorsicht: Hier wird wirklich nur der markierte Teil ausgeführt – haben wir z. B. vergessen, eine Klammer mitzumarkieren, dann wird der Befehl unvollständig ausgeführt. Diese Eigenschaft klingt zunächst etwas unpraktisch, hat aber einen wichtigen Vorteil: Wir können dadurch gezielt Teile von Befehlen ausführen, was besonders nützlich ist, wenn wir es später mit langen, geschachtelten Befehlen zu tun haben. Zudem kann man diese Eigenschaft für die Fehlersuche nutzen (s. Kap. 24).
3.1
RStudio im Überblick
Um den Befehl auszuführen, klicken wir entweder auf das Symbol RUN auf der rechten Seite der oberen Leiste des Skript-Fensters oder verwenden die Tastenkombination STRG + ENTER (Windows) bzw. CMD + ENTER (Mac). Dadurch erscheint die Ausgabe zusammen mit dem Befehl in der Konsole. Der Text im Skript-Fenster bleibt unverändert. Diese Trennung zwischen Eingaben und Ausgaben hat u. a. den Vorteil, dass man alte Befehle jederzeit wieder aufrufen und erneut ausführen kann, sogar mit anderen Datensätzen. Darstellung von Befehlen in RStudio Eben haben wir schon gesehen, dass RStudio nachfolgende Zeilen bei mehrzeiligen Befehlen einrückt. Auch bei anderen Dingen ist RStudio sehr bemüht, die Befehle so übersichtlich wie möglich darzustellen. Ein Beispiel dafür ist die Verwendung von verschiedenen Farben. So werden Funktionen (mehr dazu in Abschn. 4.3), Texteingaben (also alles, was von Anführungszeichen umgeben ist) und sonstige Bestandteile von Befehlen in unterschiedlichen Farben dargestellt. Welche das sind, kann man selbst beeinflussen: Unter TOOLS → GLOBAL OPTIONS → APPEARANCE kann man u. a. die farbliche Darstellung der Befehle und die Hintergrundfarbe verändern. Darstellung von Befehlen in diesem Buch In diesem Lehrbuch stellen wir Befehle immer so dar, wie sie in der Konsole erscheinen. Das heißt, die Befehle beginnen immer mit dem Eingabesymbol, um sie besser von Ausgaben zu unterscheiden. Wenn man diese Befehle im Skript-Fenster eingibt, muss das Eingabesymbol weggelassen werden (s. Tab. 3.1). Tabelle 3.1 Darstellung von Befehlen im Lehrbuch und Eingabe dieser Befehle im SkriptFenster
Darstellung im Lehrbuch
Eingabe im Skript-Fenster
> 3+4
3+4
> mean(x)
mean(x)
> vektor install.packages("psych", dependencies = TRUE) Installing package into ‘C:/Users/…/R/win-library/3.6’ (as ‘lib’ is unspecified) also installing the dependencies ‘abind’, ‘coda’, ‘arm’, ‘pbivnorm’, ‘numDeriv’, ‘matrixcalc’, ‘mi’, ‘minqa’, ‘nloptr’, ‘Rcpp’, ‘RcppEigen’, ‘psychTools’, ‘GPArotation’, ‘lavaan’, ‘sem’, ‘lme4’, ‘Rcsdp’ trying URL 'https://cran.rstudio.com/bin/windows/ contrib/3.6/psych_1.9.12.31.zip' Content type 'application/zip' length 3802421 bytes (3.6 MB) downloaded 3.6 MB package ‘psych’ successfully unpacked and MD5 sums checked The downloaded binary packages are in C:\Users\...\downloaded_packages
3.2
Zusätzliche Pakete
Hier wurde also nicht nur das psych-Paket, sondern auch diverse andere Pakete installiert, von denen das psych-Paket abhängt. Woran erkenne ich, ob die Installation geklappt hat? Achten Sie auf die Meldung package ‘psych’ successfully unpacked and MD5 sums checked. Wenn die kommt, ist alles gut. Funktion Pakete können auch über die folgende Funktion installiert werden: > install.packages("Name.des.Pakets", dependencies = TRUE)
Das Argument dependencies bezieht sich wiederum darauf, ob auch andere Pakete installiert werden sollen. Steht dahinter TRUE, werden alle Pakete, von denen unser Paket abhängt, direkt mitinstalliert. Der entsprechende Befehl für die Installation des psych-Pakets lautet: > install.packages("psych", dependencies = TRUE)
Tipp
R unterscheidet zwischen Groß- und Kleinschreibung. Folgende Pakete gibt es nicht: PSYCH, Psych, psYch usw.
3.2.2
Pakete laden
Die zusätzlich installierten Pakete werden beim Öffnen von Rstudio nicht automatisch geladen. Das heißt, wir müssen ein Paket jedes Mal laden, wenn wir es in einer neuen Sitzung verwenden möchten. Es ist allerdings nicht notwendig, das Paket jedes Mal neu zu installieren. Woher wissen wir, ob ein Paket bereits installiert ist? In RStudio können wir im Fenster unten rechts unter dem Reiter PACKAGES eine Liste aller bereits installierten Pakete einsehen. Diese Liste erhalten wir auch mit dem folgenden Befehl: > library()
Auch das Laden von Paketen kann wieder über das Menü oder über einen Befehl erfolgen. Wenn wir bald richtig mit R arbeiten, werden wir immer den Befehl nutzen (s. Kap. 23). Für den Einstieg schauen wir uns aber auch an, wie es über das Menü funktioniert.
29
30
3 Ein erster Überblick
Menübefehl Wir öffnen wieder im Fenster unten rechts den Reiter PACKAGES. Wir können nun das Paket aus der Liste suchen und mit einem Häckchen versehen – schon wird es geladen. Dieser Weg wird allerdings etwas umständlich, wenn wir sehr viele Pakete installiert haben. Daher verwenden wir ab jetzt lieber die Funktion. Funktion Pakete laden wir mit der folgenden Funktion: > library(Name.des.Pakets)
Warum heißt diese Funktion so? Pakete werden bei der Installation in der sog. Library gespeichert. Wir können uns die Library als Bücherregal vorstellen, in dem die Pakete gelagert werden. Tatsächlich handelt es sich dabei um einen Ordner auf Ihrem Rechner, mit Unterordnern für jedes Paket. Wichtig: Rühren Sie diesen Ordner auf keinen Fall an! Die Installation von Paketen sollte immer über RStudio erfolgen. Wenn wir nun ein Paket verwenden möchten, müssen wir es aus dem Bücherregal herausholen. Daher heißt die Funktion dazu library. Zur Veranschaulichung laden wir nun das Paket psych: > library(psych)
Normalerweise wird das Paket ohne Probleme geladen, was man daran erkennen kann, dass nur der Befehl, jedoch keine zusätzlichen Meldungen in der Konsole erscheinen. Unter Umständen gibt es jedoch zusätzliche Meldungen. Eine häufige Meldung ist die folgende: Warning message: Paket ‘psych’ wurde unter R Version 3.6.3 erstellt
Eine solche Meldung erscheint, wenn wir eine ältere R-Version verwenden. In diesem Beispiel wurde das Paket in R 3.6.2 geladen. Das Paket selbst wurde jedoch für die Version R 3.6.3 optimiert. In den meisten Fällen stellt dies kein Problem dar, da sich die Pakete von einer Version zur nächsten meistens nur wenig ändern. Um möglichen Kompatibilitätsproblemen vorzubeugen, empfiehlt es sich jedoch, stets die aktuellste R-Version installiert zu haben.
3.3
Hilfe zu R
Wir werden im Laufe des Buchs eine Reihe von Paketen kennenlernen. Die Pakete werden jeweils dann installiert und geladen, wenn sie gebraucht werden. Mit dem folgenden Befehl erhalten wir eine Liste aller bereits geladenen Pakete: > search()
Tipp
Manche Pakete funktionieren auf Mac nur, wenn bestimmte zusätzliche Dateien installiert sind. Dabei handelt es sich zum einen um XQuartz, eine Erweiterung des Mac Betriebsystems. XQuartz kann unter http://xquartz.macosforge.org heruntergeladen werden. Zum anderen sollte die Tcl/Tk-Erweiterung installiert sein. Die Tcl/Tk-Erweiterung steht unter https://cran.r-project.org/bin/macosx/ zum Download zur Verfügung. Möglicherweise erhalten Sie bei der Installation die Fehlermeldung, dass diese App von nicht verifizierten Entwicklern stammt. Klicken Sie in diesem Fall auf das Fragezeichen und folgen Sie den Anweisungen in der Hilfe zu dieser Fehlermeldung.
3.2.3
Pakete aktualisieren
Viele Pakete werden immer weiter verbessert und erweitert. Es ist daher sinnvoll, die bereits installierten Pakete von Zeit zu Zeit zu aktualisieren. Dazu wählt man in RStudio das Menü TOOLS → CHECK FOR PACKAGE UPDATES. Man erhält dann eine Übersicht, welche Versionen der Pakete man installiert hat und welche verfügbar sind. Unterscheiden sich die Versionsnummern, kann man das Paket anklicken und anschließend mit INSTALL UPDATES die Aktualisierung starten. Mit dem folgenden Befehl werden alle installierten Pakete auf einmal aktualisiert: > update.packages(ask = FALSE)
3.3
Hilfe zu R
R entwickelt sich rasant, und mittlerweile gibt es wohl niemanden mehr, der alle Pakete und Funktionen kennt. Ein wichtiges Ziel beim Einstieg in R ist deshalb, dass man lernt, sich neue Pakete und Funktionen selbständig anzueignen. Selbständig heißt aber nicht mutterseelenallein. Es gibt unzählige Stellen, wo man Hilfe finden kann: in RStudio selbst, in einschlägigen Fachbüchern und vor allem im Internet.
31
32
3 Ein erster Überblick
3.3.1
Hilfe in RStudio
Die erste Anlaufstation für Hilfe in RStudio ist das Menü HELP → R HELP. Damit öffnet sich im Fenster unten rechts eine Hilfe-Seite mit vielen nützlichen Links zu Ressourcen und Materialien zu R und RStudio (s. Abb. 3.5). Viele dieser Links führen zu Internetseiten und können daher nur verwendet werden, wenn eine Internetverbindung besteht. Die im Abschnitt MANUALS verlinkten Handbücher können aber auch offline abgerufen werden.
Abbildung 3.5 Hilfe-Seite in RStudio, zu erreichen über HELP → R HELP
3.3.2
Hilfe zu bestimmten Paketen und Funktionen
Alle Pakete enthalten Hilfe-Dateien, die direkt mitinstalliert werden. Um nähere Informationen zu einem bestimmten Paket zu bekommen, muss das Paket zunächst geladen werden: > library(NameDesPakets)
Mit der help-Funktion kann man die Hilfe-Dateien aufrufen. Hilfe zum gesamten Paket erhält man, indem man den Namen des Pakets eingibt: > help(NameDesPakets)
3.3
Hilfe zu R
Alternativ kann man auch einfach ein Fragezeichen vor den Namen des Pakets setzen: > ?NameDesPakets
Hilfe zu bestimmten Funktionen erhält man, indem man den Namen der Funktion in den Befehl eingibt (s. auch Abschn. 4.3.3): > help(NameDerFunktion) oder ?NameDerFunktion
Mit der help.search-Funktion erhält man eine Liste aller Pakete, die den gesuchten Begriff in einer Funktion enthalten: > help.search("Suchbegriff") > ??Suchbegriff
3.3.3
Hilfe im Internet
Das Internet bietet eine Unmenge an Informationen zu R. Wir gehen hier die wichtigsten Ressourcen durch. Homepages von R und RStudio Sowohl auf der offiziellen R-Homepage (http://www.r-project.org) als auch auf der Support-Webseite von RStudio (https://support.rstudio.com) findet man viele nützliche Ressourcen, z. B. Handbücher zu R. Informationen zu den einzelnen Paketen findet man unter http://cran.r-project.org/web/packages. Hier ist jedes Paket mit einer eigenen Seite verlinkt, von der man auch das Manual des jeweiligen Pakets als pdf-Dokument herunterladen kann. Einführende Webseiten Die Webseite Quick-R (http://www.statmethods.net) fasst die am häufigsten benötigten Funktionen kurz und prägnant zusammen. Für blutige Anfänger sind die Funktionen manchmal etwas zu knapp kommentiert, aber sobald man die grundlegende Logik von R verstanden hat, kann man hier sehr gut und schnell einzelne Funktionen nachschlagen. Die Homepage des Persönlichkeitspsychologen William Revelle (http://www.personality-project.org/R/R.guide.html) gibt eine Einführung in R und geht besonders auf statistische Methoden ein, die in der psychologischen Forschung häufig zum Einsatz kommen, z. B. die Faktorenanalyse. Revelle ist auch der Autor des psych-Pakets, das wir noch viel verwenden werden. Eine hilfreiche
33
34
3 Ein erster Überblick
deutschsprachige Seite ist R-Lernplattform des Lehrstuhls für Psychologische Methodenlehre an der Humbold-Universität Berlin: http://methods-berlin.com/de/r-lernplattform/. Hier findet man anschauliche Kurzanleitungen, Übungsaufgaben und FAQs zu R. Suchmaschinen Natürlich lassen sich alle Funktionen auch über reguläre Suchmaschinen wie Ecosia oder Google finden. Der Name der Software erschwert die Suche jedoch ungemein. Unter dem Stichwort »R« findet man nicht nur Statistik-Seiten. Daher sollte man lieber eine auf R spezialisierte Suchmaschine verwenden. Gut bewährt hat sich die Suchmaschine R-Seek (http://www.rseek.org). Der Vorteil dieser Suchmaschine ist, dass die Ergebnisse nach verschiedenen Kategorien sortiert werden können. Sucht man z. B. eine Funktion für eine bestimmte Art von Analyse, so kann man unter dem Stichwort Function nachschauen. Auch Blogs, Forumsdiskussionen und Wikis sind hier verlinkt. Die Suchmaschine greift auch auf die Seite https://www.rdocumentation.org zu, auf der man Dokumentationen für alle Pakete findet. Internetforen und soziale Medien Bei spezifischen Fragen oder Problemen findet man häufig in Internetforen eine Antwort. Die populärsten Foren für R sind derzeit stackoverflow (https://stackoverflow.com) und das RStudio-Forum (https://community.rstudio.com). Beide Foren werden auch von der Suchmaschine R-Seek abgesucht. Bei der Nutzung von Foren gehört es zur Etikette, dass man immer erstmal prüft, ob jemand anderes schon etwas zu dieser Frage gepostet hat. Ist das nicht der Fall, kann man selbst einen Eintrag erstellen. Dabei sollte man die Frage oder das Problem so präzise wie möglich beschreiben. Wenn man z. B. aus einer Fehlermeldung nicht schlau wird, sollte man nicht nur den Text dieser Fehlermeldung posten, sondern den gesamten R-Befehl – am besten in einer Form, dass andere ihn direkt kopieren und ausführen können, auch wenn sie keinen Zugriff auf die Daten haben. Auch in den sozialen Medien kann man viel über R lernen. Auf Twitter gibt es diverse Accounts, die regelmäßig zu R twittern, z. B. @rstudiotips, @inside_R, @hadleywickham oder @RLangTip. Anlässlich der 5. Auflage dieses Buchs gibt es neuerdings auch den Account @RfuerEinsteiger, auf dem regelmäßig Updates und Tipps zu R gepostet werden. Tweets zu R findet man außerdem unter dem Hashtag #rstats. Auf Facebook gibt es viele öffentliche Gruppen, z. B. R Users Psychology (https://www.facebook.com/groups/346735129027556/). Cheatsheets bzw. Reference Cards Cheatsheets (auch als Reference Cards bekannt) sind übersichtliche Zusammenstellungen der wichtigsten R-Funktionen, die man ausdrucken und sich als eine Art
3.4
Die wichtigsten Funktionen im Überblick
Spickzettel neben den Computer legen kann. Viele Spickzettel sind direkt von RStudio aus zu finden unter HELP → CHEATSHEETS. Eine noch größere Sammlung findet man auf der Webseite von RStudio unter https://rstudio.com/resources/cheatsheets/. Auch für dieses Buch gibt es eine solche Reference Card; sie kann auf der begleitenden Webseite http://www.beltz.de/r-fuer-einsteiger heruntergeladen werden.
3.3.4 Bücher Es gibt mittlerweile sehr viele gute Bücher zu R. Besonders empfehlen möchte ich die folgenden. Das Buch »Moderne Datenanalyse mit R« von Sauer (2019) gibt einen unterhaltsamen Einstieg in R. Der Fokus liegt dabei auf modernen R-Funktionen wie die aus den tidyverse-Paketen (s. Kap. 7) sowie auf speziellen Analyseverfahren, die weit über die im typischen Studium gelehrten Verfahren hinausgehen, z. B. prädiktive Modellierung oder Textmining. Das Buch »R for Data Science« von Wickham und Grolemund (2017) ist eines der am meisten empfohlenen englischsprachigen Bücher zu R. Inhaltlich hat es einen ähnlichen Schwerpunkt wie das Buch von Sauer (2019). Für die Erstellung von Diagrammen gibt das »R Graphics Cookbook« von Chang (2013) einen guten Überblick. Darüber hinaus wird R auch zunehmend in Statistik-Lehrbüchern verwendet (z. B. Field et al., 2012).
3.4
Powered by TCPDF (www.tcpdf.org)
Die wichtigsten Funktionen im Überblick
Funktion
Beschreibung
install.packages()
Lädt ein Paket herunter und installiert es.
library()
Lädt ein Paket in R. Dieser Vorgang muss in jeder Sitzung neu durchgeführt werden. Wird kein Paketname in der Funktion angegeben, wird eine Liste mit allen installierten Paketen angezeigt.
search()
Zeigt eine Liste mit allen aktuell geladenen Paketen an.
update.packages()
Aktualisiert alle installierten Pakete.
help() bzw. ?
Öffnet die Hilfe-Datei für das angegebene Paket bzw. die angegebene Funktion.
help.search() bzw. ??
Nennt alle Funktionen, in denen der eingegebene Suchbegriff verwendet wird.
35
36
4 Einführung in die Programmiersprache
4
Einführung in die Programmiersprache
Das Erlernen von R hat gewisse Parallelen zum Erlernen einer Fremdsprache. Wir müssen uns mit einer fremden Grammatik vertraut machen und neue Vokabeln lernen. Darüber hinaus gibt es bestimmte Stilregeln und Konventionen, die wir uns aneignen müssen. Und es gilt: Nur durch regelmäßiges Üben werden wir besser und vergessen weniger. Einen wichtigen Unterschied gibt es jedoch auch: Anders als bei einer gesprochenen Sprache erwartet niemand von uns, dass wir die Programmiersprache fließend sprechen und alle Vokabeln im Kopf haben. In diesem Kapitel beschäftigen wir uns mit der grundlegenden Grammatik von R und lernen ein paar erste Vokabeln und Stilregeln kennen. Wir behandeln R als Taschenrechner (Abschn. 4.1), geben logische Abfragen ein (Abschn. 4.2), lernen erste Funktionen kennen (Abschn. 4.3), kommentieren unser bisheriges Werk (Abschn. 4.4) und besprechen einige Konventionen, mit denen wir unsere Skripte übersichtlich gestalten können (Abschn. 4.5).
4.1
R als Taschenrechner
In R kann man nicht nur komplexe Datensätze analysieren, sondern auch ganz einfache Berechnungen durchführen. R ersetzt also nicht nur gängige Statistik-Programme, sondern auch den simplen Taschenrechner (hoffentlich aber nicht den Kopf). Tabelle 4.1 enthält eine Übersicht der wichtigsten mathematischen Operatoren und Funktionen in R. Tabelle 4.1 Mathematische Operatoren und Funktionen in R
Zeichen
Bedeutung
Zeichen
Bedeutung
+
Addition
‒
Subtraktion
*
Multiplikation
/
Division
^
Potenz
sqrt(x)
Quadratwurzel
exp(x)
Exponentialfunktion ex
log(x)
Natürlicher Logarithmus
sum(x)
Summe
abs(x)
Betrag (absoluter Wert)
4.2
Logische Abfragen
Im folgenden Beispiel berechnen wir die Summe von 1, 5 und 7. Unter dem eingegebenen Befehl erscheint direkt das Ergebnis, nämlich 13: > 1+5+7 [1] 13
4.2 Logische Abfragen In R können wir auch logische Abfragen durchführen. Logische Abfragen benötigt man z. B., wenn man einzelne Analysen nur dann ausführen möchte, wenn bestimmte Bedingungen erfüllt sind. Diese Bedingungen werden dann als logische Abfrage formuliert. Bei einer logischen Abfrage wird ausgegeben, ob unsere Eingabe richtig (TRUE) oder falsch (FALSE) ist. In einer logischen Abfrage werden verschiedene logische Zeichen verwendet (s. Tab. 4.2). Hier sind ein paar sehr einfache Beispiele für logische Abfragen: > 3 > 2 [1] TRUE > 3 == 2 [1] FALSE
Tabelle 4.2 Zeichen für logische Abfragen in R
Zeichen
Bedeutung
Zeichen
Bedeutung
==
Gleich
!=
Ungleich
>
Größer
=
Größer gleich
3 < 2 & 2 < 3 [1] FALSE
37
38
4 Einführung in die Programmiersprache
Da nur eine, jedoch nicht beide Bedingungen zutreffen, ist das Ergebnis FALSE. Wenn wir jedoch stattdessen eine »oder«-Verknüpfung verwenden, erhalten wir das Ergebnis TRUE, denn eine der beiden Bedingungen ist ja in der Tat richtig. Hier werden die beiden Bedingungen mit dem Symbol | verknüpft: > 3 < 2 | 2 < 3 [1] TRUE
Die bisherigen logischen Abfragen waren Beispiele mit Zahlen. Man kann aber auch Texte eingeben. Dabei werden Anführungszeichen verwendet, um die Texteingabe von Objektnamen (s. Kap. 5) zu unterscheiden: > "abcd" == "abcd" [1] TRUE
Nun kommt leider eine schlechte Nachricht: R weiß nicht alles. Die folgende Abfrage führt bspw. zu einem eher unromantischen Ergebnis: > "typ aus statistikkurs" == "grosse liebe" [1] FALSE
4.3
Funktionen
Funktionen haben den folgenden Aufbau: > funktion(argument1 = wert1, argument2 = wert2, …)
Eine Funktion beginnt immer mit einem Namen (hier allgemein: funktion), gefolgt von Klammern. In den Argumenten innerhalb der Klammer werden die Details angegeben, z. B. auf welche Daten die Funktion angewandt werden soll. Ein Argument ist folgendermaßen aufgebaut: Der Name des Arguments (hier verallgemeinernd argument1 und argument2) steht vor dem einfachen Gleichheitszeichen. Die Einstellung bzw. der Wert des Arguments (hier verallgemeinernd wert1 und wert2) steht hinter dem einfachen Gleichheitszeichen. Vereinfacht kann man sich Argumente als verschiedene Schalter vorstellen, mit denen wir die Funktion steuern. Für jeden Schalter gibt es eine Standardeinstellung, die genommen wird, wenn das Argument nicht in der Funktion aufgeführt wird. Um die
4.3
Funktionen
Einstellung eines Schalters zu ändern, müssen wir das Argument in der Funktion aufführen und hinter dem Gleichheitszeichen den gewünschten Wert angeben. Es gibt verschiedene Arten von Werten, die in Argumenten eingegeben werden, z. B. TRUE oder FALSE Zahlen Wörter (in Anführungszeichen) Objekte (ohne Anführungszeichen, s. Kap. 5) Welche Argumente eine Funktion enthält und was diese bedeuten, kann man in der Hilfe-Datei zu der Funktion nachschlagen (s. Abschn. 4.3.3).
4.3.1
Ein erstes Beispiel
Als Beispiel betrachten wir die Funktionen c(), mean() und round(). Diese Funktionen werden wir in den späteren Kapiteln noch genauer besprechen. Mit der c-Funktion werden alle Werte innerhalb der Klammer zusammengefügt (c steht hier für combine): > c(1,4,7,9) [1] 1 4 7 9
R weiß jetzt, dass diese Werte in dieser Reihenfolge zusammengehören. Wenn wir nun den Mittelwert für diese Werte berechnen möchten, verwenden wir die meanFunktion. Der oben angegebene c-Befehl wird vollständig in die Klammer geschrieben, d. h., die c-Funktion ist in der mean-Funktion geschachtelt: > mean(c(1,4,7,9)) [1] 5.25
Wir können sogar noch einen Schritt weitergehen: Mit der round-Funktion wird der Mittelwert auf ganze Zahlen gerundet. Dafür werden die ineinander geschachtelten mean- und c-Funktionen komplett in die Klammer übernommen: > round(mean(c(1,4,7,9))) [1] 5
Auf diese Weise kann man viele Funktionen miteinander kombinieren. Die Reihenfolge, in der die Funktionen ausgeführt werden, ist streng festgelegt: Die Befehle werden von innen nach außen durchgeführt, d. h., zuerst wird die Funktion ausgeführt, die ganz innen steht. In unserem Beispiel oben werden also zunächst die Werte erfasst
39
40
4 Einführung in die Programmiersprache
(c-Funktion), dann der Mittelwert berechnet (mean-Funktion) und abschließend gerundet (round-Funktion). Tipp
Mehrfach geschachtelte Funktionen sind sehr schnell unübersichtlich und daher manchmal etwas schwierig nachzuvollziehen. Um zu verstehen, was in einem geschachtelten Befehl genau passiert, ist es hilfreich, zunächst nur die innerste Funktion auszuführen. Im Skript markiert man dazu lediglich den innersten Befehl, denn nur der Teil eines langen Befehls, der markiert ist, wird auch ausgeführt. Anschließend führt man die nächstinnere Funktion aus und arbeitet sich so langsam bis zum äußersten (und damit vollständigen) Befehl vor. Grundsätzlich sollte man versuchen, solche verschachtelten Befehle zu vermeiden (s. Kap. 23). Für viele Personen ist die Arbeit mit R zu Beginn etwas abschreckend, weil man viele verschiedene Funktionen kennen muss. So schlimm ist es jedoch nicht: Die meisten Funktionsnamen lassen sich mit einigen Englischkenntnissen durchaus herleiten. Die wichtigsten Funktionen sind zudem auf Cheatsheets enthalten, die man im Internet kostenlos herunterladen kann (s. Abschn. 3.3.3). Wenn man eine solches Cheatsheet als Spickzettel neben sich liegen hat, kann man schon eine Menge rechnen. Und zu guter Letzt sollte man sich nicht zu sehr unter Druck setzen. Das Ziel ist nicht, alle Funktionen auswendig zu können, sondern zu wissen, wo man nachschlagen kann.
4.3.2 Funktionen aus zusätzlichen Paketen Die bisher verwendeten Funktionen stammen aus den R-Basispaketen, also aus den Paketen, die wir bei der Installation von R automatisch mitgeliefert bekommen. Häufig verwenden wir jedoch Funktionen aus zusätzlichen Paketen (s. Abschn. 3.2). Der Aufbau dieser Funktionen ist aber – bis auf wenige Ausnahmen – eng an dem Aufbau der normalen Funktionen angelehnt. Wenn man trotzdem unsicher ist, wie eine bestimmte Funktion aufgebaut ist, hilft der Blick in die Hilfe-Datei (s. Abschn. 4.3.3). Die Namen der Funktionen denken sich die Programmiererinnen und Programmierer der zusätzlichen Pakete übrigens selbst aus. Dadurch kann es vorkommen, dass Funktionen aus zwei verschiedenen Paketen denselben Namen erhalten. Zum Beispiel enthält das Paket dplyr (Wickham et al., 2020), das wir in Kapitel 7 kennenlernen werden, eine Funktion mit dem Namen filter. So eine Funktion ist aber auch im R-Basispaket stats enthalten, das automatisch mit dem Starten von R geladen wird. Mehrfach vergebene Namen für Funktionen werden dann zum Problem,
4.3
Funktionen
wenn beide Pakete gleichzeitig geladen sind. Im folgenden Beispiel laden wir das Paket dplyr (das vorher installiert worden sein muss) und erhalten die folgende (verkürzt dargestellte) Warnmeldung: > library(dplyr) Attache Paket: ‘dplyr’ The following objects are masked from ‘package:stats’: filter, lag
Diese Warnmeldung sagt uns, dass die Funktionen filter und lag sowohl im neu geladenen Paket dplyr vorkommen als auch in dem bereits geladenen R-Basispaket stats. Welche Variante dieser Funktionen würde R jetzt nutzen? Immer die aus dem Paket, das zuletzt geladen wurde. Das klingt etwas gewagt? Ist es auch. Deshalb sollte man in solchen Fällen bei der Eingabe der Funktion immer den Namen des Pakets, aus dem die Funktion genommen werden soll, davor schreiben, gefolgt von einem doppelten Doppelpunkt: > dplyr::filter()
Damit stellen wir sicher, dass die filter-Funktion aus dem dplyr-Paket verwendet wird, egal welche anderen Pakete in welcher Reihenfolge geladen wurden.
4.3.3 Hilfe zu bestimmten Funktionen Wenn man nicht genau weiß, wie eine Funktion korrekt aufgebaut sein sollte (d. h., aus welchen Bestandteilen sie besteht und in welcher Reihenfolge die einzelnen Argumente eingegeben werden), kann man mit einem der folgenden Befehle die HilfeDatei dieser Funktion öffnen: > help(NameDerFunktion) > ?NameDerFunktion)
Die Hilfe-Dateien für bestimmte Funktionen sind ziemlich technisch formuliert. Einsteiger empfinden den Begriff »Hilfe« für diese Dateien daher eher als unpassend. Trotzdem sollte man sich schon von Anfang an immer wieder die Hilfe-Dateien anschauen, um sich mit dem Aufbau und den Inhalten vertraut zu machen. Schon bald sind diese Hilfe-Dateien eine unverzichtbare Quelle, um R-Funktionen zu verstehen.
41
42
4 Einführung in die Programmiersprache
Die Hilfe-Dateien haben einen standardisierten Aufbau, den wir uns hier am Beispiel der describe-Funktion aus dem psych-Paket (Revelle, 2019) anschauen (s. Abb. 4.1): describe {psych}. Oben links steht der Name der Funktion sowie in geschweiften Klammern der Name des Pakets, in dem diese Funktion enthalten ist. Titel. Fasst die Eigenschaften der Funktion kurz zusammen. Meistens zu kurz. Description. Hier wird die Funktion mehr oder weniger anschaulich beschrieben. Usage. In diesem Abschnitt ist der Aufbau der Funktion dargestellt. Man kann hier u. a. erkennen, welche Argumente die Funktion enthält, wie diese heißen und welche Standardeinstellungen für die Argumente verwendet werden. Arguments. Hier wird für jedes Argument beschrieben, worauf sich das Argument bezieht und welche Einstellungen es gibt. Details. Für einige Pakete findet man in diesem Abschnitt weitere Informationen zur Funktion und manchmal auch zu den zugrundeliegenden statistischen Konzepten. Value. Hier werden alle in der Ausgabe enthaltenen Elemente oder Werte beschrieben. Besonders nützlich, wenn man die Abkürzungen nicht kennt.
Abbildung 4.1 Anfang der Hilfe-Datei zur describe-Funktion aus dem psych-Paket
4.5
Ein paar Stilregeln
Note. Optionaler Abschnitt mit zusätzlichen Anmerkungen. Author(s). Hier erfährt man, wer hinter dem Paket steckt und wie man diese Person erreichen kann. References. Falls irgendwo in der Hilfe-Datei Publikationen zitiert wurden, werden diese hier aufgeführt. See Also. Verwandte Funktionen. Examples. Beispiele für R-Befehle, in denen die Funktion genutzt wird. Diese Beispiele sollten so programmiert sein, dass sie ohne zusätzliche Installationen (z. B. von Daten) auskommen. Das bedeutet, dass man die Befehle in das Skript kopieren und direkt ausprobieren kann. Schon oft wurde mir der Aufbau einer Funktion erst durch das Ausprobieren dieser Beispiele so richtig klar.
4.4 Kommentare Jedes R-Skript sollte ausführlich kommentiert sein. Man kann nicht zu viel, aber sehr gut zu wenig kommentieren. Kommentare ermöglichen es anderen und unserem zukünftigen Ich nachzuvollziehen, was man wie und vor allem warum gerechnet hat. Kommentare beginnen immer mit dem Symbol # (Raute oder neudeutsch Hashtag). Alles, was hinter diesem Symbol steht, wird dann beim Ausführen der Befehle ignoriert. # Ein Kommentar kann in einer eigenen Zeile stehen > 1+5+7 # oder auch direkt hinter einem Befehl
Der Kommentar endet mit dem Ende der Zeile. Ist ein Kommentar länger als eine Zeile, muss jede Zeile mit # beginnen, sonst interpretiert R die neue Zeile als neuen Befehl.
4.5
Ein paar Stilregeln
Grundsätzlich sollten Sie Ihr R-Skript so gestalten, dass Sie selbst damit gut zurechtkommen. Die hier aufgelisteten Stilregeln haben sich aber bewährt, damit Befehle und Skripte übersichtlich bleiben (s. https://style.tidyverse.org/). Weitere Tipps für das Strukturieren von R-Skripten gibt es in Kapitel 23. Leerzeichen. Verwenden Sie Leerzeichen vor und nach Operatoren wie == , objekt vektor vektor [1] 1 4 7 9
5.1
Neue Objekte anlegen
Im nächsten Schritt berechnen wir den Mittelwert mit der mean-Funktion. Diese Funktion wird nun auf das vorher definierte Objekt vektor angewandt. Das Ergebnis wird in einem neuen Objekt mit dem Namen mittelwert gespeichert: > mittelwert gerundeter.mittelwert gerundeter.mittelwert [1] 5
Die Objekte werden im sog. Workspace gespeichert (in RStudio auch als Environment bezeichnet). Dabei handelt es sich um eine Art Arbeitsspeicher. Die Objekte im Workspace werden im Environment-Fenster angezeigt und stehen uns für den Rest der Sitzung zur Verfügung. Das heißt, selbst wenn wir die Befehlszeile löschen, mit der wir das Objekt erstellt hatten, ist das Objekt weiterhin vorhanden. In Abschnitt 5.4 besprechen wir, was es mit dem Workspace auf sich hat, wie man bei der Arbeit mit Objekten den Überblick behält und wie man unerwünschte Objekte wieder loswird. Noch ein allgemeiner Hinweis: Das Arbeiten mit Objekten ist etwas gewöhnungsbedürftig und erscheint auf den ersten Blick möglicherweise überflüssig. Trotzdem sollten wir uns damit vertraut machen, denn später brauchen wir Objekte für die Durchführung bestimmter statistischer Analysen wie z. B. der hierarchischen Regressionsanalyse (s. Kap. 15). Tipp
Sobald wir irgendeinen Text in R eingeben, geht R davon aus, dass es sich dabei entweder um den Namen einer Funktion oder um den Namen eines Objekts handelt. Alle anderen Texte (z. B. Dateinamen oder Wertelabels) müssen daher immer in Anführungszeichen gesetzt werden, sonst werden sie ebenfalls als Funktionen bzw. Objekte interpretiert und wir erhalten wahrscheinlich eine Fehlermeldung.
47
48
5 Objekte
5.2
Objekttypen
In R werden verschiedene Typen von Objekten unterschieden. Wir stellen hier die Objekttypen vor, die für den Einstieg besonders wichtig sind: Vektoren, Faktoren und Data Frames.
5.2.1
Vektoren
Vektoren kommen uns noch aus dem Mathematik-Unterricht bekannt vor: Ein Vektor war damals eine Menge von Elementen, die in mathematischer Schreibweise untereinander aufgelistet wurden, z. B. so: 3 2 6
Ein Vektor in R ist ähnlich: Auch hier handelt es sich um eine Menge von Elementen, z. B. die Werte verschiedener Versuchspersonen auf einer Variablen. Ein Vektor kann sowohl Zahlen als auch Buchstaben enthalten. Kommen nur Zahlen vor, spricht man von einem numerischen Vektor (numeric). Handelt es sich dabei ausschließlich um ganze Zahlen, bezeichnet man diesen Vektor als integer. Sobald Buchstaben vorkommen, handelt es sich automatisch um einen Text-Vektor (character). Logische Vektoren (logical) enthalten nur die Werte TRUE und FALSE. Zur Veranschaulichung erstellen wir einen numerischen Vektor, der die Altersangaben für sieben Personen enthält. Dazu geben wir den folgenden Befehl ein: > alter length(alter) [1] 7
5.2.2
Faktoren
In der Statistik haben wir gelernt, dass numerische Daten unterschiedliche Skalenniveaus annehmen können, z. B. Nominal-, Ordinal-, Intervall-, Verhältnis- oder Absolutskalenniveau (s. Eid et al., 2017). In R werden Variablen mit Ordinalskalenniveau oder höheren Skalenniveaus als Vektoren angelegt. Variablen mit Nominalskalenniveau werden dagegen als Faktoren gespeichert. Die Unterscheidung zwischen Faktoren und Vektoren hat wichtige Konsequenzen. Wie wir später sehen werden, können viele Analysen nur durchgeführt werden, wenn die Variablen den richtigen Objekttyp haben. Im folgenden Beispiel legen wir die nominalskalierte Variable Beziehungsstatus an. Zunächst fassen wir die Werte in einem Vektor zusammen. Dieser Vektor bekommt den Namen bez und enthält sieben Elemente, die nur die Werte 1 (vergeben) und 2 (Single) annehmen: > bez bez [1] 1 2 2 2 1 1 2
Wir müssen nun den Vektor bez in einen Faktor konvertieren. Die konvertierte Variable bekommt den Namen bez.faktor. Der dazugehörige Befehl sieht zunächst recht einfach aus: > bez.faktor bez.faktor [1] 1 2 2 2 1 1 2 Levels: 1 2
In Abschnitt 7.2 gehen wir noch einmal detaillierter darauf ein, wie man Vektoren in Faktoren konvertiert. Dort werden wir auch lernen, wie man Wertelabels für die einzelnen Ausprägungen vergibt.
5.2.3
Data Frames
Bisher haben wir zwei Arten von Objekten kennengelernt: Vektoren und Faktoren. Diese Objekte kann man sich auch als einzelne Variablen vorstellen. Wenn man alle Variablen (Vektoren und Faktoren) in einem einzigen Objekt kombiniert, erhält man einen Data Frame. Ein Data Frame besteht aus mehreren Zeilen und mehreren Spalten. In den Zeilen eines Data Frames stehen die Fälle oder Beobachtungen (z. B. die einzelnen Studienteilnehmer). Die Variablen bilden die Spalten. Die Variablen dürfen sowohl Zahlen als auch Buchstaben enthalten. Wenn wir Daten aus externen Programmen in R einlesen, werden diese meistens direkt in einem Data Frame gespeichert (s. Kap. 6). Wir müssen also selten einen Data Frame selbst erstellen. Trotzdem machen wir dies hier einmal, damit das Konzept verdeutlicht wird. Im Folgenden möchten wir die beiden bisher erstellten Objekte alter und bez.faktor in einem Data Frame kombinieren. Dazu führen wir den folgenden Befehl aus: > beispiel.data.frame names(beispiel.data.frame) [1] "alter" "bez.faktor"
Sehr detaillierte Informationen über das Objekt erhalten wir mit der str-Funktion. Die Abkürzung str steht für structure, d. h., die Struktur des aktuellen Objekts wird dargestellt. Wenn wir diese Funktion auf den Data Frame beispiel.data.frame anwenden, erhalten wir die folgende Ausgabe: > str(beispiel.data.frame) 'data.frame': 7 obs. of 2 variables: $ alter : num 19 23 22 25 21 20 19 $ bez.faktor: Factor w/ 2 levels "1","2": 1 2 2 2 1 1 2
Zunächst erfahren wir, dass es sich bei dem Objekt um einen Data Frame mit sieben Personen bzw. observations (7 obs.) und zwei Variablen (2 variables) handelt. Anschließend folgt eine Liste mit allen Variablen (hier alter und bez.faktor), die jeweils (1) den Variablennamen, (2) die Klasse des Objekts (hier numerischer Vektor und Faktor) sowie (3) die Werte der ersten Personen enthält. Es ist auch möglich, die Rohdaten direkt zu betrachten. Dazu klicken wir entweder in RStudio auf den Namen des Data Frames oder wenden die View-Funktion auf den Data Frame an. > View(beispiel.data.frame)
Damit öffnet sich ein neues Fenster oben links, in dem wir die Rohdaten anschauen können (Abb. 5.2). Wichtig: Wenn man etwas an dem Data Frame ändert oder ihn löscht, wird diese Datenansicht nicht automatisch aktualisiert oder geschlossen. R
51
52
5 Objekte
greift immer auf die Version des Data Frames zu, die aktuell im Workspace enthalten ist, nicht auf die, die in der Datenansicht zu sehen ist.
Abbildung 5.2 Datenansicht des Data Frames, erzeugt mit der View-Funktion
5.2.4 Weitere Objekte In R können Daten noch in weiteren Objekttypen gespeichert werden. Diese werden wir für den Einstieg aber seltener verwenden, daher werden sie hier nur kurz dargestellt. Matrizen sehen auf den ersten Blick aus wie Data Frames. Auch hier handelt es sich um Objekte mit mehreren Zeilen und Spalten. Der große Unterschied ist, dass in einer Matrix nur Daten eines Typs dargestellt werden können, also nur numerische Daten oder nur Textdaten. Um mehrere Vektoren oder Faktoren in einer Matrix zusammenzufassen, verwendet man die cbind-Funktion oder die rbind-Funktion (s. Tab. 5.1). Tibbles sind spezielle Varianten von Data Frames, die von Funktionen aus den Paketen der tidyverse-Familie verwendet werden (s. Kap. 7). Tibbles sollen eine verbesserte und vereinfachte Version von Data Frames sein. Die meisten Funktionen können mit Data Frames und Tibbles gleich gut umgehen, aber manchmal ist es notwendig, einen Data Frame in einen Tibble zu konvertieren (Funktion: as_tibble) oder einen Tibble in einen Data Frame (Funktion: as.data.frame). Listen können wie Data Frames oder Matrizen mehrere Objekte gleichzeitig enthalten. Während aber bei Data Frames und Matrizen nur Vektoren mit derselben Länge, d. h., derselben Anzahl von Elementen, kombiniert werden können, können Listen auch Objekte mit unterschiedlichen Eigenschaften und unterschiedlicher Anzahl von Elementen speichern. Listen werden mit der list-Funktion erstellt.
5.3
Elemente aus Objekten auswählen
Darüber hinaus gibt es sehr viele andere Objekttypen, z. B. Tabellen, statistische Modelle oder Formeln. Diese speziellen Objekttypen werden später eingeführt. Wenn wir für ein Objekt wissen möchten, um was für eine Art von Objekt es sich dabei handelt, verwenden wir die class-Funktion: > class(beispiel.data.frame) [1] "data.frame" > class(bez.faktor) [1] "factor"
Tabelle 5.1 Funktionen zum Anlegen von Objekten
Funktion
Beschreibung
c()
Fügt mehrere Werte in einem Vektor zusammen.
factor()
Wandelt einen Vektor in einen Faktor um.
data.frame()
Fügt Vektoren oder Data Frames in einem Data Frame zusammen.
cbind()
Fügt Vektoren in einer Matrix zusammen. Pro Vektor wird eine Spalte (c wie column) angelegt.
rbind()
Fügt Vektoren in einer Matrix zusammen. Pro Vektor wird eine Zeile (r wie row) angelegt.
as_tibble()
Wandelt einen Data Frame in einen Tibble um.
list()
Fügt mehrere Objekte zu einer Liste zusammen. Die Objekte können verschiedene Objekttypen sein.
5.3
Elemente aus Objekten auswählen
Wir haben gesehen, dass Objekte oft mehrere Elemente enthalten. Zum Beispiel besteht ein Data Frame aus mehreren Variablen, und eine Variable aus mehreren Werten. Um eine Analyse mit einer bestimmten Variable durchführen zu können, müssen wir also diese Variable irgendwie aus dem Data Frame herausbekommen. Etwas allgemeiner ausgedrückt: Wir möchten ein oder mehrere Elemente aus einem Objekt auswählen. Hier lernen wir zwei grundlegende Möglichkeiten kennen, mit denen man Elemente aus Objekten auswählen kann. Im Laufe des Buchs werden uns noch weitere Optionen begegnen, die für bestimmte Problemstellungen besonders geeignet sind.
53
54
5 Objekte
5.3.1
Das Dollarzeichen
In vielen Objekttypen erhalten die einzelnen Elemente Namen. Zum Beispiel werden für die Variablen in einem Data Frame Variablennamen vergeben. Bei derartigen Objekten kann man die einzelnen Elemente mit dem Dollarzeichen auswählen. Dazu schreibt man als erstes den Namen des Objekts auf, dann das Dollarzeichen $, und schließlich den Namen des Elements, alles ohne Leerzeichen. Im folgenden Befehl wählen wir die Variable alter aus dem oben erstellten Data Frame beispiel.data.frame aus: > beispiel.data.frame$alter [1] 19 23 22 25 21 20 19
Dieser Befehl heißt: Nimm das Objekt beispiel.data.frame und suche dort nach dem Element alter. Eine Liste aller in einem Objekt vorhandenen Elemente, die mit dem Dollarzeichen ausgewählt werden können, erhält man über die Funktion str(objektname). Um mehrere Variablen auf einmal auszuwählen, muss man diese in einem neuen Data Frame zusammenfügen. Wie das geht, besprechen wir in Abschnitt 7.3.1. Tipp
Beginnt man in RStudio, den Namen eines Objekts einzutippen, so erscheinen in einem kleinen Fenster daneben Vorschläge für Namen von existierenden Objekten. Ist der richtige Name dabei, kann man ihn anklicken oder – besser – mit den Pfeiltasten auswählen und dann mit Tabulator-Taste vervollständigen lassen. Das funktioniert auch mit Variablennamen. Sobald man den Namen des Data Frames und das Dollarzeichen eingegeben hat, werden die Namen aller Variablen angezeigt. Durch die Angabe weiterer Buchstaben kann man die Auswahl reduzieren und dann wie oben den passenden Variablennamen vom Programm vervollständigen lassen. Das spart nicht nur Zeit, sondern verringert auch die Wahrscheinlichkeit für Tippfehler.
5.3.2
Die Index-Funktion
Bei Objekten mit einer definierten Anzahl von Dimensionen kann man einzelne Elemente über die Index-Funktion auswählen. Ein Vektor oder ein Faktor haben eine Dimension, ein Data Frame, ein Tibble oder eine Tabelle haben zwei Dimensionen (Zeilen und Spalten), und sog. Arrays haben mehr als zwei Dimensionen.
5.3
Elemente aus Objekten auswählen
Um ein bestimmtes Element auszuwählen, gibt man den Objektnamen ein, gefolgt von eckigen Klammern. Innerhalb der Klammern wird die Position bzw. der Index des Elements angegeben, das man auswählen möchte. Im folgenden Beispiel lassen wir uns im Data Frame beispiel.data.frame den zweiten Wert der Variablen alter ausgeben. > beispiel.data.frame$alter[2] [1] 23
Es ist auch möglich, mehrere Indizes einzugeben. Dazu müssen die einzelnen Indizes mit der c-Funktion verbunden werden. Hier lassen wir uns den ersten, dritten und fünften Wert der Variablen alter ausgeben: > beispiel.data.frame$alter[c(1, 3, 5)] [1] 19 22 21
Bei zweidimensionalen Objekten muss man einen Index für jede Dimension angeben. In den eckigen Klammern werden daher zwei Werte eingegeben. Der erste Wert steht für die Zeile, der zweite Wert für die Spalte. Die Indizes werden durch ein Komma getrennt. Hier lassen wir uns den in der dritten Zeile und in der zweiten Spalte des Data Frames beispiel.data.frame enthaltenen Wert ausgeben. > beispiel.data.frame[3, 2] [1] 2
Es ist möglich, einen dieser Indizes einfach wegzulassen. Lässt man bspw. den zweiten Index weg, so werden anstelle einer bestimmten Spalte einfach alle Spalten ausgegeben. Auf diese Art ist es möglich, alle Werte einer bestimmten Versuchsperson anzufordern. Lässt man stattdessen den ersten Index weg, so werden anstelle einer bestimmten Zeile alle Zeilen ausgegeben. So kann man die Werte einer bestimmten Variablen anfordern.
55
56
5 Objekte
Im folgenden Beispiel lassen wir uns wieder die Werte für die Variable alter ausgeben, diesmal aber mit der Index-Funktion. Dafür müssen wir zunächst herausfinden, an welcher Position diese Variable im Data Frame vorkommt. Das können wir z. B. mit der names-Funktion erfahren: > names(beispiel.data.frame) [1] "alter" "bez.faktor"
Die Variable alter ist die erste Variable in diesem Data Frame. Wir geben also ein: > beispiel.data.frame[, 1] [1] 19 23 22 25 21 20 19
Innerhalb der eckigen Klammern steht kein Wert vor dem Komma. Damit ist klar, dass wir die Werte für alle Zeilen erhalten möchten. Die Index-Funktion lässt sich auch nutzen, um bestimmte Zeilen oder Reihen auszuschließen. Schreibt man vor den Index in Minuszeichen, so werden alle Elemente mit Ausnahme des Elements mit dieser Position ausgegeben. Hier lassen wir uns die Werte der ersten Variable alter ohne den Wert der zweiten Zeile ausgeben. > beispiel.data.frame[-2, 1] [1] 19 22 25 21 20 19
Die Index-Funktion ist zugegebenermaßen etwas gewöhnungsbedürftig. Wer weiß schon auswendig, ob die gewünschte Variable die zwanzigste oder die einundzwanzigste im Data Frame ist? Wir werden deshalb diese Funktion nur selten für die Auswahl von Variablen einsetzen. Sie ist jedoch sehr praktisch, um bestimmte Elemente aus Tabellen auszuwählen, wie wir in den späteren Kapiteln sehen werden. Tipp
Die Index-Funktion kann auch verwendet werden, um Elemente aus Listen auszuwählen. Dann muss man allerdings doppelte eckige Klammern verwenden: [[ ]]
5.4
Der Workspace
Objekte werden in R im sog. Workspace (auch: Environment, Umgebung) gespeichert. Dabei handelt es sich um eine Art temporären Ablageort, der alle Objekte ent-
5.4
Der Workspace
hält, die in einer R-Sitzung geladen oder erstellt wurden. Man kann also mehrere Objekte (z. B. mehrere Datensätze) gleichzeitig geöffnet haben und mit ihnen arbeiten. Im Laufe einer R-Sitzung legt man meistens eine Reihe von neuen Objekten an, z. B. wenn man Variablen bearbeitet eine Menge von Variablen auswählt statistische Modelle miteinander vergleicht eigene Funktionen schreibt und/oder anwendet Es ist daher sinnvoll, sich von Zeit zu Zeit einen Überblick über alle erstellten Objekte zu verschaffen. In RStudio werden alle Objekte im Environment-Fenster oben rechts angezeigt. Alternativ kann man sich alle Objekte mit den Befehlen objects()oder ls() auflisten lassen. Im folgenden Beispiel lassen wir uns alle Objekte auflisten, die bisher in diesem Kapitel erstellt wurden: > objects() [1] "alter" [4] "geschl"
"beispiel.data.frame" "gerundeter.mittelwert" "bez.faktor" "mittelwert" "vektor"
Vielleicht ist Ihnen schon aufgefallen, dass die Ausgabezeilen immer mit einer Zahl in einer eckigen Klammer beginnen. Mit diesen Zahlen werden alle Elemente einer Ausgabe durchnummeriert. Hier beginnt die zweite Zeile mit [4], was bedeutet: Das nächstgenannte Elemente ist das vierte in der Auflistung. Je nachdem, wie breit Ihr Ausgabefenster ist, kann bei Ihnen die zweite Zeile mit einem anderen Element und damit auch mit einer anderen Zahl in eckigen Klammern beginnen. Wenn der Workspace zu groß wird, sollte man ihn aufräumen. Mit der removeFunktion kann man einzelne Objekte löschen. Diese Funktion kann man auch mit rm() abkürzen. Hier löschen wir das Objekt alter: > remove(alter)
Mit dem folgenden Befehl löscht man alle Objekte, die aktuell im Workspace enthalten sind: > remove(list=ls())
In RStudio kann man auch alle Objekte löschen, indem man entweder im Environment-Fenster auf das Pinsel-Symbol klickt oder im Menü die Option SESSION → CLEAR WORKSPACE wählt.
57
58
5 Objekte
5.5
Objekte speichern und öffnen
Wenn wir Objekte neu erstellt haben, stehen diese uns nur für die laufende R-Sitzung zur Verfügung. Sobald wir R schließen, verschwinden alle Objekte. Das ist nicht unbedingt schlimm, denn solange wir unser Skript gespeichert haben (s. Abschn. 3.1.2), können wir dieses einfach neu ausführen und damit alle Objekte wiederherstellen. Manchmal macht es aber Sinn, Objekte dauerhaft in Dateien zu speichern. Zum Beispiel möchten wir häufig unsere Data Frames, die die Daten einer Studie enthalten, als Dateien speichern. Dafür legen wir zunächst unser Arbeitsverzeichnis fest.
5.5.1
Arbeitsverzeichnis festlegen
Sofern man R nichts anderes mitteilt, speichert das Programm die aktuellen Vorgänge immer in einem bestimmten Ordner, dem sog. Arbeitsverzeichnis oder working directory. Das aktuelle Arbeitsverzeichnis kann man durch den folgenden Befehl abfragen: > getwd()
Der Ausdruck wd steht für working directory. Als Ausgabe erhält man dann den Dateipfad für das aktuelle Arbeitsverzeichnis. Mit dem folgenden Befehl ändert man das Arbeitsverzeichnis für die Dauer der aktuellen Sitzung: > setwd("C:/Ordner1/Ordner2/R für Einsteiger")
Der Teil C:/Ordner1/Ordner2/ ist hier nur ein Platzhalter und wird so an anderen Computern nicht funktionieren. Wir müssen diesen Platzhalter mit dem Pfad ersetzen, der auf unserem eigenen Computer gilt. Windows-Nutzer aufgepasst! Windows verwendet für die Trennung der einzelnen Ordnerebenen den rückwärts gerichteten Schrägstrich (\), während R den vorwärts gerichteten Schrägstrich (/) verwendet. In RStudio kann man das aktuelle Arbeitsverzeichnis auch ändern, indem man im Fenster unten rechts die Ordneransicht aufruft (unter FILES ), sich zu dem Ordner durchklickt, der das aktuelle Arbeitsverzeichnis sein soll, und diesen Ordner unter MORE → SET AS WORKING DIRECTORY als Arbeitsverzeichnis definiert. Mit dem folgenden Befehl erhält man eine Liste aller im aktuellen Arbeitsverzeichnis gespeicherten Dateien: > dir()
5.5
Objekte speichern und öffnen
Tipp
Wenn man das Arbeitsverzeichnis über den Menübefehl ändert, wird der dazugehörige Befehl in der Konsole angezeigt. Es ist sehr empfehlenswert, diesen Befehl aus der Konsole zu kopieren und oben im Skript einzufügen. So muss man sich nicht in jeder Sitzung zum gewünschten Arbeitsverzeichnis durchklicken. Noch einfacher macht man es sich, wenn man mit sog. Projekten arbeitet. Mehr Informationen dazu gibt es in Kapitel 23.
5.5.2
Objekte als .RData-Datei speichern
Objekte werden im Format .RData gespeichert. Um einzelne Objekte in einer .RDataDatei zu speichern, verwenden wir die folgende Funktion: > save(objektname, file = "dateiname.RData")
Mit diesem Befehl wird das Objekt mit dem Namen objektname als Datei mit dem Namen dateiname.RData im aktuellen Arbeitsverzeichnis gespeichert. Wichtig: Dateiname und Objektname sind nicht zwangsläufig identisch. Wir können die Datei genauso benennen wie das Objekt oder auch einen ganz anderen Namen wählen. Wenn schon eine Datei unter diesem Namen angelegt wurde, wird diese automatisch überschrieben. Möchte man die Datei in einem anderen als dem aktuellen Arbeitsverzeichnis speichern, muss man hier den vollständigen Dateipfad angeben. Dabei müssen wir wieder beachten, dass R vorwärts gerichtete Schrägstriche (/) als Trennzeichen für die einzelnen Ordnerebenen verwendet. Mit dem folgenden Befehl speichern wir die Datei in einem anderen Ordner: > save(objektname, file = "C:/Ordner1/dateiname.RData")
Tipp
Im .RData-Format gespeicherte Daten können nur in R geöffnet und bearbeitet werden. Um diese Daten auch in anderen Statistik-Programmen verwenden zu können, müssen wir sie in eine Textdatei exportieren. Voraussetzung ist aber, dass die Daten in Tabellenform organisiert sind. Das ist bei Data Frames der Fall; es gibt allerdings auch Objekte, die anders organisiert sind und daher nicht so einfach exportiert werden können. Wie man Daten, Tabellen und andere Ausgaben exportiert, besprechen wir in Kapitel 22.
59
60
5 Objekte
Manchmal möchte man nicht ein einzelnes Objekt als Datei speichern, sondern alle Objekte, die gerade im Workspace vorhanden sind. In RStudio kann man dazu auf das Speichern-Symbol im Environment-Fenster klicken oder die folgende Menüoption wählen: SESSION → SAVE WORKSPACE AS. Wichtig: Über diese Menüoption kann man nicht einzelne Objekte speichern, sondern nur den gesamten Inhalt des aktuellen Workspace! Alternativ gibt es natürlich auch dafür wieder eine Funktion: > save.image(file = "workspace.RData")
5.5.3
.RData-Dateien öffnen
Alle Dateien mit der Endung .RData lassen sich über die load-Funktion öffnen: > load("dateiname.RData")
Wenn wir nur den Dateinamen angeben, wie im Beispiel oben, geht R davon aus, dass diese Datei im aktuellen Arbeitsverzeichnis gespeichert ist. Ist das nicht der Fall, müssen wir entweder das Arbeitsverzeichnis ändern (s. Abschn. 5.5.1) oder den vollständigen Dateipfad angeben, z. B. (in Windows) so: > load("C:/Ordner1/Ordner2/R für Einsteiger/dateiname.RData")
Auf den meisten Computern werden .RData-Dateien bei der Installation von R automatisch mit RStudio verknüpft. Das bedeutet, dass man diese Dateien wie gewohnt über Anklicken öffnen kann. Sie werden dann direkt in RStudio geladen. Außerdem kann man Dateien von RStudio aus über Klicken öffnen, entweder über das ÖffnenSymbol im Environment-Fenster oder über die Menüoption SESSION → LOAD WORKSPACE. Es ist aber trotzdem empfehlenswert, den Befehl zum Laden der Dateien im Skript aufzuführen, denn so muss man die Datei nicht jedes Mal erneut per Hand öffnen, wenn man eine neue R-Sitzung startet. Stattdessen kann man einfach den einmalig angelegten Befehl dafür ausführen. Tipp
Der Name eines als .RData-Datei gespeicherten Objekts kann sich vom Dateinamen unterscheiden. Zum Beispiel könnte das Objekt daten unter dem Dateinamen Meine Daten.RData gespeichert werden. Wenn man eine .RData-Datei öffnet, kennt man daher nicht den Namen des geladenen Objekts. Es gibt dafür
5.6
Die wichtigsten Funktionen im Überblick
jedoch eine Lösung: Einfach das Argument verbose = TRUE in der load-Funktion ergänzen – dann werden die Namen aller in dieser Datei enthaltenen Objekte ausgegeben.
5.6
Die wichtigsten Funktionen im Überblick
Befehl
Funktion
objekt1 daten1 daten1 id alter extra geschl 1 1 19 3.5 0 2 2 21 1.2 0 3 3 25 4.3 1 4 4 20 3.1 1 5 5 NA 2.7 0 6 6 18 2.5 0 7 7 19 2.1 1 8 8 20 4.1 0 9 9 22 NA 1 10 10 21 2.9 1
An diesem Beispiel gehen wir jetzt auf ein paar Besonderheiten ein, die man manchmal beim Einlesen von Daten berücksichtigen muss. Objekttyp Das von uns erstellte Objekt ist ein Data Frame. Das können wir z. B. herausbekommen, indem wir die class-Funktion auf das neue Objekt anwenden:
6.1
Daten aus Textdateien einlesen
> class(daten1) [1] "data.frame"
Zeilennummern Data Frames erhalten in R automatisch Zeilennummern. Die allererste Spalte ist also nicht eine Kopie der id-Variable, sondern hier werden lediglich die Zeilen durchnummeriert. Fehlende Werte Nicht immer füllen die Teilnehmer ihre Fragebögen vollständig aus, selbst wenn wir sie ausdrücklich darum bitten. Wenn Angaben zu einzelnen Variablen fehlen, sprechen wir von fehlenden Werten. Diese werden in R mit NA (»not available«) kenntlich gemacht. In Textdaten werden fehlende Werte entweder durch zwei direkt aufeinander folgende Datenfeldtrennzeichen kenntlich gemacht oder durch bestimmte Werte codiert. Im ersteren Fall muss man beim Einlesen der Daten nichts beachten. R erkennt diese Werte als fehlende Werte, wie in dem Beispiel oben. Im zweiten Fall müssen wir in der Funktion das Argument na ergänzen, mit dem wir angeben, welche Werte in fehlende Werte umgewandelt werden sollen. Sind fehlende Werte z. B. mit -99 codiert, ergänzt man das Argument na = "-99". Diese Werte werden dann beim Einlesen automatisch in NA umgewandelt. Vektoren und Faktoren Variablen, die nur aus Zahlen bestehen, werden automatisch als Vektoren eingelesen. Handelt es sich bei einer dieser Variablen um eine nominalskalierte Variable, müssen wir diese Variable nach dem Datenimport in einen Faktor konvertieren (s. Abschn. 7.2.3). Dezimaltrennzeichen R verwendet immer Punkte als Dezimaltrennzeichen, egal welches Trennzeichen in den Textdaten verwendet wurde. Lesen Sie mal die Datei Textdaten_semikolon.csv mit der read.csv2-Funktion ein und schauen Sie sich die Daten an. Auch dann werden Zahlen mit Nachkommastellen mit einem Punkt als Dezimaltrennzeichen dargestellt, obwohl dafür in der csv-Datei ein Komma verwendet wurde. Andere Textformate Die read.csv- und read.csv2-Funktionen sind Varianten der allgemeineren Funktion read.table, mit der man beliebige Textformate einlesen kann. Diese Funktion enthält verschiedene Argumente, mit denen man die Eigenschaften der Daten beschreiben kann, z. B.
67
68
6 Daten importieren
dec. Dezimaltrennzeichen, z. B. Komma (dec = ",") oder Punkt (dec = ".")
sep. Art des Datenfeldtrennzeichens, z. B. Komma (sep = ","), Semikolon (sep = ";"), Tabulator (sep = "\t ") oder Leerzeichen (sep = " ") header. Gibt an, ob die Variablennamen in der ersten Zeile (header = TRUE) stehen oder nicht (header = FALSE). na. Codierung der fehlenden Werte Mit der Funktion read.fwf werden Daten im sog. festen ASCII-Format eingelesen. Bei diesem Format stehen die Daten einer Variablen immer in derselben Spalte, und Werte unterschiedlicher Variablen werden nicht durch Datenfeldtrennzeichen getrennt.
6.2
Andere Datenformate einlesen
Tabellenkalkulationsprogramme wie Excel und kommerzielle Statistik-Programme wie SPSS oder Stata verwenden eigene Dateiformate für Daten. Es gibt eine Reihe von Paketen, die uns den Import von derartigen Dateiformaten ermöglichen. Das Paket haven (Wickham & Miller, 2019) ist ein Teil der tidyverse-Familie (mehr dazu in Kap. 7) und kann Daten aus den Statistik-Programmen SPSS (Funktion read_sav), Stata (Funktion read_dta) und SAS (Funktionen read_sas und read_xpt) importieren. Das Paket foreign (R Core Team, 2019a) kennt noch eine Reihe weiterer Dateiformate und ermöglicht auch den Export von Daten aus R in Dateiformate, die von anderen Statistik-Programmen gelesen werden können (s. Abschn. 22.1). In RStudio kann man Daten auch über eine Menüoption einlesen. Diese findet sich im Environment-Fenster oben rechts (IMPORT DATASET ) oder über FILE → IMPORT DATASET. Zur Auswahl stehen hier die Dateiformate csv, Excel, SPSS, Stata und SAS. Nachdem man das passende Dateiformat gewählt hat, öffnet sich ein Fenster, in dem man weitere Einstellungen vornehmen kann. Aufgrund dieser Einstellungen wird ein Befehl erzeugt, der Funktionen aus dem readr-Paket (Wickham et al., 2018) verwendet.
6.3
Daten betrachten
Nach dem Einlesen sollte man immer überprüfen, ob der Import fehlerfrei geklappt hat. Wir können z. B. prüfen, ob die Anzahl der Variablen und die Anzahl der Fälle mit den Originaldaten übereinstimmt. Mit der Funktion dim erhalten wir die Anzahl der Zeilen (erster Wert) und Spalten (zweiter Wert):
6.4
Daten speichern
> dim(daten1) [1] 10 4
Diese Angaben können wir auch separat anfordern mit den Funktionen ncol (number of columns) für die Anzahl der Spalten und nrow (number of rows) für die Anzahl der Zeilen. Die Anzahl der Zeilen entspricht in vielen Fällen der Anzahl der Versuchspersonen in den Daten, daher verwenden wir die nrow-Funktion auch, um die Stichprobengröße zu bestimmen. > ncol(daten1) [1] 4 > nrow(daten1) [1] 10
Die Variablennamen fordern wir mit den Funktionen names oder str an (s. Abschn. 5.2.3). Mit der Funktion summary (s. Abschn. 8.2.1) verschaffen wir uns einen schnellen Überblick über die wichtigsten statistischen Kennwerte und die Anzahl der fehlenden Werte für jede Variable. Mit der View-Funktion (s. Abschn. 5.2.3) öffnen wir die Rohdaten selbst. Mit der head-Funktion werden die ersten sechs Zeilen in der Konsole angezeigt.
6.4 Daten speichern Bei allen hier behandelten Funktionen zum Einlesen von Daten werden die Daten in einem Objekt gespeichert, meistens in einem Data Frame. Dieses Objekt steht aber zunächst nur im Workspace zur Verfügung. Wir wissen schon, dass der Workspace jedesmal geleert wird, wenn wir R schließen (s. Abschn. 5.4). Wenn wir die Daten nicht jedes Mal erneut einlesen möchten, sollten wir das Objekt als .RData-Datei speichern und in der nächsten Sitzung mit der load-Funktion öffnen (s. Abschn. 5.5).
69
70
6 Daten importieren
6.5
Die wichtigsten Funktionen im Überblick
Funktion
Beschreibung
read.csv()
Importiert eine csv-Datei mit Kommata als Datenfeldtrennzeichen und Punkten als Dezimaltrennzeichen
read.csv2()
Importiert eine csv-Datei mit Semikolons als Datenfeldtrennzeichen und Kommata als Dezimaltrennzeichen
read.table()
Allgemeine Funktion zum Einlesen von Textdaten
read.fwf()
Importiert Daten im festen ASCII-Format
dim()
Anzahl der Zeilen und Spalten eines Data Frames
nrow()
Anzahl der Zeilen eines Data Frames
ncol()
Anzahl der Spalten eines Data Frames
names()
Variablennamen eines Data Frames
str()
Struktur eines Data Frames
View()
Ansicht eines Data Frames im Dateneditor
head()
Daten der ersten sechs Zeilen eines Data Frames
6.6
Übungen
Im Open Science Framework (https://osf.io/) stellen viele Wissenschaftlerinnen und Wissenschaftler ihre Daten zur Verfügung. Gehen Sie auf die Startseite und klicken Sie auf »Search«. Dort können Sie nach Projekten zu verschiedenen Forschungsthemen suchen (z. B. »life satisfaction«). Suchen Sie ein Projekt zu einem Sie interessierenden Forschungsthema, das offene Daten zur Verfügung stellt. Laden Sie die Daten herunter, lesen Sie sie in R ein und speichern Sie die Daten in einer .RData-Datei.
Powered by TCPDF (www.tcpdf.org)
7.1
7
Klassische und moderne Datenaufbereitung
Datenaufbereitung
Mittlerweile haben wir die Daten zwar erfolgreich in R eingelesen, aber drauflos rechnen können wir in den meisten Fällen trotzdem noch nicht. Uns erwartet die mäßig aufregende und häufig etwas mühselige Arbeit der Datenaufbereitung. Wir sprechen zunächst über zwei grundlegende Ansätze der Datenaufbereitung: die klassische Datenaufbereitung, die weitgehend mit Funktionen aus den R-Basispaketen auskommt, und die moderne Datenaufbereitung, die Funktionen aus den tidyverse-Paketen verwendet (Abschn. 7.1). Anschließend beschäftigen wir uns mit der Aufbereitung einzelner Variablen (Abschn. 7.2). In den folgenden Abschnitten betrachten wir die Aufbereitung ganzer Data Frames: Wie kann man bestehende Data Frames reduzieren (Abschn. 7.3), wie kann man mehrere Data Frames zusammenfügen (Abschn. 7.5), sortieren (Abschn. 7.4) und wie kann man die Struktur von Data Frames verändern (Abschn. 7.6). Im abschließenden Abschnitt geht es um die fortgeschrittene Datenaufbereitung, bei der mehrere einzelnen Schritte kombiniert werden (Abschn. 7.7). Die Beispiele in diesem Kapitel beziehen sich auf die Datensätze Minidaten 1.RData (Objektname: daten1), Minidaten 2.RData (Objektname: daten2) und Minidaten 3.RData (Objektname: daten3; s. Anhang A: Datensätze). Dabei handelt es sich um kleine Datensätze mit einer geringen Zahl an Fällen und Variablen. Tipp
Die in diesem Kapitel behandelten Befehle werden im Buch immer so dargestellt, dass sie einwandfrei funktionieren, wenn man die beiden Datensätze frisch geladen und noch nicht verändert hat. Wenn Sie die Befehle parallel zum Lesen des Buchs am Computer direkt ausprobieren wollen, dann sollten Sie die Daten zu Beginn jedes Abschnitts neu laden.
7.1
Klassische und moderne Datenaufbereitung
Die meisten Befehle haben bei der Datenaufbereitung das folgende Format: > meineDaten meineDaten meineDaten % funktion(…)
Auch hier beginnt der Befehl mit dem Namen des Objekts, in dem der veränderte Data Frame gespeichert werden soll. Der Teil rechts vom Zuweisungspfeil sieht aber anders aus. Dieser Teil beginnt nicht, wie gewohnt, direkt mit einer Funktion, sondern mit dem Namen des Data Frames, der verändert werden soll. Das dahinter folgende Symbol %>% bezeichnet man als Pipe. Es kann direkt eingetippt oder mit der Tastenkombination STRG + SHIFT + M (Windows) bzw. CMD + SHIFT + M (Mac) eingefügt werden. Die Pipe kann übersetzt werden mit: Nimm das, was vor bzw. links von mir steht und mache damit das, was hinter bzw. rechts von mir steht. Der Vorteil der Pipe ist, dass man damit beliebig viele Befehle miteinander verketten kann (s. Abschn. 7.7). Wir gewöhnen uns daher diesen Aufbau direkt an, auch wenn er im Moment noch etwas seltsam wirkt.
73
74
7 Datenaufbereitung
7.2
Variablen erstellen und bearbeiten
In der Psychologie gibt es viele Fälle, in denen wir aus den vorhandenen Variablen neue Variablen erstellen müssen. Hier einige Beispiele: Eine der verwendeten Variablen ist extrem schief verteilt. Wir möchten diese Variable transformieren, um eine annähernd normalverteilte Variable zu erhalten, mit der wir besser rechnen können. Wir möchten eine Variable zentrieren oder standardisieren. Wir haben eine Skala mit 5 Items verwendet und möchten nun für jede Person den Mittelwert über diese 5 Items berechnen. Die Mittelwerte sollen in einer neuen Variablen gespeichert werden. Die Werte einer Variablen sollen umcodiert werden.
7.2.1
Neue Variablen zum Data Frame hinzufügen
Allen eben aufgeführten Fällen ist gemeinsam, dass eine Variable zu einem bereits bestehenden Data Frame hinzugefügt wird. Wir besprechen zunächst, wie man grundsätzlich im klassischen und im modernen Ansatz Variablen zu einem Data Frame hinzufügen kann. Anschließend gehen wir verschiedene Anwendungsfälle durch. Variablen hinzufügen mit den R-Basisfunktionen Neue Variablen werden einem bereits bestehenden Data Frame hinzugefügt, indem man den Zuweisungspfeil mit der Dollarzeichen-Option kombiniert. Zur Veranschaulichung betrachten wir ein Beispiel aus dem Datensatz Minidaten 1.RData. Der Name des in dieser Datei enthaltenen Data Frames ist daten1. In diesem Data Frame ist für jede Person das Alter im Jahr der Datenerhebung (2020) in der Variablen alter gespeichert. Wir möchten nun eine neue Variable anlegen, die das Geburtsjahr der Personen enthält. Dafür ziehen wir die Alterswerte vom Jahr der Datenerhebung ab: > daten1$gebjahr daten1 % mutate(gebjahr = 2020 - alter)
In den Klammern der mutate-Funktion wird der Name der neuen Variablen festgelegt und anschließend definiert, welche Werte diese Variable erhalten soll. Zwei Unterschiede zum klassischen Ansatz werden hier deutlich. Erstens verzichten wir hier ganz auf das Dollarzeichen. Zweitens verwenden wir für die Erstellung der neuen Variablen das Gleichheitszeichen = statt den Zuweisungspfeil names(daten1) [1] "id" "alter" "extra" "geschl"
Hier werden deutschsprachige Variablennamen verwendet. Wir möchten nun stattdessen englischsprachige Namen vergeben. Mit dem folgenden Befehl ändern wir alle Variablennamen auf einmal: > names(daten1) names(daten1) [1] "id" "age"
"extra" "sex"
Tipp
Bei der Wahl der Variablennamen sollten die folgenden Dinge beachtet werden: Kurz, aber verständlich (z. B. geschl oder sex für die Variable Geschlecht) Stellen die Variablen mehrere Items einer Skala dar, kann man diese Variablen durchnummerieren (z. B. neuro_1, neuro_2, neuro_3 etc. für die verschiedenen Items einer Neurotizismus-Skala). Dabei ist es sinnvoll, die Nummer mit einem Symbol wie . oder _ vom Rest des Variablennamens zu trennen (s. Abschn. 7.6). Besteht ein Variablenname aus mehreren Wörtern, sollte man diese nicht mit einem Leerzeichen trennen, sondern mit Symbolen wie . oder _ . Es ist auch möglich, einzelne Variablennamen gezielt zu ändern. Dafür müssen wir die Position der Variable im Data Frame erkennen und diese Position in eckigen Klammern angeben (s. Abschn. 5.3.2). Mit dem folgenden Befehl erhält man bspw. den Namen der zweiten und vierten Variablen des (neu geladenen) Data Frames daten1.
7.2
Variablen erstellen und bearbeiten
> names(daten1)[c(2,4)] [1] "alter" "geschl"
Diese Variablennamen verändern wir mit dem folgenden Befehl: > names(daten1)[c(2,4)] names(daten1) [1] "id" "age"
"extra" "sex"
Diese Vorgehensweise hat allerdings mindestens zwei Nachteile. Erstens können »echte« Datensätze schon mal hunderte Variablen enthalten, was es mühsam macht, die Position einer bestimmten Variablen zu finden. Zweitens kann sich diese Position auch ändern, wenn wir z. B. die Daten erneut einlesen und dabei etwas an der Anzahl der Variablen verändern. Diese Probleme treten nicht auf, wenn wir stattdessen die nun folgende moderne Variante anwenden. Variablen umbenennen mit tidyverse In tidyverse verwenden wir zum Umbenennen von Variablen die rename-Funktion aus dem dplyr-Paket. In dieser Funktion legen wir für jede umzubenennende Variable ein eigenes Argument an. Vorne (links) steht der neue Variablennamen, hinten (rechts) der alte Variablenname. Wir können beliebig viele Variablen in einem Befehl umbenennen. Variablen, die hier nicht aufgeführt werden, behalten ihren ursprünglichen Namen. Mit dem folgenden Befehl nennen wir die Variablen alter und geschl in age und sex um: > daten1 % rename( age = alter, sex = geschl)
7.2.3
Variablentyp ändern
Die meisten Programme für die Datenerhebung generieren ausschließlich numerische Daten. Diese Daten werden beim Einlesen als numerische Vektoren angelegt. Das ist aber nicht immer wünschenswert. Wie in Kapitel 5 besprochen, ist es sinnvoll und manchmal sogar notwendig, nominalskalierte Variablen als Faktoren zu speichern. Im (neu geladenen) Data Frame daten1 ist eine nominalskalierte Variable enthalten: geschl. Diese Variable ist aber aktuell als numerischer Vektor definiert. Das
77
78
7 Datenaufbereitung
können wir z. B. sehen, wenn wir die class-Funktion auf diese Variable anwenden oder die str-Funktion auf den ganzen Data Frame (s. Abschn. 5.2). Wir müssen diese Variable also in einen Faktor konvertieren. Außerdem schauen wir uns an, wie man Faktoren in Vektoren konvertiert. Variablentyp ändern mit den R-Basisfunktionen Um einen Vektor in einen Faktor zu konvertieren, verwenden wir die factor-Funktion. > daten1$geschl.f levels(daten1$geschl.f) [1] "0" "1"
Die Ausprägungen sind hier 0 und 1. Die Werte der ursprünglichen Variablen werden hier also direkt übernommen. Wir wissen aber nicht, welche Zahlen für welche Merkmalsausprägung stehen. Daher ist es sinnvoll, Wertelabels zu definieren. Wir modifizieren den Befehl folgendermaßen: > daten1$geschl.f levels(daten1$geschl.f) [1] "m" "w"
Die factor-Funktion ist nun um einige Argumente erweitert worden. Im Argument levels = c(0, 1) wird noch einmal explizit aufgeführt, welche Levels bzw. Ausprägungen vorkommen. Anschließend wird durch das Argument labels = c("w", "m") festgelegt, welche Wertelabels den einzelnen Werten zugeordnet werden. Das erste Wertelabel bezieht sich dabei auf den ersten Wert, der vorher bei levels aufgeführt wurde; das zweite Wertelabel bezieht sich auf den zweiten Wert. Im Data Frame werden nun die einzelnen Ausprägungen der Variable Geschlecht mit den oben definierten Wertelabels dargestellt (s. Abb. 7.1).
7.2
Variablen erstellen und bearbeiten
Abbildung 7.1 Data Frame daten1 nach Hinzufügen eines Faktors mit Wertelabels Tipp
Wie schon beim Benennen von Objekten und Variablen sollten Sie auch bei den Wertelabels auf Sonderzeichen wie z. B. Umlaute verzichten, um möglichen Kompatibilitätsproblemen vorzubeugen. Statt »männlich« schreiben wir also lieber »maennlich«, »male« oder einfach »m«. Manchmal ist es notwendig, Faktoren in Vektoren zu konvertieren, z. B. wenn man die Daten in eine rein numerische Textdatei exportieren möchte (s. Abschn. 22.1). Wir betrachten nun wieder die Variable geschl.f, die wir im vorangegangenen Abschnitt in einen Faktor konvertiert haben. Bevor wir diesen Faktor konvertieren, sollten wir uns noch einmal die Faktorstufen mit den dazugehörigen Wertelabels ausgeben lassen: > levels(daten1$geschl.f) [1] "m" "w"
Wir sehen, dass der Faktor geschl.f die Ausprägungen m (männlich) und w (weiblich) hat. Es ist wichtig, dass wir uns merken, dass die Ausprägung m zuerst aufgeführt wird. Jetzt konvertieren wir den Faktor. Wir verwenden dafür die as.numeric-Funktion und geben der konvertierten Variablen den Namen geschl.num: > daten1$geschl.num class(daten1$geschl.num) [1] "numeric"
Mit der head-Funktion erhalten wir den »Kopf« des Data Frames, d. h., die obersten sechs Zeilen. Wie man sieht, sind jetzt alle Werte der Variablen geschl.num numerisch mit den Ausprägungen 1 und 2: > head(daten1) id alter extra geschl geschl.f geschl.num 1 1 19 3.5 0 m 1 2 2 21 1.2 0 m 1 3 3 25 4.3 1 w 2 4 4 20 3.1 1 w 2 5 5 NA 2.7 0 m 1 6 6 18 2.5 0 m 1
Durch die Konvertierung sind also die Wertelabels verloren gegangen. Wofür stehen hier dann 1 und 2? Oben haben wir uns die Faktorstufen der Ausgangsvariablen ausgeben lassen. Die Ausprägung m wurde als erstes aufgeführt, die Faktorstufe w als zweites. Die Werte in der konvertierten Variablen wurden genau in dieser Reihenfolge vergeben: Die erste Ausprägung erhält die 1, die zweite Ausprägung die 2 usw. In unserem Fall steht also 1 für männlich und 2 für weiblich. Variablentyp ändern mit tidyverse Auch bei der Arbeit mit tidyverse verwenden wir die Funktion factor zum Konvertieren eines Vektors in einen Faktor und die Funktion as.numeric zum Konvertieren eines Faktors in einen Vektor. Diese Funktionen werden allerdings in die mutate-Funktion eingebettet. Im folgenden Befehl konvertieren wir noch einmal die Variable geschl in einen neuen Faktor mit dem Variablennamen geschl.f: > daten1 % mutate( geschl.f = factor(geschl, levels = c(0, 1), labels = c("m", "w") ))
Ein Vorteil der mutate-Funktion ist, dass mehrere Variablen in einem Rutsch konvertiert werden können. Wenn wir also mehrere Variablen konvertieren müssten, könnten wir diese hier einfach hintereinander in den mutate-Befehl hineinschreiben.
7.2
Variablen erstellen und bearbeiten
7.2.4 Variablen zentrieren und standardisieren Das Zentrieren oder Standardisieren von Variablen ist für viele statistische Analysen wichtig. Um eine Variable zu zentrieren, zieht man von jedem einzelnen Wert den Mittelwert der Variablen ab. Die zentrierte Variable hat dann den Mittelwert 0. Um eine Variable zu standardisieren, teilt man zusätzlich noch durch die Standardabweichung der Variablen. Die standardisierte Variable hat dann den Mittelwert 0 und die Standardabweichung 1. Die einzelnen Werte der standardisierten Variablen nennt man auch z-Werte. Um Variablen zu zentrieren oder zu standardisieren, verwendet man in R die scale-Funktion. Variablen zentrieren und standardisieren mit den R-Basisfunktionen Im folgenden Beispiel standardisieren wir die Variable alter und speichern die standardisierten Werte in der neuen Variablen alter.z ab: > daten1$alter.z daten1$alter.cen daten1 % mutate( alter.z = scale(alter), alter.cen = scale(alter, scale = FALSE))
7.2.5
Variablen umpolen
In den meisten psychologischen Fragebögen werden bewusst sowohl positiv als auch negativ formulierte Items verwendet. Bevor man diese zu einem Skalenwert zusammenfasst, muss man daher zunächst dafür sorgen, dass bei allen Items hohe Werte eine hohe Ausprägung des gemessenen Merkmals widerspiegeln. Dazu polt man entweder alle negativ formulierten Items oder alle positiv formulierten Items um.
81
82
7 Datenaufbereitung
In diesem Beispiel verwenden wir den Data Frame daten2 aus der Datei Minidaten 2.RData. Dieser Data Frame enthält u. a. die Variablen neuro_1, neuro_2 und neuro_3, wobei es es sich um drei Items einer Skala zur Messung von Neurotizismus handelt. Alle Items wurden auf einer Antwortskala von 1 bis 5 gemessen. Das Item neuro_2 wurde negativ formuliert und muss daher umgepolt werden. Am schnellsten kann man Items mit der folgenden Formel umpolen: neu daten2$neuro_2r daten2 % mutate(neuro_2r = 6 - neuro_2)
Um zu überprüfen, ob das Umpolen geklappt hat, erstellen wir eine Kontingenztabelle der alten und der neuen Variablen (s. Abschn. 9.1). Hier können wir z. B. erkennen, dass die Personen, die auf der alten Variablen den Wert 1 hatten (1. Zeile), auf der neuen Variablen den Wert 5 erhalten haben (5. Spalte). > table(daten2$neuro_2, daten2$neuro_2r)
7.2
1 2 3 4 5
1 0 0 0 0 1
2 0 0 0 1 0
3 0 0 3 0 0
4 0 1 0 0 0
Variablen erstellen und bearbeiten
5 1 0 0 0 0
7.2.6 Variablen umcodieren Im vorherigen Abschnitt haben wir besprochen, wie man Variablen umpolt. Dabei handelt es sich um eine spezielle Art von Umcodierung. Bei der Umcodierung werden den ursprünglichen Werten einer Variablen neue Werte zugeordnet. Das Umpolen ist wohl die am häufigsten eingesetzte Art der Umcodierung, aber es gibt auch andere Varianten. Zum Beispiel kann es vorkommen, dass man nur einen bestimmten Wert umcodieren möchte und alle anderen Werte intakt lässt. Oder man möchte bestimmte Wertebereich zu einem Wert zusammenfassen. Diese Fälle lassen sich nicht in einer einfachen Formel wie die für die Umpolung ausdrücken. In diesem Abschnitt werden Funktionen vorgestellt, die solche flexiblen und komplexen Umcodierungen ermöglichen. Variablen umcodieren mit der which-Funktion Die which-Funktion gibt die Position von Werten aus, auf die eine bestimmte Bedingung zutrifft, also alle Werte, für die das Ergebnis einer logischen Abfrage (s. Abschn. 4.2) TRUE ist. Diese Funktion kann man bspw. nutzen, um alle Zeilen bzw. Personen anzufordern, die auf einer bestimmten Variablen einen bestimmten Wert haben. Der gewünschte Wert wird bei numerischen Variablen als Zahl angegeben und bei Textvariablen und Faktoren als Text in Anführungszeichen. Mit dem folgenden Befehl erfahren wir, welche Personen auf der Variablen neuro_1 einen Wert größer oder gleich 4 haben: > which(daten2$neuro_1 >= 4) [1] 1 6
Die ausgegebenen Werte geben die Zeilen an, in denen die Daten dieser Personen gespeichert sind. Wir können diese Ausgabe daher in der Index-Funktion verwenden. Zur Erinnerung: Mit der Index-Funktion werden gezielt bestimmte Zeilen und/oder Spalten ausgewählt (s. Abschn. 5.3.2). Mit dem folgenden Befehl fordern wir die Werte der Variablen neuro_1 für die Zeilen 1 und 6 aus dem Data Frame daten2 an. Beide Werte sind größer als oder gleich 4 – wie gewünscht:
83
84
7 Datenaufbereitung > daten2$neuro_1[which(daten2$neuro_1 >= 4)] [1] 4 5
Jetzt kommt der Trick: Wir können nun die hier ausgewählten Werte durch einen beliebigen anderen Wert ersetzen, indem wir hinter den oben gezeigten Befehl den Zuweisungspfeil und dann den neuen Wert aufführen. Hier legen wir fest, dass beide Werte mit 4 codiert werden sollen: > daten2$neuro_1[which(daten2$neuro_1 >= 4)] daten2$neuro_1r[which(daten2$neuro_1 = 3)] daten2$neuro_1r is.na(daten2$neuro_1) [1] FALSE FALSE FALSE TRUE FALSE FALSE FALSE
Diese logische Bedingung setzen wir nun wie gewohnt in die which-Funktion oder in die ifelse-Funktion ein. Tipp
Die Funktion !is.na gibt uns genau das gegenteilige Ergebnis der is.na-Funktion aus. Diese Funktion können wir also einsetzen, um alle gültigen (nicht fehlenden) Werte zu identifizieren.
7.2.7
Skalenwerte berechnen
In den meisten psychologischen Skalen wird das psychologische Merkmal mit mehreren Items gemessen, um die Reliabilität der Skala zu erhöhen. Bei solchen Skalen interessieren uns in der Regel nicht die Antworten auf einzelne Items, sondern wir möchten für jede Person nur einen einzigen Wert haben, der die Ausprägung dieser Person auf dem psychologischen Merkmal widerspiegelt. Diesen Wert bezeichnet man auch als Skalenwert. Skalenwerte berechnet man, indem man für jede Person die Werte aus mehreren Items (in R: Variablen) in einem einzigen Wert zusammenfasst, z. B., indem man für jede Person die Werte auf den einzelnen Items mittelt oder aufaddiert. Möglicherweise muss man vorher einzelne Variablen umpolen (s. Abschn. 7.2.5). Im Data Frame daten2 aus der Datei Minidaten 2.RData wurden die Persönlichkeitsdimensionen Neurotizismus und Extraversion mit jeweils drei Items erfasst (neuro_1 bis neuro_3 bzw. extra_1 bis extra_3). Wir möchten nun für jede Person den Skalenwert für Neurotizismus berechnen. Die Items neuro_1 und neuro_3 wurden so formuliert, dass hohe Werte auf diesen Items eine hohe Ausprägung im Neurotizismus widerspiegeln. Das Item neuro_2 wurde jedoch so formuliert, dass
87
88
7 Datenaufbereitung
hohe Werte auf dem Item eine niedrige Ausprägung im Neurotizismus widerspiegeln. Dieses Item haben wir daher vorab umgepolt und in der Variablen neuro_2r gespeichert (s. Abschn. 7.2.5). Skalenwerte berechen mit den R-Basisfunktionen Mit den R-Basisfunktionen können wir den Skalenwert entweder direkt über eine Formel berechnen oder spezielle Funktionen verwenden. Im folgenden Beispiel berechnen wir den Skalenwert als Mittelwert über alle Items mithilfe der Formel. Die neue Variable erhält den Namen neuro: > daten2$neuro daten2$neuro daten2$neuro daten2 % mutate( neuro.mean = (neuro_1 + neuro_2r + neuro_3) / 3, neuro.sum = rowSums(data.frame(neuro_1, neuro_2r, neuro_3)) )
Die Variable neuro.mean gibt den zeilenweisen Mittelwert über alle Items wieder und wurde über die Formel bestimmt. Die Variable neuro.sum gibt den zeilenweisen Summenwert über alle Items wieder und wurde über die Funktion rowSums bestimmt.
7.3
Data Frames reduzieren
Im vorherigen Abschnitt haben wir besprochen, wie wir unseren Data Frame erweitern, indem wir neue Variable hinzufügen. In diesem Abschnitt machen wir das Gegenteil: Wir stutzen den Data Frame auf die Zeilen und Spalten zurecht, die wir benötigen.
89
90
7 Datenaufbereitung
7.3.1
Variablen auswählen
Für viele statistische Analysen ist es sinnvoll, den Data Frame auf die Variablen zu reduzieren, die für diese Analyse relevant sind. Wie immer gibt es auch wieder verschiedene Möglichkeiten, dies zu tun. Wir besprechen die R-Basisfunktionen data.frame und die Index-Funktion sowie die dplyr-Funktion select. In allen Beispielen wählen wir aus dem Data Frame daten2 die Variablen extra_1, extra_2 und extra_3 aus. Auswahl von Variablen über die data.frame-Funktion Mit der data.frame-Funktion (s. Abschn. 5.2.3) erstellen wir neue Data Frames. Diese Funktion kann sowohl auf Variablen (wie hier) als auch auf Data Frames angewandt werden. Wichtig ist dabei, dass die Anzahl der Werte der Variablen bzw. die Anzahl der Zeilen der Data Frames identisch sein muss. Um die Variablen extra_1 bis extra_3 auszuwählen, geben wir den folgenden Befehl ein: > auswahl str(auswahl) 'data.frame': 7 obs. of $ daten2.extra_1: int $ daten2.extra_2: int $ daten2.extra_3: int
3 2 4 3
variables: 2 3 1 5 2 1 2 1 2 5 5 3 2 3 5 1 2 2
Wie man in dieser Ausgabe sehen kann, wurden die Variablen umbenannt in daten2.extra_1 bis daten2.extra_3. Der Name des ursprünglichen Data Frames wurde also mit den Variablennamen verbunden. Wenn man dies nicht möchte, kann man innerhalb der data.frame-Funktion neue Variablennamen definieren: > auswahl names(daten2) [1] "id" "neuro_1" "neuro_2" "neuro_3" "extra_1" [6] "extra_2" "extra_3" "wohnort"
Die Variablen extra_1 bis extra_3 stehen in der fünften, sechsten und siebten Spalte des Data Frames. Wir wählen sie daher wie folgt aus: > auswahl auswahl auswahl % select(extra_1, extra_2, extra_3)
Was besonders praktisch ist: Für die select-Funktion gibt es eine Reihe von Hilfsfunktionen, mit denen man die Variablen nach bestimmten Kriterien auswählen kann. Zum Beispiel kann man mit starts_with alle Variablen auswählen, die mit denselben Buchstaben beginnen. Für unser Beispiel würde das dann so aussehen: > auswahl % select(contains("extra"))
91
92
7 Datenaufbereitung
Andere Hilfsfunktionen sind ends_with (wählt alle Variablen aus, deren Namen mit bestimmten Zeichen aufhören) und contains (wählt alle Variablen aus, deren Namen eine bestimmte Zeichenfolge enthalten, egal an welcher Stelle). Weitere Hilfsfunktionen werden auf dem Cheatsheet für dplyr aufgeführt (s. Abschn. 3.3.3).
7.3.2
Fälle auswählen
Nicht immer sollen alle Fälle in unseren Daten in die Analysen eingehen. Es kann z. B. vorkommen, dass wir nur bestimmte Altersgruppen oder nur Personen einer bestimmten experimentellen Bedingung untersuchen möchten. In diesem Fall wählt man eine Untergruppe aus bzw. filtert die Fälle nach bestimmten Eigenschaften. Im folgenden Beispiel verwenden wir den Data Frame daten1 und wählen alle Personen aus, die mindestens 20 Jahre alt sind. Auch hier gibt es wieder verschiedene Wege zum Ziel. Wir besprechen zunächst die Auswahl von Fällen über die R-Basisfunktionen subset und die Index-Funktion und schauen uns anschließend die dplyr-Funktion filter an. Auswahl von Fällen über die subset-Funktion Eine bequeme Funktion für die Auswahl von Untergruppen ist die subset-Funktion. Mit dem folgenden Befehl wählen wir alle Personen mit einem Alter von mindestens 20 Jahren aus: > sub = 20)
Die subset-Funktion hat hier zwei Argumente: Zunächst wird der Name der Ausgangsdaten genannt, hier also daten1. Im anschließenden subset-Argument wird mit einer logischen Bedingung festgelegt, welche Kriterien zutreffen müssen, damit die Fälle ausgewählt werden. Logische Bedingungen haben wir schon in den Abschnitten 4.2 und 7.2.6 kennengelernt. Auch hier können wir wieder verschiedene logische Operatoren verwenden und mehrere logische Bedingungen miteinander verknüpfen. Außerdem können wir die logische Bedingung auch komplett negieren – das bedeutet: Wir wollen genau das gegenteilige Ergebnis erhalten. Im folgenden Befehl wählen wir alle Fälle aus, die nicht jünger als 20 Jahre sind – dieser Befehl wählt also exakt dieselben Personen aus wie die Variante oben: > sub which(daten1$alter >= 20) [1] 2 3 4 8 9 10
Diese Werte geben wir jetzt an der ersten Stelle der Index-Funktion an und wählen damit alle uns interessierenden Zeilen aus: > sub = 20), ]
Auch hier können wir wieder negierende logische Bedingungen definieren. Mit dem folgenden Befehl werden alle Personen ausgeschlossen, die jünger als 20 Jahre sind. Dazu setzen wir ein Minus vor die which-Funktion: > sub sub % dplyr::filter(alter >= 20)
Auch hier können wir die logische Bedingung wieder flexibel erweitern und mehrere logische Bedingungen verknüpfen, wie wir es in den Abschnitten 4.2 und 7.2.6 kennengelernt haben.
93
94
7 Datenaufbereitung
7.3.3
Zeilen mit fehlenden Werten entfernen
Für einige Analysen ist es notwendig, dass die Daten keine fehlenden Werte enthalten. Dies gilt z. B. für die hierarchische Regressionsanalyse (Kap. 15). In solchen Fällen erstellt man einen neuen Data Frame, aus dem die Fälle mit fehlenden Werten entfernt wurden. Fehlende Werte entfernen mit den R-Basisfunktionen Mit der R-Basisfunktion na.omit werden alle Fälle mit fehlenden Werten aus einem Data Frame entfernt. Die Abkürzung na steht in R für not available und wird für fehlende Werte verwendet. Im folgenden Beispiel wenden wir diese Funktion auf den Data Frame daten1 an und speichern das Ergebnis in dem neuen Data Frame daten1_ohna (ohna steht hier für »ohne NAs«). > daten1_ohna nrow(daten1) [1] 10 > nrow(daten1_ohna) [1] 8
Eine Besonderheit der na.omit-Funktion ist, dass alle Fälle entfernt werden, die auf irgendeiner Variablen im Data Frame fehlende Werte haben. Das ist in vielen Fällen übertrieben, denn meistens möchten wir nicht alle Personen mit irgendwelchen fehlenden Werten ausschließen (was in echten Daten auf fast alle Fälle zutrifft), sondern nur die, die auf den uns interessierenden Variablen fehlende Werte haben. Um das zu vermeiden, speichern wir zunächst die Variablen, die wir gerade benötigen, in einem neuen Data Frame (s. Abschn. 7.3.1) und wenden anschließend die na.omitFunktion auf den neuen Data Frame an. Fehlende Werte mit tidyverse In tidyverse kann man fehlende Werte mit der drop_na-Funktion entfernen. Wendet man diese Funktion auf den gesamten Data Frame an, werden wie bei der na.omit-Funktion alle Personen entfernt, die auf irgendeiner Variablen fehlende Werte haben:
7.4
Data Frames sortieren
> daten1_ohna daten1_ohna.2 % drop_na(extra)
7.4 Data Frames sortieren Für die meisten statistischen Verfahren ist uns egal, in welcher Reihenfolge die Daten im Data Frame erscheinen. Manchmal ist es aber nützlich oder wichtig, die Daten nach bestimmten Kriterien zu sortieren. Data Frames sortieren mit den R-Basisfunktionen Mit den R-Basisfunktionen kann man die Zeilen in Data Frames nach bestimmten Variablen sortieren, indem man die order-Funktion mit der Index-Funktion kombiniert. Die order-Funktion wird auf die Variable angewandt, die man sortieren möchte. Hier sortieren wir den Data Frame daten1 nach den Ausprägungen der Variablen alter: > order(daten1$alter) [1] 6 1 7 4 8 2 10
9
3
5
Achtung: Die Zahlen in der Ausgabe sind nicht die sortierten Werte der Variablen alter. Das sehen wir schon daran, dass in diesem Beispiel die Zahlen viel zu klein sind – das Alter in diesem Data Frame lag ja zwischen 18 und 25 Jahren. Was also haben diese Zahlen zu bedeuten? Sie geben die Reihenfolge der Zeilen an, die sich durch die Sortierung ergeben würde. Der Wert 6 wird als erstes aufgeführt. Die Person mit dem kleinsten Wert auf der Variablen alter ist also in Zeile 6 zu finden. Als nächstes kommt der Wert 1, d. h., die nächstjüngste Person findet sich in Zeile 1. Die älteste Person finden wir in Zeile 5, da der Wert 5 ganz am Ende aufgeführt wird. Technisch ausgedrückt erzeugt die order-Funktion eine bestimmte Art der Permutation, d. h., die einzelnen Werte werden nach einem bestimmten Schema durchgewürfelt (permutiert).
95
96
7 Datenaufbereitung
Diese Ausgabe können wir nun in die Index-Funktion einsetzen, um den Data Frame zu sortieren. Dazu fügen wir den Befehl von oben an der ersten Stelle innerhalb der eckigen Klammern ein: > daten1[order(daten1$alter), ] id alter extra geschl 6 6 18 2.5 0 1 1 19 3.5 0 7 7 19 2.1 1 4 4 20 3.1 1 8 8 20 4.1 0 2 2 21 1.2 0 10 10 21 2.9 1 9 9 22 NA 1 3 3 25 4.3 1 5 5 NA 2.7 0
Hiermit erhalten wir einen Data Frame, in dem die Fälle bzw. Zeilen aufsteigend nach dem Alter sortiert sind. Wenn wir diesen Data Frame dauerhaft zur Verfügung haben möchten, müssen wir ihn als neues Objekt speichern. Die order-Funktion lässt sich erweitern. Mit dem zusätzlichen Argument decreasing = TRUE werden die Werte absteigend (d. h., vom höchsten zum niedrigsten Wert) sortiert. Wenn wir nach mehreren Variablen sortieren möchten, geben wir die Variablen hintereinander in die order-Funktion ein. Es wird dann als erstes nach der an erster Stelle aufgeführten Variablen sortiert, anschließend nach der an zweiter Stelle aufgeführten Variablen, usw. Data Frames sortieren mit tidyverse In tidyverse verwenden wir die arrange-Funktion aus dem dplyr-Paket zum Sortieren eines Data Frames. Die Variable, nach der wir sortieren wollen, wird in der arrange-Funktion aufgeführt: > daten1 %>% arrange(alter)
Auch hier ist die Standardeinstellung, dass die Werte aufsteigend, d. h., vom kleinsten zum größten Wert, sortiert werden. Um das zu ändern, wird die desc-Funktion auf die Variable angewandt: > daten1 %>% arrange(desc(alter))
7.5
Data Frames zusammenfügen
Möchten wir nach mehreren Variablen sortieren, listen wir diese hintereinander in der arrange-Funktion auf. Die desc-Funktion kann auf jede Variable separat angewandt werden. Im folgenden Beispiel sortieren wir erst aufsteigend nach Alter und anschließend innerhalb jeder Altersgruppe absteigend nach Extraversion: > daten1 %>% arrange(alter, desc(extra)) id alter extra geschl 1 6 18 2.5 0 2 1 19 3.5 0 3 7 19 2.1 1 4 8 20 4.1 0 5 4 20 3.1 1 6 10 21 2.9 1 7 2 21 1.2 0 8 9 22 NA 1 9 3 25 4.3 1 10 5 NA 2.7 0
7.5
Data Frames zusammenfügen
Häufig sind die Daten einer Studie zunächst in unterschiedlichen Data Frames abgespeichert und müssen später in einem einzigen Data Frame zusammengefügt werden. Dabei werden zwei Fälle unterschieden: Die Data Frames enthalten (mehr oder weniger) dieselben Variablen, aber unterschiedliche Personen bzw. Fälle (Abschn. 7.5.1). Die Data Frames enthalten (mehr oder weniger) dieselben Fälle, aber unterschiedliche Variablen. Beide Data Frames enthalten eine ID-Variable, über die die Fälle einander eindeutig zugeordnet werden können (Abschn. 7.5.2).
7.5.1
Fälle zusammenfügen
Wir möchten zwei Data Frames zusammenfügen, die dieselben Variablen, aber unterschiedliche Personen enthalten: den Data Frame daten1 aus der Datei Minidaten 1.RData und den Data Frame daten3 aus der Datei Minidaten 3.RData. Damit das klappt, müssen die Variablennamen in beiden Data Frames übereinstimmen. Wir dürfen z. B. nicht für die Variable Extraversion in dem einen Data Frame den Namen extra vergeben und in dem anderen Data Frame den Namen eXtra. R würde diese Variablen als unterschiedliche Variable interpretieren und daher nicht in einer einzigen Spalte zusammenfügen. Möglicherweise muss man daher
97
98
7 Datenaufbereitung
die Variablennamen zunächst vereinheitlichen, indem man sie in einem der Data Frames umbenennt (s. Abschn. 7.2.2). Die Data Frames daten1 und daten3 enthalten bereits dieselben Variablennamen. Fälle zusammenfügen mit den R-Basisfunktionen Wir fügen die beiden Data Frames mit der rbind-Funktion (s. Abschn. 5.2.4) zusammen und speichern das Objekt unter dem Namen alle_vpn: > alle_vpn alle_vpn bind_rows(daten1[,-2], daten3[,-3]) id extra geschl alter 1 1 3.5 0 NA 2 2 1.2 0 NA 3 3 4.3 1 NA 4 4 3.1 1 NA 5 5 2.7 0 NA 6 6 2.5 0 NA 7 7 2.1 1 NA 8 8 4.1 0 NA 9 9 NA 1 NA
7.5 10 10 11 100 12 101 13 102
2.9 NA NA NA
1 0 0 1
Data Frames zusammenfügen
NA 24 19 25
Die ersten 10 Fälle stammen aus daten1; die letzten 3 Fälle stammen aus daten3. Die Variablen id und geschl waren in beiden Data Frames enthalten und wurden korrekt in jeweils einer Spalte zusammengefügt. Die Variable extra war aber nur im ersten Data Frame enthalten, deshalb erhalten alle Fälle aus dem zweiten Data Frame hier fehlende Werte. Genau umgekehrt ist es für die Variable alter. Diese Variable war nur im zweiten Data Frame enthalten, daher erhalten alle Fälle aus dem ersten Data Frame hier fehlende Werte.
7.5.2
Variablen zusammenfügen
Wir möchten nun zwei Data Frames zusammenfügen, die dieselben Personen enthalten, aber nicht dieselben Variablen. So etwas kommt bspw. bei Längsschnittstudien vor, wenn man die Daten von verschiedenen Messzeitpunkten in unterschiedlichen Dateien gespeichert hat. Damit die Daten aus den beiden Data Frames eindeutig den richtigen Personen zugeordnet werden können, muss jede Person eine Identifikationsnummer (ID) haben. Jede ID darf nur ein einziges Mal vergeben sein, damit es nicht zu Verwechslungen kommen kann. Die ID wird in einer eigenen Variablen gespeichert und kommt in beiden Data Frames vor. Wir fügen jetzt die Data Frames daten1 und daten2 zusammen. In beiden Data Frames werden die Personen über die Variable id identifiziert. Der Data Frame daten1 enthält die Daten der Personen mit den IDs 1 bis 10. Der Data Frame daten2 enthält die Daten der Personen mit den IDs 1, 2, 4, 5, 10, 12 und 13. Das bedeutet, einige Personen (mit den IDs 1, 2, 4, 5, 10) kommen in beiden Data Frames vor, manche Personen (mit den IDs 3, 6, 7, 8, 9) kommen nur in daten1 vor, und manche Personen (mit den IDs 12 und 13) kommen nur in daten2 vor. Diese Information ist wichtig, da wir entscheiden müssen, welche Personen in dem neu zusammengefügten Data Frame enthalten sein sollen. Es gibt vier Möglichkeiten, welche Personen im neuen Data Frame landen: alle nur diejenigen, die in beiden Data Frames vertreten sind nur diejenigen, die in daten1 vertreten sind, unabhängig davon, ob sie in daten2 vorkommen oder nicht nur diejenigen, die in daten2 vertreten sind, unabhängig davon, ob sie in daten1 vorkommen oder nicht
99
100
7 Datenaufbereitung
Variablen zusammenfügen mit den R-Basisfunktionen Zum Zusammenfügen von Variablen verwenden wir die merge-Funktion. Für unser Beispiel führen wir zunächst den folgenden Befehl aus: > beide.min beide.min$id [1] 1 2 4 5 10
Der neue Data Frame enthält nur die Fälle, die in beiden Data Frames vorkamen. Hier wird also ganz streng jeder Fall entfernt, der nicht in beiden Data Frames vorhanden ist. Nun möchten wir einen Data Frame erstellen, der alle Fälle enthält, egal ob sie in beiden oder nur in einem der Ausgangsdaten enthalten waren. Dazu ergänzen wir in der merge-Funktion das Argument all = TRUE: > beide.max beide.max$id [1] 1 2 3 4
5
6
7
8
9 10 12 13
Wir können das Argument so verändern, dass nur die Personen im neuen Data Frame vorkommen, die in daten1 enthalten waren – unabhängig davon, ob sie in daten2 vertreten sind oder nicht. Das erreichen wir mit dem Argument all.x = TRUE. Das kleine .x bezieht sich dabei auf den Data Frame, der in dem Befehl als erstes genannt wird. Möchten wir stattdessen alle Personen behalten, die in daten2 vorkommen, geben wir stattdessen das Argument all.y = TRUE ein.
7.6
Data Frames umstrukturieren
Variablen zusammenfügen mit tidyverse In tidyverse gibt es für jede der vier Möglichkeiten des Zusammenfügens eine eigene Funktion. Mit der Funktion inner_join werden die Data Frames so zusammengefügt, dass nur die Personen bleiben, die in beiden Data Frames vorkamen. Die Funktion ist ansonsten genauso aufgebaut wie die merge-Funktion: > beide.min daten2 id neuro_1 neuro_2 neuro_3 extra_1 extra_2 extra_3 wohnort 1 1 4 3 4 2 4 3 Land 2 4 2 3 2 2 2 2 Stadt 3 2 1 1 4 3 1 3 Land 4 5 NA 2 4 1 2 5 Land 5 10 3 3 2 5 5 1 Stadt 6 12 5 5 1 2 5 2 Land 7 13 1 4 2 1 3 2 Stadt
Dieser Data Frame enthält zwei messwiederholte Variablen, neuro und extra, die jeweils dreimal gemessen wurden. Die Werte dieser Variablen sollen im Long-Format jeweils in derselben Spalte enthalten sein. Außerdem enthält dieser Data Frame zwei Variablen, die nicht wiederholt gemessen wurden: id und wohnort. Diese Variablen
7.6
Data Frames umstrukturieren
sollen natürlich auch im neuen Data Frame behalten werden, allerdings müssen wir sie anders behandeln als die messwiederholten Variablen. Schritt 1: Umstrukturierung ins Ultralong-Format Die Umstrukturierung ins Long-Format erfolgt in zwei Schritten. Im ersten Schritt werden die Daten ins sog. Ultralong-Format transformiert: > ultralang % pivot_longer( cols = -c(id, wohnort), names_to = "varname", values_to = "wert") > ultralang # A tibble: 42 x 4 id wohnort varname wert
1 1 Land neuro_1 4 2 1 Land neuro_2 3 3 1 Land neuro_3 4 4 1 Land extra_1 2 5 1 Land extra_2 4 6 1 Land extra_3 3 7 4 Stadt neuro_1 2 8 4 Stadt neuro_2 3 9 4 Stadt neuro_3 2 10 4 Stadt extra_1 2 # ... with 32 more rows
Wir schauen uns zuerst an, was hierbei rausgekommen ist, und betrachten dann die Funktion genauer. Der neue Data Frame (genauer: ein Tibble) ultralang hat in diesem Beispiel nur vier Variablen. Die ersten beiden Variablen sind die nicht-messwiederholten Variablen id und wohnort. Wir können an dem Ausschnitt der ersten zehn Zeilen dieses Data Frames erkennen, dass die Person mit der ID 1 in insgesamt sechs Zeilen vorkommt. Der Wert auf der Variablen wohnort ist für diese Person immer gleich. Das sollte so sein, denn diese Variable wurde ja nur ein einziges Mal gemessen und kann sich daher nicht innerhalb dieser Person unterscheiden. Die dritte Variable heißt hier varname (kurz für Variablenname) und enthält die Variablennamen der messwiederholten Variablen. In der vierten Variablen mit dem Namen wert sind die dazugehörigen Werte der Variablen enthalten. Beispielsweise steht in der ersten Zeile der Wert 4. Dies ist also die Ausprägung von Person 1 auf der Variablen neuro_1, also der Neurotizismuswert dieser Person zum ersten Messzeitpunkt.
103
104
7 Datenaufbereitung
Was also ist das Ultralong-Format? In diesem Format werden alle messwiederholten Variablen in einigen wenigen Variablen repräsentiert, hier zwei. Eine Variable gibt den Variablennamen an, der Informationen zum psychologischen Merkmal und zum Messzeitpunkt enthält; die andere Variable gibt die jeweilige Ausprägung auf dieser Variablen an. Die Anzahl der Zeilen pro Person entspricht der Anzahl der Messzeitpunkte × Anzahl der messwiederholten Variablen, hier also 3 Messzeitpunkte × 2 messwiederholte Variablen = 6 Zeilen pro Person. Wir kehren jetzt zurück zu dem Befehl, mit dem wir die Daten ins Ultralong-Format umstrukturiert haben. Damit wir nicht so viel blättern müssen, ist er hier noch einmal abgedruckt: > ultralang % pivot_longer( cols = -c(id, wohnort), names_to = "varname", values_to = "wert")
Die Funktion pivot_longer stammt aus dem tidyr-Paket (Wickham & Henry, 2019). Das englische Verb pivot wird im deutschen mit »schwenken« oder »drehen« übersetzt. Die pivot-Funktion ersetzt die etwas in die Jahre gekommene gatherFunktion aus demselben Paket. Die Funktion hat hier drei Argumente: cols. Hier geben wir entweder an, welche Variablen ins Ultralong-Format transformiert werden sollen, oder, wie in diesem Beispiel, welche nicht ins Ultralong-Format transformiert werden sollen (s. Minuszeichen). Prinzipiell werden alle messwiederholten Variablen umstrukturiert und alle nicht-messwiederholten Variablen nicht. names_to. Name der Variablen, die die ursprünglichen Variablennamen enthalten soll. Diesen Namen können wir frei wählen. values_to. Name der Variablen, die die Werte der messwiederholten Variablen enthalten soll. Diesen Namen können wir frei wählen. Die oben gezeigten Daten haben jetzt noch einen Schönheitsfehler. Sie sind noch nicht perfekt »tidy«, da die in der Variablen varnames aufgeführten Variablennamen nach wie vor zwei Informationen vermischen: den Messzeitpunkt und den Namen des psychologischen Merkmals. Wir erweitern daher die pivot_longer-Funktion, um diese Informationen zu trennen. Konkret teilen wir die ursprünglichen Variablennamen auf und speichern die einzelnen Bestandteile in unterschiedlichen Variablen:
7.6
Data Frames umstrukturieren
> ultralang % pivot_longer( cols = -c(id, wohnort), names_to = c("varname", "mzp"), names_sep = "_", values_to = "wert")
In diesem Befehl werden im Argument names_to jetzt zwei neue Variablen benannt: varname und mzp (Abkürzung für Messzeitpunkt). Das sind die beiden Variablen, in denen die Informationen aus den ursprünglichen Variablennamen gleich gespeichert werden. Im Argument names_sep geben wir an, dass die Variablennamen beim Unterstrich aufgeteilt werden sollen. Es lohnt sich also, die Variablen schon in den Rohdaten einheitlich so zu benennen, dass man die verschiedenen Informationen mit einem Symbol trennen kann. Die pivot_longer-Funktion kann auch andere Arten von zusammengesetzen Variablennamen trennen. Mehr Infos dazu gibt es in der Hilfe-Datei für diese Funktion. Wir schauen uns auch jetzt wieder das Ergebnis an: > ultralang # A tibble: 42 x 5 id wohnort varname
1 1 Land neuro 2 1 Land neuro 3 1 Land neuro 4 1 Land extra 5 1 Land extra 6 1 Land extra 7 4 Stadt neuro 8 4 Stadt neuro 9 4 Stadt neuro 10 4 Stadt extra # ... with 32 more rows
mzp wert 1 4 2 3 3 4 1 2 2 4 3 3 1 2 2 3 3 2 1 2
Das hier ist jetzt ein wunderschöner, aufgeräumter Datensatz. Die Spalte varname enthält die Information zum Merkmal, die Variable mzp enthält die Information zum Messzeitpunkt, und die Variable wert enthält die jeweiligen Ausprägungen auf der Variable zu dem Messzeitpunkt. Schritt 2: Umstrukturierung ins Long-Format Ein Haken am Ultralong-Format ist, dass jetzt unterschiedliche psychologische Merkmale in derselben Variablen auftauchen. Für die meisten statistischen Analysen
105
106
7 Datenaufbereitung
benötigen wir aber Daten, in denen die psychologischen Merkmale in unterschiedlichen Variablen bzw. Spalten aufgeführt sind und wir pro Person für jeden Messzeitpunkt nur eine Zeile haben. Wir müssen also die Ultralong-Daten wieder etwas breiter machen. Dazu verwenden wir die Funktion pivot_wider: > lang % pivot_wider( names_from = varname, values_from = wert)
Im Argument names_from legen wir fest, woher die zukünftigen Variablennamen stammen (hier: Variable varname). Im Argument values_from geben wir an, woher die Werte für die Variablen stammen (hier: Variable wert). Wir betrachten wieder das Ergebnis: > lang # A tibble: 21 x 5 id wohnort mzp neuro extra 1 1 Land 1 4 2 2 1 Land 2 3 4 3 1 Land 3 4 3 4 4 Stadt 1 2 2 5 4 Stadt 2 3 2 6 4 Stadt 3 2 2 7 2 Land 1 1 3 8 2 Land 2 1 1 9 2 Land 3 4 3 10 5 Land 1 NA 1 # ... with 11 more rows
Dieser Data Frame hat die gewünschte Struktur: Für jede Person gibt es für jeden Messzeitpunkt eine eigene Zeile, insgesamt also drei. Die Variable mzp gibt den Messzeitpunkt an. Die Werte für die messwiederholten Variablen Neurotizismus und Extraversion sind in den Spalten neuro und extra enthalten.
7.6.2 Von Long zu Wide Im vorherigen Abschnitt haben wir im zweiten Schritt bereits Daten etwas breiter gemacht. Wir wollen jetzt den Data Frame lang wieder ins ursprüngliche breite Format bringen. Dazu verwenden wir wieder die pivot_wider-Funktion:
7.7
Fortgeschrittene Datenaufbereitung
> breit % pivot_wider( names_from = mzp, values_from = -c(id, wohnort, mzp), names_sep = ".")
Im Argument names_from geben wir an, aus welcher Variable im langen Data Frame die Variablennamen im neuen Data Frames gebildet werden sollen. Hier geben wir die Variable mzp an. Im Argument values_from führen wir entweder alle messwiederholten Variablen auf, oder, wie in diesem Beispiel, schließen mithilfe des Minuszeichens alle nicht-messwiederholten Variablen aus. Schließlich legen wir im Argument sep fest, welches Symbol verwendet werden soll, um die einzelnen Bestandteile der neuen Variablennamen zu trennen. Wir entscheiden uns hier für einen Punkt. Der damit erstellte Data Frame sieht wieder genauso aus wie der ursprüngliche Data Frame daten2. Die einzige (gewollte) Änderung ist, dass die Namen der messwiederholten Variablen jetzt nicht mehr einen Unterstrich, sondern einen Punkt enthalten: > breit # A tibble: 7 x 8 id wohnort neuro.1 neuro.2 neuro.3 extra.1 extra.2 extra.3
1 1 Land 4 3 4 2 4 3 2 4 Stadt 2 3 2 2 2 2 3 2 Land 1 1 4 3 1 3 4 5 Land NA 2 4 1 2 5 5 10 Stadt 3 3 2 5 5 1 6 12 Land 5 5 1 2 5 2 7 13 Stadt 1 4 2 1 3 2
7.7
Fortgeschrittene Datenaufbereitung
Dieses Kapitel ist schon ganz schön lang, und trotzdem haben wir bisher nur die vergleichsweise einfachen Probleme der Datenaufbereitung besprochen. Oft ist die Datenaufbereitung noch wesentlich komplexer. Zum Beispiel muss man manchmal bestimmte Aufbereitungsschritte nur für ausgewählte Untergruppen durchführen, oder man muss Analysen und Datenaufbereitung miteinander verbinden. Für fortgeschrittene Probleme der Datenaufbereitung dieser Art gibt es selten maßgeschneiderte Funktionen. Stattdessen muss man die bekannten Funktionen in einer bestimmten Reihenfolge hintereinander durchführen.
107
108
7 Datenaufbereitung
Mit den R-Basisfunktionen kann man mehrere Funktionen kombinieren, indem man diese entweder ineinander verschachtelt oder hintereinander durchführt und die Zwischenergebnisse jeweils als Objekte speichert. Beide Ansätze stoßen aber bei komplexen Vorgängen an ihre Grenzen. Geschachtelte Funktionen werden sehr schnell unübersichtlich, und das wiederholte Anlegen von neuen Objekten kann nicht nur unsere Kreativität beim Ausdenken neuer Objektnamen strapazieren, sondern unter Umständen auch den Arbeitsspeicher überlasten. Für solche Fälle ist tidyverse meistens überlegen, und das liegt vor allem an der Pipe. Mit der Pipe können wir verschiedene Schritte der Datenaufbereitung direkt hintereinander durchführen, ohne dabei unzählige Objekte oder unübersichtliche Befehle zu produzieren. Als Beispiel betrachten wir nochmal die Umstrukturierung der Daten vom Wide- ins Long-Format (s. Abschn. 7.6.1). Diese Umstrukturierung haben wir in zwei Schritten durchgeführten (von Wide zu Ultralong zu Long) und das Zwischenergebnis in einem eigenen Objekt gespeichert. Wir können stattdessen auch den zweiten Schritt mit einer Pipe an den Befehl für den ersten Schritt anhängen: > lang % pivot_longer( cols = -c(id, wohnort), names_to = c("varname", "mzp"), names_sep = "_", values_to = "wert") %>% pivot_wider( names_from = varname, values_from = wert)
Das Pipe-Symbol %>% bedeutet: Nimm das, was vor mir steht und mache damit das, was nach mir steht. Das funktioniert im tidyverse deshalb so gut, weil die Funktionen ja immer einen Data Frame als Input erwarten und auch einen Data Frame (genauer: einen Tibble) ausgeben. Diesen Befehl könnte man also folgermaßen verbalisieren (in Anlehnung an Sauer, 2019): Nimm den Data Frame daten2 UND DANN transformiere ihn mit der pivot_longer ins Ultralang-Format UND DANN nimm den resultierenden Data Frame und transformiere ihn mit der pivot_wider-Funktion ins Long-Format.
7.8
Funktionen aus den R-Basispaketen im Überblick
Tipp
Für noch komplexere Probleme der Datenaufbereitung gibt es spezielle tidyverse-Funktionen, die in die Pipe eingebunden werden können. Die group_by-Funktion kann verwendet werden, um die nachfolgenden Befehle getrennt für bestimmte Gruppen durchzuführen (für ein Beispiel s. Abschn. 20.2.2). Viele Funktionen gibt es auch mit den Suffixen _all (tue dies für alle Spalten), _if (tue dies für bestimmte Zeilen) und _at (tue dies für bestimmte Spalten). Viele weitere Beispiele und Hilfestellungen findet man im Cheatsheet für dplyr (s. Abschn. 3.3.3) und auf der Webseite https://www.tidyverse.org/. Eine großartige deutschsprachige Quelle ist das Lehrbuch von Sauer (2019).
7.8
Funktionen aus den R-Basispaketen im Überblick
Funktion
Beschreibung
daten$neu %
Pipe (deutsch: Pfeife). Wird zum Verknüpfen verschiedener tidyverse-Befehle verwendet.
mutate()
Sammelfunktion zum Verändern bestehender Variablen bzw. Erstellen neuer Variablen.
rename()
Benennt Variablen um.
recode()
Codiert Werte einer Variablen in neue Werte um.
select()
Wählt bestimmte Variablen aus einem Data Frame aus. Die Variablen können namentlich aufgelistet werden oder mit Hilfsfunktionen wie starts_with(), ends_with() oder contains() ausgewählt werden.
filter()
Wählt Fälle nach bestimmten Kriterien aus einem Data Frame aus.
drop_na()
Flexible Funktion zum Ausschluss von Fällen mit fehlenden Werten.
arrange()
Sortiert den Data Frame nach einer oder mehren Variablen.
desc()
Wird innerhalb der arrange-Funktion angewandt, um Variablen zu kennzeichnen, die absteigend sortiert werden sollen.
bind_rows()
Fügt zwei Data Frames mit unterschiedlichen Fällen zusammen.
7.10
Übungen
Funktion
Beschreibung
inner_join(), full_join(), left_join(), right_join()
Fügen zwei Data Frames mit denselben Personen, aber unterschiedlichen Variablen zusammen.
pivot_longer()
Strukturiert einen Data Frame ins Long- bzw. Ultralong-Format um.
pivot_wider()
Strukturiert einen Data Frame ins Wide-Format um.
group_by()
Bewirkt, dass die folgenden tidyverse-Befehle getrennt für in dieser Funktion definierte Untergruppen durchgeführt werden.
7.10 Übungen Diese Übungen beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze). Verwenden Sie für diese Übungen jeweils sowohl die R-Basisfunktionen als auch die entsprechenden tidyverse-Funktionen. So bekommen Sie am besten heraus, welchen Ansatz Sie in Zukunft für Ihre Datenaufbereitung bevorzugen. (1) Die Daten enthalten drei Variablen, die die Zufriedenheit der Studierenden mit ihrem Studium erfassen: Zufriedenheit mit den Studieninhalten (zuf.inh.1), den Studienbedingungen (zuf.bed.1) und den Belastungen durch das Studium (zuf.bel.1). Berechnen Sie für alle Personen die individuellen Mittelwerte (d. h., die Skalenwerte) über diese drei Variablen hinweg und fügen Sie diese als neue Variable zum Data Frame hinzu. Den Namen der neuen Variablen können Sie frei wählen. (2) Die Variablen stim1 bis stim12 enthalten die Antworten auf zwölf Items, mit denen die Stimmung der Studierenden gemessen werden soll. Alle Items wurden auf einer Skala von 1 bis 5 beantwortet. Die Items stim1, stim2, stim6, stim8, stim10 und stim12 waren positiv formuliert (z. B. »gut«), d. h., bei diesen Items kennzeichnen hohe Werte eine gute Stimmung. Die Items stim3, stim4, stim5, stim7, stim9 und stim11 waren dagegen negativ formuliert (z. B. »schlecht«), d. h., bei diesen Items kennzeichnen hohe Werte eine schlechte Stimmung. Polen Sie die negativ formulierten Items um und fügen Sie die umgepolten Werte als neue Variablen zum Data Frame erstis hinzu. (3) Fügen Sie zwei neue Variablen zum Data Frame erstis hinzu: (a) die standardisierten Werte der Variablen gewiss und (b) die zentrierten Werte der Variablen gewiss.
111
112
7 Datenaufbereitung
(4) Sortieren Sie die Ausgabe nach der Variablen Prokrastination (prok). Wie lautet die ID (Variable code) der Person mit dem niedrigsten Prokrastinationswert? (5) Erstellen Sie einen neuen Data Frame, der nur Personen mit einem Prokrastinationswert (prok) von 2.5 oder kleiner enthält. (6) Erstellen Sie einen neuen Data Frame, der nur die Variablen lz13 bis lz17 enthält und nur Personen mit gültigen Werten auf diesen Variablen.
Powered by TCPDF (www.tcpdf.org)
8.1
8
Häufigkeitstabellen
Univariate deskriptive Statistik
Ziel der deskriptiven Statistik ist das Beschreiben von Daten anhand von statistischen Kennwerten. In diesem Kapitel beschäftigen wir uns mit statistischen Kennwerten zur Beschreibung der Verteilung einzelner Variablen (univariat = eine Variable). Statistische Kennwerte für die Beschreibung des Zusammenhangs zwischen zwei Variablen werden im folgenden Kapitel besprochen. Zum Einstieg schauen wir uns an, wie verschiedene Arten von Häufigkeitstabellen erstellt werden (Abschn. 8.1). Anschließend besprechen wir Funktionen für verschiedene univariate deskriptive Kennwerte (Abschn. 8.2). Zum Schluss berechnen wir die deskriptiven Statistiken getrennt für verschiedene Untergruppen (Abschn. 8.3). Die Beispiele in diesem Kapitel beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze).
8.1
Häufigkeitstabellen
In Häufigkeitstabellen wird für jede in den Daten vorhandene Merkmalsausprägung angegeben, wie häufig diese Ausprägung vorkommt. Dabei unterscheidet man zwischen absoluten und relativen Häufigkeiten. Absolute Häufigkeiten bezeichnen die Anzahl der Personen mit einer bestimmten Ausprägung, z. B. 5 Frauen und 5 Männer. Relative Häufigkeiten bezeichnen dagegen den Anteil der Personen mit einer bestimmten Ausprägung an der gesamten Stichprobe, z. B. 50 % Frauen und 50 % Männer. Als Beispiel betrachten wir in den folgenden Abschnitten die Variable wohnort.alt. Diese Variable enthält die Antworten auf das Item »Wo haben Sie vor zwölf Monaten gelebt?«. Die Antwortkategorien sind (1) in den alten Bundesländern, (2) in den neuen Bundesländern, (3) in Berlin und (4) im Ausland. Die Variable wohnort.alt ist eine nominalskalierte Variable, die in den Daten bereits als Faktor mit Wertelabels definiert wurde (s. Abschn. 7.2.3).
8.1.1
Absolute Häufigkeiten
Eine Tabelle mit absoluten Häufigkeiten erhalten wir mit der table-Funktion:
113
114
8 Univariate deskriptive Statistik > table(erstis$wohnort.alt) alte BL neue BL Berlin Ausland 32 26 86 18
Wenn wir Wertelabels für den Faktor vergeben haben, werden diese Wertelabels auch in der Ausgabe angegeben. Anderenfalls erscheinen hier die numerischen Ausprägungen der Variablen. Die Reihenfolge der Kategorien in der Tabelle entspricht der Reihenfolge der Merkmalsausprägungen, wie wir sie beim Anlegen des Faktors definiert haben (s. Abschn. 7.2.3). Man kann sich aber auch die Kategorien sortieren lassen: > sort(table(erstis$wohnort.alt)) Ausland neue BL alte BL Berlin 18 26 32 86
Standardmäßig werden die Kategorien hier aufsteigend sortiert, d. h., die Kategorie mit der kleinsten absoluten Häufigkeit wird als erste aufgeführt. Mit dem zusätzlichen Argument decreasing = TRUE sortieren wir die Kategorien absteigend.
8.1.2
Relative Häufigkeiten
Die relativen Häufigkeiten geben an, wie häufig eine Kategorie im Verhältnis zur gesamten Stichprobe vorkommt. Sie wird berechnet, indem man die absolute Häufigkeit einer bestimmten Kategorie durch die Gesamtsumme teilt. In R erhalten wir die relativen Häufigkeiten mit der Funktion prop.table (proportions table). Wichtig: Diese Funktion wird nicht etwa direkt auf die Variable angewandt, sondern auf die mit der table-Funktion berechneten absoluten Häufigkeiten (s. Abschn. 8.1.1). > prop.table(table(erstis$wohnort.alt)) alte BL neue BL Berlin Ausland 0.1975309 0.1604938 0.5308642 0.1111111
Die relativen Häufigkeiten addieren sich immer zu 1 auf. Um stattdessen prozentuale Häufigkeiten zu erhalten, multiplizieren wir die relativen Häufigkeiten mit 100. Die prozentualen Häufigkeiten addieren sich immer zu 100 auf. > 100 * prop.table(table(erstis$wohnort.alt)) alte BL neue BL Berlin Ausland 19.75309 16.04938 53.08642 11.11111
8.1
Häufigkeitstabellen
In diesem Beispiel erhalten wir Werte mit recht vielen Nachkommastellen. Wir vereinfachen die Darstellung, indem wir diese Werte mit der round–Funktion runden. > round(100 * prop.table(table(erstis$wohnort.alt))) alte BL neue BL Berlin Ausland 20 16 53 11
Standardmäßig werden die Zahlen mit dieser Funktion auf ganze Werte gerundet. Die gewünschte Anzahl der Nachkommastellen geben wir im Argument digits an. Hier runden wir auf eine Nachkommastelle: > round(100 * prop.table(table(erstis$wohnort.alt)), digits = 1) alte BL neue BL 19.8 16.0
Berlin Ausland 53.1 11.1
Wir sehen jetzt also, dass 11.1 % der Befragten nach Deutschland gezogen sind, um hier zu studieren, während mehr als die Hälfte, nämlich 53.1 % der Befragten, bereits vor ihrem Studium in Berlin wohnten. Tipp
Bei ordinalskalierten kategorialen Variablen (also Variablen, bei denen sich die Kategorien in einer Rangfolge anordnen lassen) ist man manchmal an sog. kumulierten Häufigkeiten interessiert. Dabei werden die Häufigkeiten nicht einzeln für jede Kategorie ausgegeben, sondern über mehrere Kategorien aufsummiert. Dies kann sowohl für absolute als auch für relative Häufigkeiten gemacht werden. In R erhalten wir kumulierte Häufigkeiten, indem wir die cumsum-Funktion auf eine Tabelle mit absoluten oder relativen Häufigkeiten anwenden.
8.1.3
Integration der Häufigkeiten in einer Tabelle
Wir haben nun drei verschiedene Arten von Häufigkeiten kennengelernt: absolute Häufigkeiten, relative Häufigkeiten und prozentuale Häufigkeiten. Für jede dieser Häufigkeiten haben wir bisher einen eigenen Befehl ausgeführt und damit eine eigene Tabelle erhalten. Die einzelnen Befehle wurden mit der Zeit immer verschachtelter und damit unübersichtlicher. Wir schauen uns jetzt an, wie man die Befehle vereinfachen kann und zudem eine Tabelle erzeugt, die alle Häufigkeiten enthält. Dazu speichern wir die einzelnen Häufigkeiten in Objekten (s. Kap. 5).
115
116
8 Univariate deskriptive Statistik
Wir beginnen mit den absoluten Häufigkeiten. Diese Tabelle wird unter dem Namen absolut gespeichert: > absolut relativ prozent haeufigkeiten round(haeufigkeiten, digits = 2) absolut relativ prozent alte BL 32 0.20 19.75 neue BL 26 0.16 16.05 Berlin 86 0.53 53.09 Ausland 18 0.11 11.11
8.2
8.2
Deskriptive Kennwerte
Deskriptive Kennwerte
Um die Verteilung von Variablen zu beschreiben, werden zwei Arten von Kennwerten herangezogen: Maße der zentralen Tendenz beschreiben die Lage der Verteilung und geben den häufigsten oder typischsten Wert der Verteilung an. Dispersionsmaße geben die Unterschiedlichkeit in den Daten an und werden daher auch als Streuungsmaße bezeichnet. Welches Maß der zentralen Tendenz und welches Dispersionsmaß für bestimmte Variablen geeignet ist, hängt vom Skalenniveau dieser Variablen ab. Wir besprechen zunächst zwei Funktionen, mit denen man mehrere deskriptive Kennwerte auf einmal erhält: die summary-Funktion und die describe-Funktion aus dem psych-Paket (Revelle, 2019). Anschließend gehen wir auf spezielle Funktionen für einzelne statistische Kennwerte ein.
8.2.1
Die summary-Funktion
Die summary-Funktion ist eine sog. generische Funktion. Das bedeutet, dass sie auf verschiedene Objekttypen angewandt werden kann und für den Objekttyp angemessene Ausgaben erzeugt. In diesem Kapitel wenden wir die Funktion auf Vektoren, Faktoren und ganze Data Frames an. In späteren Kapiteln werden wir die Funktion verwenden, um die Ergebnisse statistischer Modelle zu erhalten. Wir beginnen mit dem Faktor wohnort.alt. Hier erhalten wir die absoluten Häufigkeiten sowie die Anzahl der fehlenden Werte: > summary(erstis$wohnort.alt) alte BL neue BL Berlin Ausland 32 26 86 18
NA's 29
Etwas anders sieht die Ausgabe aus, wenn wir die summary-Funktion auf einen Vektor anwenden, wie im folgenden Beispiel. Hier wird die sog. Fünf-Punkte-Zusammenfassung (Min. = Minimum, 1st Qu. = 1. Quartil, Median = Median, 3rd Qu. = 3. Quartil und Max. = Maximum), der Mittelwert (mean) sowie die Anzahl der fehlenden Werte (NA's) angegeben: > summary(erstis$extra) Min. 1st Qu. Median 1.500 3.250 3.500
Mean 3rd Qu. 3.592 4.000
Max. 5.000
NA's 3
Die summary-Funktion kann auch auf den kompletten Data Frame angewendet werden, z. B. mit summary(erstis). Wir erhalten so mit nur einem einzigen Befehl die deskriptiven Statistiken für alle Variablen (hier aus Platzgründen nicht abgedruckt).
117
118
8 Univariate deskriptive Statistik
8.2.2 Die describe-Funktion Es ist üblich, Mittelwerte immer zusammen mit Standardabweichungen zu berichten. Die Standardabweichung wird jedoch mit der summary-Funktion nicht ausgegeben. Für Vektoren ist eine der besten Funktionen, um effizient möglichst viele statistische Kennwerte zu erhalten, die describe-Funktion aus dem psych-Paket (Revelle, 2019). Wir müssen also dieses Paket installieren (falls noch nicht geschehen) und laden. Die describe-Funktion kann auf einzelne Variablen oder auf einen Data Frame aus mehreren Variablen angewandt werden. Im folgenden Beispiel erstellen wir eine Tabelle mit deskriptiven Statistiken für die Variablen gewiss (Gewissenhaftigkeit) und extra (Extraversion). Dazu fassen wir zunächst die beiden Variablen in einem neuen Data Frame zusammen. Wir verwenden hier die select-Funktion aus dem dplyr-Paket (Wickhamn et al., 2020), das ebenfalls vorher installiert und geladen sein muss. Wir können aber natürlich auch eine der anderen Möglichkeiten zur Auswahl von Variablen wählen, die wir in Abschnitt 7.3.1 kennengelernt haben. > auswahl % select(gewiss, extra)
Anschließend wenden wir die describe-Funktion auf den neu erstellen Data Frame an: > describe(auswahl)
gewiss extra
vars n mean sd median trimmed mad min max range 1 188 3.61 0.78 3.75 3.65 0.74 1.25 5 3.75 2 188 3.59 0.64 3.50 3.60 0.74 1.50 5 3.50
skew kurtosis se -0.42 -0.12 0.06 -0.15 0.05 0.05
Diese umfangreiche Tabelle gehen wir jetzt Spalte für Spalte durch. Die erste Spalte enthält die Variablennamen. In der Spalte vars werden die Variablen durchnummeriert. Es folgen die Anzahl gültiger Fälle für diese Variable (n), Mittelwert (mean), Standardabweichung (sd), Median (median) sowie der getrimmte Mittelwert (trimmed). Der getrimmte Mittelwert beruht auf Daten, aus denen die niedrigsten 10 % und die höchsten 10 % der Werte entfernt wurden. Die Spalte mad enthält die sog. Median Absolute Deviation. Dabei handelt es sich um ein robustes Dispersionsmaß, dass die durchschnittliche Abweichung der Werte vom Median ausdrückt. In
8.2
Deskriptive Kennwerte
den weiteren Spalten folgen Minimum (min), Maximum (max), Spannweite des Wertebereichs (range), Schiefe (skew), Exzess (kurtosis) und der Standardfehler des Mittelwerts (se). Schiefe und Exzess sind Maße für die Abweichung der Verteilung von der Normalverteilung.
8.2.3
Funktionen für einzelne Kennwerte
Für die meisten statistischen Kennwerte gibt es auch eigene Funktionen. Die Namen dieser Funktionen kann man sich meist leicht merken, sofern man den englischen Begriff für den Kennwert kennt. So heißt z. B. für die Funktion für das arithmetische Mittel mean. Tabelle 8.1 gibt eine Übersicht über die Funktionen für die gängigsten statistischen Kennwerte. Tabelle 8.1 Funktionen für die wichtigsten deskriptivstatistischen Kennwerte.
Kennwert
Funktion
Paket
Median
median()
stats
Mittelwert (arithmetisches Mittel)
mean()
stats
Minimum
min()
stats
Maximum
max()
stats
Wertebereich
range()
stats
Interquartilsabstand
IQR()
stats
Standardabweichung
sd()
stats
Varianz
var()
stats
Schiefe
skew()
psych
Kurtosis
kurtosi()
psych
Auf zwei Besonderheiten müssen wir gesondert eingehen. Erstens müssen wir über das Argument na.rm sprechen, das für alle in der Tabelle aufgeführten Funktionen relevant ist. Zweitens gibt es keine eigene Funktion für den Modalwert. Den können wir aber über einen Trick ermitteln. Das Argument na.rm Die in Tabelle 8.1 aufgeführten Funktionen haben eine etwas unglückliche Standardeinstellung: Sie geben nur dann ein Ergebnis aus, wenn in den Daten keine fehlenden Werte vorkommen. Das ist aus mathematischer Sicht plausibel, denn fehlende Werte sind in der Berechnung von Median, Mittelwert usw. nicht vorgesehen. Da
119
120
8 Univariate deskriptive Statistik
echte Daten aber fast immer fehlende Werte enthalten, führt dies dazu, dass diese Funktionen fast immer ihren Dienst verweigern. Wir zeigen das hier am Beispiel der median-Funktion, mit der wir den Median für die Variable extra bestimmen. > median(erstis$extra) [1] NA
Die Variable extra hat fehlende Werte, daher erhalten wir das Ergebnis NA. Wir müssen daher R explizit dazu auffordern, die fehlenden Werte bei der Berechnung des Medians einfach zu ignorieren. Das tun wir mit dem Argument na.rm = TRUE. > median(erstis$extra, na.rm = TRUE) [1] 3.5
Wenn wir eine der in Tabelle 8.1 aufgeführten Funktionen verwenden, sollten wir das Argument na.rm = TRUE standardmäßig aufnehmen. Das finden Sie nervig? Damit sind Sie nicht alleine, und deshalb haben andere R-Nutzer bereits alternative Funktionen entwickelt, die auf dieses Argument verzichten, z. B. die describe-Funktion aus dem psych-Paket, die wir in Abschn. 8.2.2 besprochen haben. Modalwert Der Modalwert einer Variablen ist die Ausprägung, die am häufigsten in der Stichprobe vorkommt. Diese Information können wir u. a. der Häufigkeitstabelle entnehmen, die wir oben schon kennengelernt haben. Hier ist mit 86 Personen die Ausprägung »Berlin« am häufigsten vertreten: > table(erstis$wohnort.alt) wohnort.alt alte BL neue BL Berlin Ausland 32 26 86 18
Wenn eine Variable sehr viele Ausprägungen hat, kann so eine Häufigkeitstabelle jedoch schnell unübersichtlich werden. Wir können den Modalwert daher auch so anfordern: > which.max(table(erstis$wohnort.alt)) Berlin 3
8.2
Deskriptive Kennwerte
Dieser Befehl bezieht sich nicht auf die Rohdaten, sondern auf die Häufigkeitstabelle, die mit dem Befehl table(erstis$wohnort.alt) angefordert wurde. Die Funktion which.max besagt, dass die Bezeichnung der Kategorie ausgegeben werden soll, die den höchsten Wert erhalten hat, hier also die höchste absolute Anzahl an Personen. Im Beispiel ist das die Kategorie Berlin. Darunter steht – in diesem Beispiel – die Zahl 3. Diese Zahl gibt die Position der Kategorie in der Häufigkeitstabelle an. In der oben erstellten Häufigkeitstabelle wurde die Kategorie Berlin an dritter Stelle aufgeführt, daher erhalten wir hier das Ergebnis 3. Achtung: Die which.max-Funktion sollte nicht mit der max-Funktion verwechselt werden. Wenden wir die max-Funktion auf die Häufigkeitstabelle an, erhalten wir die absolute Häufigkeit für die Kategorie Berlin (hier also 86 Personen). Dies ist jedoch nicht der Modalwert! > max(table(erstis$wohnort.alt)) [1] 86
8.2.4 Quantile Quantile sind Werte einer Variablen, unterhalb derer ein bestimmter Anteil der Werte der Variablen liegt. Wir haben bereits ein Quantil kennengelernt, nämlich den Median. Dieses Quantil teilt die Daten in zwei gleich große Hälften. In diesem Abschnitt besprechen wir weitere Quantile. Quartile Als Quartile bezeichnet man die Quantile, die die Stichprobe in vier gleich große Gruppen teilen. Sie werden mit der quantile-Funktion angefordert. Im folgenden Beispiel bestimmen wir die Quartile für die Variable stim1. Dabei handelt es sich um ein Item zur Messung der guten Stimmung mit fünf Antwortoptionen (von 1 bis 5). > quantile(erstis$stim1, na.rm = TRUE) 0% 25% 50% 75% 100% 1 3 4 4 5
Zusätzlich zu den drei Quartilen werden auch noch das Minimum (0 %) sowie das Maximum (100 %) ausgegeben.
121
122
8 Univariate deskriptive Statistik
Andere Quantile Man kann die Daten nicht nur in Hälften oder Viertel aufteilen, sondern auch in andere Anteile. So teilen Dezile eine Stichprobe in zehn gleiche Teile, und Perzentile teilen eine Stichprobe in hundert gleiche Teile. Die quantile-Funktion gibt standardmäßig Quartile aus, man kann aber auch andere Quantile anfordern. Die gewünschten Quantile gibt man im Argument probs an. Wenn wir z. B. das 0.4-Quantil bestimmen möchten, also den Wert der Variablen, unterhalb dessen 40 % der Werte liegen, geben wir den folgenden Befehl ein: > quantile(erstis$stim1, na.rm = TRUE, probs = .4)
Im probs-Argument können auch mehrere Quantile angefordert werden. Dafür müssen wir die gewünschten Quantile als Vektor zusammenfassen, z. B. probs = c(.4, .6, .8).
8.3
Gruppenvergleiche
Bisher haben wir uns die deskriptiven Statistiken für die gesamte Stichprobe angeschaut. Wir können uns aber auch deskriptive Statistiken für Untergruppen ausgeben lassen. Mit der describeBy-Funktion aus dem psych-Paket (Revelle, 2019) werden dieselben statistischen Kennwerte wie mit der describe-Funktion (s. Abschn. 8.2.1) ausgegeben, aber getrennt für bestimmte Untergruppen. In diesem Beispiel fordern wir deskriptive Statistiken für die Variable extra getrennt für Frauen und Männer an: > describeBy(erstis$extra, erstis$geschl) Descriptive statistics by group group: weiblich
1
vars n mean sd median trimmed mad min max range skew 1 113 3.61 0.64 3.5 3.62 0.74 2 5 3 -0.18
kurtosis se -0.11 0.06 ------------------------------------------------------------
8.3
Gruppenvergleiche
group: männlich vars n mean sd median trimmed mad min max range skew 1 1 55 3.5 0.68 3.5 3.5 0.74 1.5 5 3.5 -0.11 kurtosis se 0.13 0.09
Ein kleiner Nachteil dieser Ausgabe ist, dass die deskriptiven Statistiken nicht in Tabellenform dargestellt werden (zu erkennen u. a. an der horizontalen Linie) und daher nicht einfach exportiert werden können (s. Kap. 22). Um die Ergebnisse in Tabellenform darzustellen, ergänzen wir das Argument mat = TRUE: > describeBy(erstis$extra, erstis$geschl, mat = TRUE)
Wie in der describe-Funktion können wir auch hier deskriptive Statistiken für mehrere Variablen anfordern, indem wir diese Variablen vorab in einem eigenen Data Frame speichern und diesen Data Frame im ersten Argument aufführen. Außerdem ist es möglich, mehrere Variablen für die Definition der Untergruppen zu verwenden. Im nächsten Beispiel werden die deskriptiven Statistiken der Variablen extra für jede mögliche Kombination der Variablen geschl (weiblich vs. männlich) und berlin (ja = wohnt in Berlin, nein = wohnt nicht in Berlin) ausgegeben, insgesamt also für vier Gruppen. Die Gruppenvariablen müssen dafür mit der listFunktion (nicht mit der data.frame-Funktion!) zusammengefasst werden: > describeBy(erstis$extra, list(erstis$geschl, erstis$berlin), mat = TRUE)
11 12 13 14
11 12 13 14
item 1 2 3 4
group1 group2 var n mean sd median weiblich ja 1 92 3.619565 0.6676166 3.625 männlich ja 1 49 3.428571 0.6208194 3.500 weiblich nein 1 16 3.546875 0.4584280 3.500 männlich nein 1 5 4.250000 0.8660254 4.500
trimmed 3.635135 3.457317 3.517857 4.250000
mad 0.555975 0.741300 0.370650 0.741300
min 2.0 1.5 3.0 3.0
max range 5.0 3.0 4.5 3.0 4.5 1.5 5.0 2.0
123
124
8 Univariate deskriptive Statistik skew kurtosis se 11 -0.2141340 -0.1992321 0.06960384 12 -0.4946173 0.1526528 0.08868848 13 0.4107645 -0.8886500 0.11460701 14 -0.3752777 -1.8833333 0.38729833
8.4 Die wichtigsten Funktionen im Überblick Funktionen für einzelne deskriptivstatistische Kennwerte sind in Tabelle 8.1 zusammengefasst und hier nicht noch einmal aufgeführt. Funktion
Beschreibung
table()
Erstellt eine Häufigkeitstabelle für eine Variable.
sort()
Gibt die Elemente eines Objekts in aufsteigender Reihenfolge wieder.
prop.table()
Gibt die relativen Häufigkeiten einer Häufigkeitstabelle wieder.
round()
Rundet alle Werte eines Objekts auf eine bestimmte Anzahl an Nachkommastellen.
cumsum()
Gibt die kumulierten Häufigkeiten einer Häufigkeitstabelle an.
summary()
Generische Funktion zur Zusammenfassung von Objekten. Handelt es sich bei dem Objekt um einen Data Frame, Vektoren oder Faktoren werden deskriptive Statistiken ausgegeben. Handelt es sich bei dem Objekt um ein statistisches Modell, werden die Ergebnisse der Analyse ausgegeben.
describe()*
Gibt eine Reihe nützlicher statistischer Kennwerte an. Funktion aus dem psych-Paket.
describeBy()*
Gibt dieselben statistischen Kennwerte wie die describe-Funktion an, allerdings getrennt für bestimmte Gruppen. Funktion aus dem psych-Paket.
na.rm = TRUE
Argument für statistische Funktionen. Zeigt an, dass fehlende Werte bei der Anwendung der Funktion übersprungen werden sollen.
which.max()
Gibt die Kategorie eines Objekts an, die den höchsten Wert hat. Ist das Objekt eine Häufigkeitstabelle, entspricht dieser Wert dem Modalwert.
8.5
Übungen
Funktion
Beschreibung
which.min()
Gibt die Kategorie eines Objekts an, die den niedrigsten Wert hat.
quantile()
Gibt Minimum, Maximum sowie die drei Quartile eines Vektors an.
* Funktionen aus zusätzlichen Paketen
8.5
Übungen
Diese Übungen beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze). (1) Erstellen Sie eine Tabelle mit den prozentualen Häufigkeiten für die Variable gruppe. (2) Bestimmen Sie den Modalwert und den Wertebereich der Variablen gute vs. schlechte Stimmung (gs.1). (3) Beschreiben Sie die Stichprobe anhand der Variablen Geschlecht (geschl) und Alter (alter), indem Sie die folgenden Fragen beantworten: (a) Wie viele Frauen haben an der Befragung teilgenommen? (b) Wie hoch ist der Frauenanteil an der Stichprobe? (c) Wie alt sind die Teilnehmer im Durchschnitt? (d) Wie hoch ist die Standardabweichung für das Alter? (4) Verwenden Sie die describe-Funktion aus dem psych-Paket, um deskriptive Kennwerte für die intervallskalierten Variablen Lebenszufriedenheit (lz.1) und Extraversion (extra) zu berechnen. (5) Berechnen Sie die mittlere Lebenszufriedenheit (lz.1) getrennt für Frauen und Männer (geschl) mit der describeBy-Funktion aus dem psych-Paket.
Powered by TCPDF (www.tcpdf.org)
125
126
9 Bivariate deskriptive Statistik
9
Bivariate deskriptive Statistik
In diesem Kapitel behandeln wir Tabellen und statistische Kennwerte für zwei Variablen. Für die Beschreibung von zwei nominal- oder ordinalskalierten Variablen werden häufig Kontingenztabellen (auch: Kreuztabellen) erstellt (Abschn. 9.1). Um die Beziehung zwischen zwei Variablen zu quantifizieren, stehen verschiedene Zusammenhangsmaße zur Verfügung. Das bekannteste Zusammenhangsmaß ist die Produkt-Moment-Korrelation (Abschn. 9.2). Dieses Zusammenhangsmaß darf jedoch nur verwendet werden, wenn beide Variablen metrisch skaliert sind. Für nicht-metrische Variablen gibt es alternative Zusammenhangsmaße (Abschn. 9.3). Die Beispiele in diesem Kapitel beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze).
9.1
Kontingenztabellen
Kontingenz- bzw. Kreuztabellen sind eine besondere Form von Häufigkeitstabellen. In Kontingenztabellen werden alle Ausprägungen mehrerer Variablen miteinander kombiniert und für alle möglichen Kombinationen die Häufigkeiten angegeben. Im folgenden Beispiel möchten wir wissen, wie viele Frauen und Männer jeweils in Berlin oder außerhalb Berlins wohnen. Wir haben zwei Variablen (geschl und berlin) mit jeweils zwei Ausprägungen (weiblich und männlich bzw. ja und nein). Ähnlich wie bei den eindimensionalen Häufigkeitstabellen unterscheidet man auch hier zwischen absoluten und relativen Häufigkeiten.
9.1.1
Absolute Häufigkeiten
Häufigkeitstabellen lassen sich in R mit der table-Funktion anfordern (s. Abschn. 8.1). Bei zwei Variablen werden die Ausprägungen der ersten Variablen in den Zeilen und die Ausprägungen der zweiten Variablen in den Spalten dargestellt: > table(erstis$berlin, erstis$geschl) geschl berlin weiblich männlich ja 94 49 nein 16 5
9.1
Kontingenztabellen
Darüber hinaus kann man die Zeilen- und Spaltensummen sowie die Gesamtsumme anfordern. Am schnellsten geht das mit der addmargins-Funktion: > addmargins(table(erstis$berlin, erstis$geschl)) geschl berlin weiblich männlich Sum ja 94 49 143 nein 16 5 21 Sum 110 54 164
Alternativ kann man die Zeilen- und Spaltensummen auch separat anfordern. Zeilensummen erhält man mit der rowSums-Funktion (row steht für rows, der englische Begriff für Zeile). Spaltensummen erhält man mit der colSums-Funktion (col steht für column, der englische Begriff für Spalte).
9.1.2
Relative Häufigkeiten und Prozentwerte
In Abschnitt 8.1 wurde gezeigt, wie man relative Häufigkeiten und Prozentwerte anfordern kann und wie man diese Werte rundet. Diese Funktionen lassen sich genauso auf Kontingenztabellen anwenden. Bei Kontingenztabellen kommt aber noch eine Besonderheit dazu: Wir haben die Auswahl zwischen verschiedenen relativen Häufigkeiten, je nachdem, welchen Wert man als Referenz nimmt. Man hat die Wahl zwischen Gesamtsumme, Zeilensumme und Spaltensumme. Relative Häufigkeiten in Bezug zur Gesamtsumme Relative Häufigkeiten in Bezug zur Gesamtsumme erhält man, wenn man die prop.table-Funktion wie gewohnt auf die Tabelle anwendet: > prop.table(table(erstis$berlin, erstis$geschl)) weiblich männlich ja 0.57317073 0.29878049 nein 0.09756098 0.03048780
Wenn man nun noch die addmargins-Funktion auf diesen Befehl anwendet, erhält man zusätzlich die relativen Zeilen- und Spaltenhäufigkeiten sowie die relative Gesamthäufigkeit, die natürlich den Wert 1 haben sollte:
127
128
9 Bivariate deskriptive Statistik > addmargins(prop.table(table(erstis$berlin, erstis$geschl))) weiblich männlich Sum ja 0.57317073 0.29878049 0.87195122 nein 0.09756098 0.03048780 0.12804878 Sum 0.67073171 0.32926829 1.00000000
Multipliziert man diesen Befehl mit 100, erhält man die entsprechenden Prozentwerte. Um die Tabelle übersichtlicher zu machen, kann man die Werte mit der round-Funktion runden. Relative Häufigkeiten in Bezug zur Zeilensumme Um die Häufigkeiten in Bezug auf die Zeilensumme anzufordern, wird die prop.table-Funktion um das Argument 1 erweitert. Diese relativen Häufigkeiten addieren sich innerhalb jeder Zeile zu 1: > prop.table(table(erstis$berlin, erstis$geschl), 1) weiblich männlich ja 0.6573427 0.3426573 nein 0.7619048 0.2380952
Relative Häufigkeiten in Bezug zur Spaltensumme Um die Häufigkeiten in Bezug auf die Spaltensumme anzufordern, wird die prop.table-Funktion um das Argument 2 erweitert. Diese relativen Häufigkeiten addieren sich innerhalb jeder Spalte zu 1: > prop.table(table(erstis$berlin, erstis$geschl), 2) weiblich männlich ja 0.85454545 0.90740741 nein 0.14545455 0.09259259
9.1.3
Mehrdimensionale Kontingenztabellen
Man kann auch drei oder mehr Variablen in Kontingenztabellen miteinander kombinieren. Dafür erweitert man den Befehl um den entsprechenden Variablennamen. Wenn wir bspw. drei Variablen angeben, erhalten wir für jede Ausprägung der an dritter Stelle genannten Variablen eine eigene Kontingenztabelle mit den Häufigkeiten der beiden zuerst genannten Variablen.
9.2
9.2
Zusammenhangsmaße für metrische Variablen
Zusammenhangsmaße für metrische Variablen
Der Zusammenhang zwischen metrischen Variablen kann über die Produkt-Moment-Korrelation nach Pearson sowie über die Kovarianz quantifiziert werden, die wir hier beide besprechen. Tipp
Für manche Fragestellungen möchte man herausfinden, wie groß die Korrelation zwischen zwei Variablen ist, wenn eine oder mehrere Drittvariablen statistisch kontrolliert werden. Dazu bestimmt man eine Partialkorrelation oder (seltener) eine Semipartialkorrelation. Partialkorrelationen können wir z. B. mit der Funktion partial.r aus dem psych-Paket (Revelle, 2019) oder mit den Funktion pcor und pcor.test aus dem ppcor-Paket (Kim, 2015) bestimmen. Für Semipartialkorrelationen enthält das ppcor-Paket die Funktionen spcor und spcor.test.
9.2.1
Produkt-Moment-Korrelation
In R haben wir mehrere Möglichkeiten, die Produkt-Moment-Korrelation anzufordern. Wir schauen uns die Funktionen cor.test und cor aus den R-Basispaketen an sowie die corr.test-Funktion aus dem psych-Paket (Revelle, 2019). cor-Funktion Mit der cor-Funktion fordern wir die Korrelationen zwischen zwei oder mehreren Variablen an. Als Beispiel berechnen wir nun die bivariaten Korrelationen zwischen den Variablen Abiturjahrgang (abi), Alter (alter) und der Zufriedenheit mit den Studieninhalten (zuf.inh.1). Zunächst speichern wir diese drei Variablen in einem neuen Objekt. Wir verwenden hier die select-Funktion aus dem dplyr-Paket (Wickham et al., 2020; s. Abschn. 7.3.1): > auswahl % select(alter, abi, zuf.inh.1)
Wir wenden nun die cor-Funktion auf dieses neue Objekt an. > cor(auswahl) alter abi zuf.inh.1 alter 1 NA NA abi NA 1 NA zuf.inh.1 NA NA 1
129
130
9 Bivariate deskriptive Statistik
Warum erhalten wir keine Korrelationskoeffizienten, sondern lediglich das Ergebnis NA? Wie schon bei den univariaten deskriptiven Statistiken ist diese Ausgabe ein Zeichen dafür, dass mindestens eine der Variablen fehlende Werte enthält. Bei den univariaten deskriptiven Statistiken haben wir in diesem Fall das Argument na.rm = TRUE ergänzt (s. Abschn. 8.2.3). Bei der cor-Funktion verwenden wir stattdessen das Argument use. Wir haben die Auswahl zwischen use = "pairwise" und use = "complete": use = "pairwise". Für jede bivariate Korrelation werden alle Fälle verwendet, die gültige Werte auf diesen zwei Variablen haben – unabhängig davon, ob sie auf den anderen Variablen in der Korrelationsmatrix fehlende Werte haben. Dabei kann es vorkommen, dass die einzelnen Korrelationskoeffizienten auf unterschiedlichen Stichproben basieren. Auf Englisch bezeichnet man diesen Umgang mit fehlenden Werten als pairwise deletion. use = "complete". Es werden nur die Personen berücksichtigt, die auf allen in der Korrelationsmatrix enthaltenen Variablen gültige Werte haben. Dadurch basieren alle Korrelationskoeffizienten auf derselben Stichprobe. Auf Englisch bezeichnet man diesen Umgang mit fehlenden Werten als listwise deletion. In diesem Beispiel haben wir die complete-Option gewählt: > cor(auswahl, use = "complete") alter abi zuf.inh.1 alter 1.0000000 -0.82564797 -0.11802470 abi -0.8256480 1.00000000 0.09585762 zuf.inh.1 -0.1180247 0.09585762 1.00000000
corr.test-Funktion Mit der cor-Funktion werden nur die Korrelationskoeffizienten ausgegeben. Wir erhalten weder Informationen zur Stichprobengröße noch zum p-Wert. Diese statistischen Angaben lassen sich mit der corr.test-Funktion aus dem psych-Paket (Revelle, 2019) anfordern. > corr.test(auswahl) Call:corr.test(x = auswahl) Correlation matrix alter abi zuf.inh.1 alter 1.00 -0.83 -0.12 abi -0.83 1.00 0.10 zuf.inh.1 -0.12 0.10 1.00
9.2 Sample Size alter alter 176 abi 169 zuf.inh.1 167
Zusammenhangsmaße für metrische Variablen
abi zuf.inh.1 169 167 169 163 163 167
Probability values (Entries above the diagonal are adjusted for multiple tests.) alter abi zuf.inh.1 alter 0.00 0.00 0.24 abi 0.00 0.00 0.24 zuf.inh.1 0.12 0.22 0.00
Die Ausgabe besteht aus drei Teilen: Korrelationsmatrix: Die Korrelationskoeffizienten für alle bivariaten Variablenkombinationen. Stichprobengröße: Anzahl der Fälle (hier: Personen), die in die Berechnung der jeweiligen Koeffizienten eingeflossen sind. p-Werte: Die p-Werte für die jeweiligen Korrelationskoeffizienten. Die p-Werte unterhalb der Diagonalen beruhen auf den normalen bivariaten Tests. Bei den p-Werten oberhalb der Diagonalen wurde eine Korrektur für multiple Tests durchgeführt, sodass diese p-Werte immer größer sind als die p-Werte unterhalb der Diagonalen. Jede dieser Tabellen lässt sich auch einzeln anfordern. Das ist besonders dann praktisch, wenn man die Korrelationsmatrix exportieren möchte. Um bestimmte Tabellen anzufordern, verwenden wir das Dollarzeichen, das allgemein zur Auswahl von Elementen aus Objekten verwendet wird (s. Abschn. 5.3.1). In diesem Beispiel lassen wir uns nur die Koeffizienten ausgeben: > corr.test(auswahl)$r alter abi zuf.inh.1 alter 1.0000000 -0.83022112 -0.12023710 abi -0.8302211 1.00000000 0.09585762 zuf.inh.1 -0.1202371 0.09585762 1.00000000
Mit $n erhalten wir die Tabelle mit den Stichprobengrößen und mit $p erhalten wir die Tabelle mit den p-Werten. Wir können uns außerdem die t-Werte für jeden Test ($t), die Standardfehler ($se) sowie die Konfidenzintervalle ($ci) anzeigen lassen.
131
132
9 Bivariate deskriptive Statistik
Standardmäßig verwendet die corr.test-Funktion paarweisen Fallausschluss (s. o.). Wenn wir stattdessen listenweisen Fallausschluss bevorzugen, verwenden wir wie bei der cor-Funktion das Argument use = "complete". Tipp
Tabellen mit deskriptiven Statistiken sollten in keiner empirischen Studie fehlen. Eine solche Tabelle enthält typischerweise die Mittelwerte, Standardabweichungen und Interkorrelationen der in der Studie verwendeten Variablen. Um so eine Tabelle in R zu erstellen, berechnen wir zunächst die deskriptiven Statistiken und die Korrelationen und speichern die Ausgaben jeweils als neue Objekte ab. Wir verwenden hier die describe-Funktion und die corr.test-Funktion aus dem psych-Paket: > d k t cor.test(erstis$abi, erstis$alter) Pearson's product-moment correlation data: abi and alter t = -19.2468, df = 167, p-value < 2.2e-16
9.2
Zusammenhangsmaße für metrische Variablen
alternative hypothesis: true correlation is not equal to 0 95 percent confidence interval: -0.8719051 -0.7765915 sample estimates: cor -0.8302211
Im Beispiel oben wurde überprüft, ob der Korrelationskoeffizient ungleich Null ist (alternative hypothesis: true correlation is not equal to 0), d. h., es wurde eine ungerichtete Hypothesen geprüft. Die cor.test-Funktion bietet uns außerdem die Möglichkeit, gerichtete Hypothesen zu testen. Wenn wir das Argument alternative = "less" ergänzen, wird überprüft, ob die Korrelation kleiner als Null ist. Mit dem Argument alternative = "greater" überprüfen wir, ob die Korrelation größer als Null ist. Tipp
Bei sehr kleinen Zahlen verwendet R gerne die sog. wissenschaftliche Notation. Im Beispiel oben wird der p-Wert mit 2.2e-16 dargestellt, was mit 2.2 × 10–16 übersetzt wird. Eine einfache Daumenregel für p-Werte ist: Wenn wissenschaftliche Notation verwendet wird, ist der p-Wert auf jeden Fall kleiner als .001 und kann damit laut APA-Regeln mit p < .001 angegeben werden. Man kann die wissenschaftliche Notationen aber auch unterdrücken, indem man den folgenden Befehl anwendet: > options(scipen=999) scipen steht für Scientific Penalty. Der Wert 999 drückt aus, dass nur dann wis-
senschaftliche Notation verwendet werden soll, wenn die herkömmliche Notation mehr als 999 Stellen zusätzlich in Anspruch nimmt. Da dies so gut wie nie vorkommt, wird damit die wissenschaftliche Notation vollständig unterdrückt. Wenn wir diese Option aktivieren und anschließend den cor.test-Befehl von oben wiederholen, erhalten wir für den folgenden p-Wert: p-value < 0.00000000000000022
9.2.2 Kovarianz Die Kovarianz ist ein unstandardisiertes Zusammenhangsmaß, d. h., sie hat keinen festgelegten Wertebereich wie die Korrelation. In R kann man die Kovarianz mit der cov-Funktion anfordern. Diese Funktion ist sehr ähnlich zur cor-Funktion, die wir im vorherigen Abschnitt besprochen haben. Auch bei der cov-Funktion muss das use-Argument ergänzt werden, wenn fehlende Werte auf einer der Variablen vorlie-
133
134
9 Bivariate deskriptive Statistik
gen. Für die Kovarianz zwischen Alter und Abijahrgang erhalten wir das folgende Ergebnis: > cov(erstis$alter, erstis$abi, use = "complete") [1] -45.54853
Wir erhalten in unserem Beispiel eine negative Kovarianz, d. h., je kleiner der Wert für das Abijahr, desto älter sind die Personen. Anders als bei der Korrelation sagt uns die Kovarianz aber nichts über die Stärke des Zusammenhangs aus, da die Ausgangsmetrik der beiden Variablen hier noch einfließt. Verwendet man stattdessen standardisierte Werte, erhält man die Korrelation. Die cov-Funktion funktioniert auch für mehr als zwei Variablen. Hier wenden wir sie auf den in Abschnitt 9.2.1 erstellten Data Frame auswahl an. Genau wie der cor-Funktion müssen wir auch hier mit dem Argument use wieder den Umgang mit fehlenden Werten festlegen: > cov(auswahl, use = "pairwise") alter abi alter 44.3791883 -45.5485348 abi -45.5485348 65.9804170 zuf.inh.1 -0.5068898 0.4922997
zuf.inh.1 -0.5068898 0.4922997 0.3955382
Eine solche Matrix nennt man auch Varianz-Kovarianz-Matrix, da sie sowohl die Kovarianzen der Variablenpaare als auch die Varianzen der einzelnen Variablen enthält. Die Varianzen stehen dabei in der Hauptdiagonalen, die Kovarianzen stehen in den übrigen Zellen. Wo kommen diese Varianzen plötzlich her? Die Kovarianz einer Variablen mit sich selbst ist gleich der Varianz dieser Variable. Dies können wir überprüfen, indem wir die Varianz für die Variable alter auf dem herkömmlichen Weg berechnen: > var(erstis$alter, na.rm = TRUE) [1] 44.37919
Wir erhalten eine Varianz von ca. 44.38. Dies entspricht genau dem Wert, den wir der ersten Zelle der Varianz-Kovarianz-Matrix entnehmen können.
9.3
Zusammenhangsmaße für nicht-metrische Variablen
Die Produkt-Moment-Korrelation und die Kovarianz dürfen nur für metrische Variablen berechnet werden, da sie auf den Mittelwerten und Varianzen der Variablen
9.4
Die wichtigsten Funktionen im Überblick
basieren. Wenn eine oder beide Variablen nicht metrisch sind, muss man daher alternative Zusammenhangsmaße berechnen. Welches Zusammenhangsmaß angemessen ist, hängt von den Skalenniveaus der beiden Variablen ab (für Details s. Eid et al., 2017). Die Funktion association.measures aus dem Paket oii (Hale et al., 2017) gibt eine Reihe verschiedener Zusammenhangsmaße aus, z. B. den φ-Koeffizienten (für zwei dichotome Variablen), Cramérs V (für zwei nominalskalierte Variablen) oder den γ-Koeffizienten (für zwei Variablen mit geordneten Kategorien). Auch das psych-Paket (Revelle, 2019) enthält eine Reihe von Funktionen für Zusammenhangsmaße, z. B. die Funktionen polychoric und tetrachoric für polychorische bzw. tetrachorische Korrelationen und die Funktionen biserial und polyserial für biseriale bzw. polyseriale Korrelationen. Sehr empfehlenswert ist auch das vcd-Paket (Meyer et al., 2020), das speziell für die Analyse und Visualisierung von kategorialen Variablen entwickelt wurde.
9.4 Die wichtigsten Funktionen im Überblick Funktion
Beschreibung
table()
Erstellt eine Häufigkeitstabelle für eine oder mehrere Variablen.
addmargins()
Fügt Zeilen- und Spaltensummen zu einer Kontingenztabelle hinzu.
rowSums()
Gibt die Zeilensummen einer Kontingenztabelle aus.
colSums()
Gibt die Spaltensummen einer Kontingenztabelle aus.
cor()
Gibt alle bivariaten Korrelationen der Variablen im Data Frame aus.
corr.test()*
Gibt alle bivariaten Korrelationen der Variablen im Data Frame sowie Stichprobengrößen und p-Werte aus. Funktion aus dem psych-Paket.
cor.test()
Prüft einen Korrelationskoeffizienten auf Signifikanz. Gibt u. a. t-Wert, p-Wert und Konfidenzintervall aus.
cov()
Gibt alle Kovarianzen der Variablen im Data Frame (Varianz-Kovarianz-Matrix) aus.
* Funktionen aus zusätzlichen Paketen
135
136
9 Bivariate deskriptive Statistik
9.5
Übungen
Diese Übungen beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze). (1) Berechnen Sie den Zusammenhang zwischen Gewissenhaftigkeit (gewiss) und Prokrastination (prok) und interpretieren Sie Ihr Ergebnis inhaltlich. (2) Erstellen Sie eine Kontingenztabelle für die Teilnahme an der Orientierungswoche (uni3) und der Teilnahme an Unipartys (uni8). Die Tabelle sollte neben den absoluten Häufigkeiten für jede einzelne Zelle auch die Zeilen- und Spaltensummen enthalten. (3) Laut Theorie sollen die Big Five (extra, vertraeg, gewiss, neuro, intell) voneinander unabhängig sein. Statistisch ausgedrückt heißt das, dass die Korrelationen zwischen den Variablen gleich Null sein sollten. Überprüfen Sie diese Hypothese. (4) Befunde aus der psychologischen Glücksforschung deuten darauf hin, dass Menschen glücklicher sind, wenn sie extravertierter und emotional stabiler (also weniger neurotisch) sind. Trifft dies auch in unseren Daten zu? Berechnen Sie die bivariaten Zusammenhänge zwischen Lebenszufriedenheit (lz.1), Extraversion (extra) und Neurotizismus (neuro) und interpretieren Sie Ihre Ergebnisse inhaltlich.
Powered by TCPDF (www.tcpdf.org)
10
10
Datenvisualisierung
Datenvisualisierung
Wir behandeln in diesem Kapitel zwei verschiedene Ansätze zu Datenvisualisierung in R. Zum einen gehen wir auf Grafik-Funktionen ein, die in den R-Basispaketen (genauer: im Paket graphics) enthalten sind oder auf diesen Funktionen aufbauen. Der Vorteil an diesem Ansatz ist, dass diese Funktionen denselben Aufbau haben wie andere, uns schon bekannte R-Funktionen. Wir bezeichnen diese Funktionen als klassische Funktionen. Zum anderen besprechen wir die Grafik-Funktionen aus dem Paket ggplot2 (Wickham, 2016). Die mit ggplot2 erstellten Diagramme werden von vielen R-Profis bevorzugt, da sie flexibler sind und sehr viel umfangreichere Möglichkeiten bieten. Einsteiger müssen sich aber zunächst an eine etwas andere Grammatik gewöhnen, da die Befehle hier etwas anders aufgebaut sind, als wir es sonst kennen. Welchen Ansatz sollten Sie übernehmen? Das ist alleine Ihre Entscheidung! Es gibt kein Richtig oder Falsch. Beide Ansätze bieten sehr viele Möglichkeiten, und am Ende ist es Geschmackssache, welchen Ansatz man bevorzugt. Dieses Kapitel beginnt mit einer allgemeinen Einführung in die Erstellung von Diagrammen mit Funktionen aus den R-Basispaketen (Abschn. 10.1) und mit ggplot2 (Abschn. 10.2). Beide Abschnitte orientieren sich an den folgenden Leitfragen: Wie legt man die Art des Diagramms fest? Wie verändert man das Aussehen des Diagramms? Wie fügt man Elemente zum Diagramm hinzu? Wie kann man mehrere Diagramme anordnen? Anschließend gehen wir auf einige spezielle Diagramme ein und schauen uns jeweils an, wie man diese mit den Basis-Funktionen und mit ggplot2 erstellt (Abschn. 10.3). Im R-Skript zu diesem Kapitel finden Sie übrigens weitere Befehle für Diagramme, die aus Platzgründen in diesem Kapitel nicht behandelt werden können. Wie man Diagramme exportiert, wird in Abschnitt 22.3 behandelt. Die Beispiele in diesem Kapitel beziehen sich auf die Datensätze vpn.RData und erstis.RData (s. Anhang A: Datensätze).
137
138
10 Datenvisualisierung
10.1 Einführung in die klassischen Grafik-Funktionen 10.1.1 Wie legt man die Art des Diagramms fest? Die meisten klassischen Grafik-Funktionen bauen auf der plot-Funktion auf. Dabei handelt es sich um eine sog. generische Funktion, d. h., um eine Funktion, die auf fast jedes Objekt angewandt werden kann, und fast immer erhält man ein einigermaßen sinnvolles Diagramm. In Tabelle 10.1 ist zusammengefasst, welche Diagramme erstellt werden, wenn man die plot-Funktion auf eine oder zwei Variablen anwendet, die entweder als Vektoren oder als Faktoren definiert sind. Bei zwei Variablen wird die als erste genannte Variable auf der x-Achse und die als zweite genannte Variable auf der y-Achse dargestellt. Zusätzlich zur plot-Funktion gibt es eine Reihe spezieller Funktionen für Diagramme, die uns später im Kapitel begegnen werden. Diese Funktionen bauen meistens auf der plot-Funktion auf und können über dieselben Argumente angepasst werden, die auch in der plot-Funktion enthalten sind. Tabelle 10.1 Verschiedene Diagrammarten, die mit der plot-Funktion erstellt werden können
plot-Funktion
Diagramm
plot(vektor)
Index-Diagramm
plot(faktor)
Säulendiagramm
plot(vektor, vektor)
Streudiagramm
plot(faktor, vektor)
Boxplots
plot(faktor, faktor)
Mosaik-Diagramm
plot(data.frame)
Streudiagramm-Matrix (nur wenn Data Frame ausschließlich Vektoren enthält)
In einem Index-Diagramm werden die beobachteten Werte als einzelne Datenpunkte nebeneinander in der Reihenfolge dargestellt, in der sie im Data Frame gespeichert sind. Das Diagramm sieht aus wie ein Streudiagramm, zeigt aber nur die Werte einer einzelnen Variablen an. Ein Mosaik-Diagramm besteht aus verschiedenen farblich markierten Flächen, wobei jede Fläche die relative Größe einer bestimmten Gruppe darstellt. Dieses Diagramm eignet sich zur Darstellung des Zusammenhangs zwischen zwei nominalen Variablen bzw. zur Visualisierung von Kontingenztabellen.
10.1
Einführung in die klassischen Grafik-Funktionen
Auf die anderen in der Tabelle aufgeführten Diagrammtypen gehen wir in Abschnitt 10.3 genauer ein. Zum Einstieg visualisieren wir jetzt die Daten im Data Frame vpn aus der Datei vpn.RData. In diesen Daten wurde die Entwicklung der Teilnehmerzahl einer Studie dokumentiert. In der Variablen tag wurden die Tage seit Beginn der Studie durchnummeriert (z. B. 1 = erster Tag der Studie). In der Variablen n wurde festgehalten, wie viele Versuchspersonen an dem Tag an der Studie teilgenommen haben. Beide Variablen sind als Vektoren definiert. Wenn wir sie in die plot-Funktion einsetzen, erhalten wir daher ein Streudiagramm (s. Abb. 10.1 oben links): > plot(vpn$tag, vpn$n)
In dem mit diesem Befehl erstellten Diagramm sind die Werte der zuerst genannten Variablen (hier: tag) auf der x-Achse dargestellt und die Werte der als zweites genannten Variablen (hier: n) auf der y-Achse. Die einzelnen Datenpunkte werden hier als Kreise dargestellt. Mit dem zusätzlichen Argument type verändern wir den Diagrammtyp. Mit type = "l" werden die Datenpunkte mit einer Linie verbunden. Mit type = "b" werden sowohl Symbole als auch Linien dargestellt. Diesen Diagrammtyp verwenden wir in den folgenden Abschnitten (s. Abb. 10.1 oben rechts). Mit type = "s" erhalten wir Stufen, und mit type = "h" werden vertikale Linien für jeden Datenpunkt dargestellt. Für andere Diagrammtypen stehen spezielle Funktionen zur Verfügung, von denen wir einige in Abschnitt 10.3 besprechen.
10.1.2 Wie verändert man das Aussehen des Diagramms? Wir verändern das Aussehen des Diagramms durch zusätzliche Argumente innerhalb der plot-Funktion. Die Anzahl der Argumente ist so groß, dass wir hier nur auf einige wenige eingehen können. Eine Auflistung aller Grafikparameter, die über zusätzliche Argumente verändert werden können, erhalten wir mit help(par). Für alle Argumente gibt es Standardeinstellungen, die wir ebenfalls über die Hilfe-Datei erfahren können oder durch Eingabe des Befehls par(). Tipp
Befehle für Diagramme werden sehr schnell sehr lang. Um den Überblick zu behalten, ist es empfehlenswert, für jedes Argument eine eigene Zeile anzulegen.
139
140
10 Datenvisualisierung
Abbildung 10.1 Verschiedene mit der plot-Funktion erstellte Diagramme. Oben links wurden keine weiteren Einstellungen vorgenommen. Oben rechts wurde type = "b" eingestellt. Unten links wurde die Form und Größe der Datenpunkte mit den Argumenten cex und pch geändert. Unten rechts wurden Linientyp und Linienstärke mit den Argumenten lty und lwd geändert.
Form und Größe der Datenpunkte Datenpunkte werden standardmäßig als Kreise dargestellt. Mit dem Argument pch lassen sich andere Symbole verwenden. Wir geben entweder das gewünschte Symbol direkt im Argument an (z. B. pch = "A") oder geben eine Zahl ein, die für ein bestimmtes Symbol steht (z. B. pch = 2). Verwenden wir Anführungszeichen, wird das Zeichen in den Anführungszeichen als Symbol verwendet. Verwenden wir keine Anführungszeichen, geht R davon aus, dass es sich um den Code eines von 25 Symbolen
10.1
Einführung in die klassischen Grafik-Funktionen
handelt (s. Abb. 10.2). Dabei sind die Symbole 21 bis 24 etwas besonders. Im Gegensatz zu den anderen Symbolen, die immer einfarbig sind, können hier für den Rand und für die Füllung unterschiedliche Farben verwendet werden. Für den Rand wird das Standard-Argument col verwendet (s. u.), für die Füllung das Argument bg (kurz für background). Mit dem Argument cex verändern wir die Größe der Symbole. In diesem Argument geben wir eine Zahl an, die dem Faktor entspricht, um den die Größe des Symbols relativ zur Standardgröße verändert werden soll. Mit cex = 2 werden also alle Datenpunkte doppelt so groß wie standardmäßig vorgesehen dargestellt. Im folgenden Befehl stellen wir die Datenpunkte als dreifach vergrößerte ausgefüllte Dreiecke dar (s. Abb. 10.1 unten links): > plot(vpn$tag, vpn$n, type = "b", pch = 17, cex = 3)
Abbildung 10.2 Codes und Symbole für die Darstellung von Datenpunkten. In den klassischen Grafik-Funktionen wird das Symbol mit dem pch-Argument festgelegt, in ggplot2 mit dem shape-Argument. Bei den Symbolen 21 bis 24 können unterschiedliche Farben für den Rand und die Füllung gewählt werden.
141
142
10 Datenvisualisierung
Typ und Stärke der Linien Den Linientyp stellen wir mit dem Argument lty (kurz für line type) ein. Der gewünschte Linientyp kann entweder über einen Code oder über dessen englischsprachige Bezeichnung angegeben werden (s. Tab. 10.2). Standardmäßig werden alle Linien als Typ 1 (d. h. durchgezogene Linien) dargestellt. Tabelle 10.2 Codes und Bezeichnungen für verschiedene Linientypen in R.
Linientyp Code
Linientyp Bezeichnung
Ungefähres Aussehen
0
"blank"
1
"solid"
2
"dashed"
----------------------------
3
"dotted"
⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
4
"dotdash"
- ⋅ - ⋅ - ⋅ - ⋅ -⋅ - ⋅ - ⋅ - ⋅ - ⋅ - ⋅
5
"longdash"
−−−−−−−−−−−−−
6
"twodash"
−-−-−-−-−-−-−-−
Die Stärke der Linie stellen wir mit dem Argument lwd (kurz für line width) ein. In diesem Argument geben wir eine Zahl an, die beschreibt, um welchen Faktor wir die Linienstärke relativ zur Standardeinstellung verändern möchte. Möchte man eine Linie haben, die doppelt so dick ist wie normal, verwendet man das Argument lwd = 2. Im folgenden Befehl wird die Linie gepunktet dargestellt und doppelt so dick wie normal (s. Abb. 10.1 unten rechts): > plot(vpn$tag, vpn$n, type = "b", lty = 3, lwd = 2)
Farben Bis auf wenige Ausnahmen werden Diagramme standardmäßig in verschiedenen Grautönen ausgegeben. Das ist praktisch, da die meisten gedruckten Texte (inklusive dieses Lehrbuchs) in schwarz-weiß erscheinen. Aber natürlich kann R mehr als nur grau. Von cornflowerblue bis tomato4 stehen insgesamt 657 namentlich benannte
10.1
Einführung in die klassischen Grafik-Funktionen
Farbtöne zur Verfügung. Eine vollständige Liste aller namentlich benannten Farbtöne erhält man mit dem Befehl colors(). Für neun besonders häufig verwendete Farbtöne kann man zudem einen Code verwenden (s. Tab. 10.3). Tabelle 10.3 Codes für neun besonders häufig verwendete Farbtöne
Code
Farbe
Code
Farbe
0
Weiß
5
Türkis
1
Schwarz
6
Pink
2
Rot
7
Gelb
3
Grün
8
Grau
4
Blau
Die Farbe der Datenpunkte geben wir im Argument col an. Mit dem folgenden Befehl ändern wir die Farbe der Datenpunkte und Linien in unserem Beispieldiagramm zu Rot: > plot(vpn$tag, vpn$n, type = "b", col = 2)
Mit diesem Befehl werden sowohl die einzelnen Punkte als auch die verbindenden Linien in rot dargestellt. Wenn wir diese Elemente in unterschiedlichen Farben darstellen möchten, müssen wir zunächst das Diagramm mit nur einem Element erstellen (z. B. nur die Linien mit type = "l") und anschließend mit der points-Funktion die Punkte nachträglich hinzufügen. Ein Beispiel dafür finden Sie im R-Skript zu diesem Kapitel. Wie man die Farben der Achsenbeschriftungen und Diagrammtitel verändert, besprechen wir in den nächsten Abschnitten. Auch die Farben der Box, des Hintergrunds und aller anderen Elemente im Diagramm können wir gezielt verändern. Nähere Informationen dazu findet man in der Hilfe-Datei help(par). Tipp
Für Personen mit künstlerischer Begabung bietet R noch viel mehr Möglichkeiten. So kann man jede beliebige Farbe über dessen RGB-Code festlegen (s. rgb-Funktion). Enthält ein Diagramm mehrere Farben, kann man über sog. Farbpaletten Farben so auswählen, dass sie gut zusammenpassen (z. B. im Paket RColorBrewer; Neuwirth, 2014).
143
144
10 Datenvisualisierung
Darstellung der Daten in Abhängigkeit von weiteren Variablen Wir können die Darstellung von Datenpunkten und Linien nicht nur beeinflussen, um hübsche Diagramme zu erstellen, sondern auch, um mehr als zwei Variablen zu visualisieren. So können wir z. B. festlegen, dass die Farbe, Form oder Größe der Datenpunkte von der Ausprägung einer dritten Variablen abhängt. Auch die Größe und Art der Linie können wir von der Ausprägung einer weiteren Variablen abhängig machen. Dazu geben wir in den entsprechenden Argumenten nicht wie bisher konkrete Werte ein, sondern die Variable, die hier dargestellt werden soll. Bei dieser Variablen muss es sich um einen numerischen Vektor handeln. In unserem Datenbeispiel enthält die Variable werbung Informationen darüber, ob an dem Tag Werbung für die Studie gemacht wurde oder nicht. Im folgenden Befehl wird die Ausprägung dieser Variablen in der Form der Datenpunkte dargestellt (Argument pch). Da es sich bei der Variablen werbung um einen Faktor handelt, wird dieser mit der Funktion as.numeric in einen numerischen Vektor umgewandelt (s. Abschn. 7.2.3). Das Ergebnis dieses Befehls ist in Abbildung 10.3 links dargestellt. > plot(vpn$tag, vpn$n, type = "b", pch = as.numeric(vpn$werbung))
Unser Diagramm hat jetzt noch einen entscheidenen Haken: Wir wissen nicht, wofür die Symbole stehen. In Abschnitt 10.1.3 kommen wir auf dieses Diagramm zurück und fügen eine Legende hinzu.
Abbildung 10.3 Im Streudiagramm links ist die Form der Datenpunkte abhängig von der Ausprägung auf der Drittvariablen werbung. Im Streudiagramm rechts wurden Achsenskalierung und Achsenbeschriftung angepasst.
10.1
Einführung in die klassischen Grafik-Funktionen
Achsenskalierung und Achsenbeschriftung Der Wertebereich der x- und y-Achse wird automatisch so festgelegt, dass sie dem tatsächlichen Wertebereich der zu visualisierenden Variablen entsprechen. Um die Achsenskalierung zu verändern, verwenden wir das Argument xlim = c(min, max) für den Wertebereich der x-Achse und das Argument ylim = c(min, max) für den Wertebereich der y-Achse. Bei der Achsenbeschriftung unterscheiden wir zwischen zwei verschiedenen Elementen: die Werte der Achse (auf Englisch auch als Tick Marks bezeichnet) sowie den Titel der Achse (auf Englisch auch als Axis Label bezeichnet). Die Werte der Achse versucht R so zu beschriften, dass möglichst runde Zahlen verwendet werden und dass der Abstand zwischen den Wertebeschriftungen immer gleich groß ist. In den allermeisten Fällen machen diese Standardeinstellungen Sinn. Wenn man die Wertebeschriftungen ändern möchte, muss man zunächst innerhalb der plot-Funktion die Beschriftung der Achse mit den Argumenten xaxt = "n" (für die x-Achse) bzw. yaxt = "n" (für die y-Achse) unterdrücken und anschließend mit der axis-Funktion die Achse nachträglich zum Diagramm hinzufügen (s. Abschn. 10.1.3). Die Wertebeschriftungen sind standardmäßig auf der x-Achse horizontal und auf der y-Achse vertikal ausgerichtet. Mit dem Argument las steuert man die Ausrichtung der Wertebeschriftungen. Hier gibt man eine Zahl ein, die für eine bestimmte Ausrichtung steht (s. Hilfe-Datei help(par)). Mit las = 1 werden alle Beschriftungen horizontal ausgerichtet (was meistens am besten lesbar ist). Wir können außerdem der Achse einen Titel geben, z. B. den Namen der Variablen, die dort dargestellt ist. Beim Streudiagramm werden die beiden im Befehl angegebenen Variablen bereits automatisch als Achsentitel übernommen. Die Achsentitel verändern wir mit den Argumenten xlab (Label der x-Achse) bzw. ylab (Label der y-Achse). Im folgenden Befehl ändern wir die Wertebereiche der beiden Achsen, die Ausrichtung der Wertebeschriftung und geben beiden Achsen neue Titel (s. Abb. 10.3 rechts). > plot(vpn$tag, vpn$n, type = "b", xlim = c(.8, 5.2), ylim = c(0, 100), las = 1, xlab = "Tag", ylab = "Anzahl Versuchspersonen")
145
146
10 Datenvisualisierung
Wir können zudem das Aussehen der Beschriftungen verändern. Tabelle 10.4 gibt einen Überblick über verschiedene Argumente, mit denen wir die Schriftgröße, den Schriftschnitt sowie die Farbe verschiedener Textelemente verändern können. Bei der Schriftgröße werden Varianten des cex-Arguments verwendet, das wir oben schon zur Beeinflussung der Größe der Datensymbole kennengelernt haben. Auch hier geben wir eine Zahl ein, die angibt, um welchen Faktor relativ zur Standardeinstellung die Größe des Textelements geändert werden soll. Der sog. Schriftschnitt (z. B. kursive oder fette Schreibweise) wird mit den Varianten des Arguments font verändert. Hier steht 1 für normalen Text (Standardeinstellung), 2 für fett, 3 für kursiv und 4 für fett und kursiv. Die Farbe der Textelemente geben wir in den jeweiligen Varianten des col-Arguments an. Farben werden hier genauso angegeben wie wir es oben besprochen haben. Tabelle 10.4 Argumente für die Veränderung der Schriftgröße, des Schriftschnitts sowie der Farbe verschiedener Textelemente in einem Diagramm
Textelement
Schriftgröße
Schriftschnitt
Farbe
Achsenbeschriftung
cex.axis
font.axis
col.axis
Achsentitel
cex.lab
font.lab
col.lab
Titel
cex.main
font.main
col.main
Untertitel
cex.sub
font.sub
col.sub
10.1.3 Wie fügt man Elemente zum Diagramm hinzu? Es kommt häufig vor, dass wir bestimmte Elemente zu einem bereits erstellten Diagramm hinzufügen möchten, z. B. Beschriftungen, Legenden oder weitere Daten. Diese zusätzlichen Elemente werden, bis auf wenige Ausnahmen, über eigene Funktionen hinzugefügt. Das bedeutet konkret: Zuerst erstellen wir das Diagramm, und anschließend fügen wir in einem separaten Befehl die weiteren Elemente dazu. Legende hinzufügen In diesem Abschnitt schauen wir uns beispielhaft an, wie man eine Legende zu einem bestehenden Diagramm hinzufügt. Oben hatten wir ein Diagramm erstellt, in dem die Form der Datenpunkte von den Ausprägungen einer dritten Variablen abhing. Hier noch einmal der Befehl für dieses Diagramm (s. Abb. 10.3 links): > plot(vpn$tag, vpn$n, type = "b", pch = as.numeric(vpn$werbung))
10.1
Einführung in die klassischen Grafik-Funktionen
Nachdem wir das Diagramm mit dem Befehl oben erstellt haben, fügen wir eine Legende mit der legend-Funktion hinzu. Diese Funktion hat mindestens drei Argumente: Position der Legende im Diagramm. Die Position kann entweder über die x- und y-Koordinaten angegeben werden oder über die Bezeichnung der Position: "bottomright", "bottom", "bottomleft", "left", "topleft", "top", "topright", "right" oder "center". Bezeichungen der Gruppen. An zweiter Stelle geben wir einen Vektor an, der die Bezeichnungen der unterschiedlichen Ausprägungen der Variablen enthält, so wie sie in der Legende erscheinen sollen. Grafische Darstellung der Gruppen. Hier geben wir an, mit welchem grafischen Element die Gruppen unterschieden werden. Dazu geben wir das entsprechende Argument an (z. B. pch für Form der Datenpunkte, col für Farbe, lty für Linientyp) sowie einen Vektor, der die entsprechenden Einstellungen für die Gruppen enthält. Geben wir z. B. lty = c(1, 2) an, wird die erste Ausprägung mit einer durchgezogenen Linie gekennzeichnet und die zweite Ausprägung mit einer gestrichelten Linie. Um für unser oben erstelltes Diagramm eine Legende erstellen zu können, müssen wir erstmal selbst herausfinden, welche Form der Datenpunkte für welche Ausprägung steht. Wir haben dort unseren Faktor werbung in einen numerischen Vektor transformiert. Aber welche numerischen Werte wurden für welche Faktorstufe vergeben? Das können wir herausfinden, indem wir die levels-Funktion auf den Faktor anwenden: > levels(vpn$werbung) [1] "Keine Werbung" "Werbung"
Die erste hier aufgeführte Ausprägung erhält den numerischen Wert 1, die zweite Ausprägung erhält den numerischen Wert 2. Eine Möglichkeit, das direkt in den Daten zu überprüfen, besteht darin, eine Kontingenztabelle für den Faktor und den numerischen Vektor zu erstellen: > table(vpn$werbung, as.numeric(vpn$werbung)) 1 2 Keine Werbung 2 0 Werbung 0 3
147
148
10 Datenvisualisierung
Hier können wir erkennen, dass Fälle, die auf dem Faktor die Ausprägung Keine Werbung hatten, auf dem numerischen Vektor die Ausprägung 1 erhalten, usw. In unserem Diagramm haben wir mit pch = as.numeric(vpn$werbung) angegeben, dass die Form der Datenpunkte von der Ausprägung auf dem numerischen Vektor abhängt. Jetzt wissen wir also, dass für die Tage ohne Werbung das Symbol pch = 1 (Kreis) gewählt wurde und für Tage mit Werbung das Symbol pch = 2 (Dreieck). Mit dieser Information erstellen wir jetzt die Legende: > legend("topleft", c("Keine Werbung", "Werbung"), pch = c(1,2))
Achtung: Die Reihenfolge der Werte im pch-Argument muss exakt der Reihenfolge der Ausprägungen im zweiten Argument entsprechen, sonst ist die Zuordnung in der Legende falsch. Das Aussehen der Legende können wir über weitere Argumente innerhalb der legend-Funktion anpassen. Weitere Informationen dazu erhalten wir mit help(legend).
Abbildung 10.4 Streudiagramm, in dem die Form der Datenpunkte abhängig ist von der Ausprägung der Drittvariablen werbung. Die Legende gibt die Zuordnung der Form der Datenpunkte zu den Ausprägungen dieser Drittvariablen an.
10.1
Einführung in die klassischen Grafik-Funktionen
Wir hätten uns das übrigens auch einfacher machen können, indem wir die Bezeichungen und die Zuordnungen der Datensymbole nicht manuell eingeben, sondern direkt aus den Daten bestimmen. Mit dem folgenden Befehl erhalten wir dieselbe Legende wie eben. Das Diagramm mit Legende ist in Abbildung 10.4 dargestellt. > legend("topleft", levels(vpn$werbung), pch = as.numeric(vpn$werbung))
Weitere Funktionen für zusätzliche Diagramm-Elemente Wir haben hier leider nicht den Platz, jede Funktion für zusätzliche Elemente im Detail zu besprechen. Einige dieser Funktionen werden uns aber in Abschnitt 10.3 oder in späteren Kapiteln begegnen. Nähere Informationen zu diesen Funktionen erhält man außerdem wie immer über die dazugehörigen Hilfe-Dateien. Unter anderem stehen dafür die folgenden Funktionen zur Verfügung: lines() für Linien (z. B. Abschn. 10.3.2) points() für Datenpunkte abline() für Geraden, z. B. Regressionsgeraden (s. Abschn. 10.3.5) arrows() für Pfeile title() für Diagrammtitel. Der Titel des Diagramms kann auch über das Argument main festgelegt werden. Um einen voreingestellten Titel eines Diagramms zu unterdrücken, verwenden wir das Argument main = "". text() für Texte innerhalb des Diagramms axis() für Achsen und Achsenbeschriftungen curve(..., add = TRUE) für Funktionskurven (s. Abschn. 11.1) legend() für Legenden (s. o.) symbols() für Symbole
10.1.4 Wie kann man mehrere Diagramme anordnen? Wenn man mehrere Diagramme zusammen präsentieren möchte, kann man diese Diagramme schon in R zusammenstellen lassen und in einer einzigen Datei abspeichern. Dafür braucht man den folgenden Befehl: > par(mfrow = c(a, b))
Mit der par-Funktion kann man diverse Parameter in einem Diagramm verändern. Einer dieser Parameter ist mfrow (für »multiframe row«). Dieser Befehl geht immer mit einem Vektor c(a, b) einher, in dem angegeben wird, wie viele Diagramme pro
149
150
10 Datenvisualisierung
Zeile (a) und pro Spalte (b) in der Abbildung erscheinen sollen. Wenn man also zwei Diagramme untereinander abbilden möchte, führt man zunächst den Befehl par(mfrow = c(2, 1)) aus und erstellt anschließend die beiden Diagramme. Diese Einstellung gilt so lange, bis man sie mit par(mfrow = c(1, 1)) wieder zurücksetzt.
10.2 Einführung in ggplot2 10.2.1 Wie legt man die Art des Diagramms fest? Die Abkürzung gg im Namen des ggplot2-Pakets (Wickham, 2016) steht für »Grammar of Graphics«. Dahinter verbirgt sich ein bestimmtes System, durch das Daten in grafische Elemente übersetzt werden. Die Grundidee dieser Grammatik ist folgende: Jedes Diagramm basiert auf bestimmten Daten. Diese Daten müssen als Data Frame gespeichert sein und »tidy« sein, also eine aufgeräumte Datenstruktur haben (s. Abschn. 7.1). Die Eigenschaften der Daten (z. B. bestimmte Werte) werden in bestimmte visuelle Eigenschaften übersetzt (sog. aesthetic attributes, z. B. Position im Koordinatensystem oder Größe oder Farbe von grafischen Elementen). Diese visuellen Eigenschaften können in verschiedenen geometrischen Objekten (z. B. Punkte oder Linien) dargestellt werden. Das klingt sehr abstrakt, daher machen wir uns das an einem einfachen Beispiel klar. Wir möchten die Daten aus dem Data Frame vpn visualisieren. Dazu müssen wir zunächst festlegen, welche Variablen überhaupt visualisiert werden sollen und an welcher Stelle im Diagramm. Wir legen fest, dass die Variable tag auf der x-Achse des Diagramms und die Variable n auf der y-Achse des Diagramms dargestellt werden soll. Wir können außerdem festlegen, dass die dritte Variable werbung in der Form, Farbe oder Größe bestimmter grafischer Elemente dargestellt werden soll. Das lassen wir jetzt aber erstmal noch weg. Anschließend müssen wir entscheiden, ob die Daten als Punkte, als Linie oder vielleicht ganz anders dargestellt werden. Wir müssen also die geometrische Form festlegen. Diese drei Elemente – Daten, Ästhetik und geometrische Form – sind die Basis jedes ggplot-Befehls. Für unser Beispiel könnte das so aussehen: > ggplot(data = vpn, aes(x = tag, y = n)) + geom_point()
Im ersten Argument geben wir die Daten an, die hier visualisiert werden sollen. Im zweiten Argument legen wir in der aes-Funktion die Ästhetik des Diagramms fest,
10.2
Einführung in ggplot2
d. h., wir weisen jeder Variablen eine bestimmte Position im Diagramm zu. In diesem Beispiel legen wir fest, dass die Variable tag auf der x-Achse und die Variable n auf der y-Achse dargestellt werden soll. Mit der Funktion geom_point legen wir die geometrische Darstellung fest: Hier wird ein Punktediagramm erstellt. Das damit erzeugte Diagramm ist in Abbildung 10.5 oben links dargestellt. Vielleicht ist Ihnen aufgefallen, dass die geom_point-Funktion nicht als Argument innerhalb der ggplot-Funktion auftaucht, sondern als eigener Befehl darunter steht. Die beiden Befehle werden mit dem Plus-Zeichen am Ende der ersten Zeile verknüpft. Das Plus-Zeichen muss unbedingt am Ende der Zeile und nicht am Anfang der nächsten Zeile stehen, da R sonst nicht merkt, dass der Befehl noch weitergeht! Diese Schreibweise ist eine Besonderheit von ggplot2 und ein Grund, warum dieses Paket für R-Einsteiger etwas gewöhnungsbedürftig ist, denn hier weicht die Syntax des Pakets von der uns bekannten Syntax der R-Sprache ab. Der Name des Pakets täuscht nicht: Es handelt sich hierbei tatsächlich um eine eigene Grammatik. Diese Grammatik ist aber ebenfalls sehr logisch aufgebaut und für die Erstellung von Diagrammen wesentlich flexibler und vielseitiger als die klassischen R-Funktionen für Diagramme, weshalb dieses Paket trotz der abweichenden Syntax so beliebt ist. Der Diagrammtyp wird in ggplot2 also über die geom-Funktionen festgelegt. Davon gibt es jede Menge – die gängigsten sind in Tabelle 10.5 aufgelistet. Wenn wir also den Diagrammtyp ändern möchten, müssen wir lediglich die geom-Funktion im Befehl oben austauschen. Probieren Sie das mal mit unserem Datenbeispiel aus!
Tabelle 10.5 Ausgewählte geom-Funktionen aus dem ggplot2-Paket
geom-Funktion
Beschreibung
geom-Funktion
Beschreibung
geom_abline
Geraden
geom_violin
Violin-Plot
geom_bar
Säulen
geom_line
Linien
geom_boxplot
Boxplots
geom_step
Stufen
geom_density
Kerndichte
geom_point
Punkte
geom_dotplot
Dotplot
geom_qq
Q-Q-Plot
geom_smooth
Anpassungskurve
geom_area
Fläche
geom_jitter
Punkte mit zufälliger Streuung
geom_segment, geom_curve
Segmente und Funktionskurven
151
152
10 Datenvisualisierung
Wir können auch mehrere geom-Funktionen in einem Diagramm kombinieren. Im folgenden Befehl kombinieren wir Punkte und Linien (vgl. type = "b" in Abschn. 10.1.1). Das mit diesem Befehl erstellte Diagramm ist in Abbildung 10.5 oben rechts zu sehen. > ggplot(data = vpn, aes(x = tag, y = n)) + geom_point() + geom_line()
Abbildung 10.5 Verschiedene mit der ggplot-Funktion erstellte Diagramme. Oben links wurde nur geom_point verwendet. Oben rechts wurden geom_point und geom_line kombiniert. Unten links wurde die Form und Größe der Datenpunkte innerhalb von geom_point mit den Argumenten size und shape geändert. Unten rechts wurden Linientyp und Linienstärke innerhalb von geom_line mit den Argumenten linetype und size geändert.
10.2.2 Wie verändert man das Aussehen des Diagramms? Das Erscheinungsbild des Diagramms wird über zwei Aspekte beeinflusst: die grafische Darstellung der geometrischen Objekte (also der Daten selbst) sowie die Dar-
10.2
Einführung in ggplot2
stellung der anderen Elemente (z. B. Hilfslinien, Hintergrund) im Diagramm. Letzteres wird über sog. Themen (themes) gesteuert, die wir am Ende dieses Abschnitts besprechen. Wir beginnen mit den geometrischen Objekten. Die grafische Darstellung der geometrischen Objekte wird über zusätzliche Argumente beeinflusst, die an zwei Stellen im ggplot-Befehl eingefügt werden können: innerhalb der aes-Funktion zu Beginn des Befehls oder innerhalb der jeweiligen geom-Funktion. Einstellungen, die wir in der aes-Funktion vornehmen, werden so für alle geometrischen Objekte des Diagramms übernommen, es sei denn, es wird explizit etwas anderes angegeben. Wenn wir z. B. in der aes-Funktion das Argument col = "red" ergänzen, dann werden alle geometrischen Objekte in Rot dargestellt, sofern nicht in der jeweiligen geom-Funktion explizit eine andere Farbe angefordert wird. Einstellungen, die wir in den geom-Funktionen vornehmen, gelten nur für dieses spezifische geometrische Objekt. Form und Größe der Datenpunkte Die Form der Datenpunkte legen wir im Argument shape fest. Genau wie beim pchArgument der klassischen R-Funktionen für Diagramme können wir auch hier das gewünschte Symbol in Anführungszeichen eingeben oder den Code für ein bestimmtes Symbol ohne Anführungszeichen angeben (s. Abb. 10.2). Mit dem Argument size legen wir die Größe der Datenpunkte in Millimetern fest. Mit dem folgenden Befehl werden die Datenpunkte als ausgefüllte Dreiecke mit einem Durchmesser von 3 mm dargestellt (s. Abb. 10.5 unten links). > ggplot(data = vpn, aes(x = tag, y = n)) + geom_point(shape = 17, size = 3) + geom_line()
Typ und Stärke der Linien Der Linientyp wird über das Argument linetype gesteuert. Wir geben hier dieselben Werte an wie beim lty-Argument der klassischen R-Funktionen (s. Tab. 10.2). Die Linienstärke wird über das Argument size gesteuert. Wir geben hier die gewünschte Linienstärke in Millimetern an. Mit dem folgenden Befehl werden die Linien gepunktet (Linientyp 3) und mit einer Linienstärke von 2 mm dargestellt (s. Abb. 10.5 unten rechts). > ggplot(data = vpn, aes(x = tag, y = n)) + geom_point() + geom_line(linetype = 3, size = 2)
153
154
10 Datenvisualisierung
Farben Die Farben der geometrischen Objekte steuern wir über das Argument col. Hier wird entweder der Name oder der RGB-Code (d. h., der Rot-Grün-Blau-Code, s. Abschn. 10.1.2) der gewünschten Farbe in Anführungszeichen angegeben. Eine vollständige Auflistung aller namentlich benannten Farbtöne erhalten wir mit colors(). Mit dem folgenden Befehl werden die Punkte in rot und die Linien in blau dargestellt. > ggplot(data = vpn, aes(x = tag, y = n)) + geom_point(col = "red") + geom_line(col = "blue")
Darstellung der Daten in Abhängigkeit von weiteren Variablen Auch in ggplot2 können wir die Darstellung der Daten (hier: der geometrischen Objekte) von der Ausprägung von weiteren Variablen abhängig machen und somit Informationen über mehr als zwei Variablen visualisieren. Dazu müssen wir zunächst die Drittvariable in die aes-Funktion aufnehmen, denn hier wird festgelegt, wie die Werte dieser Variablen visualisiert werden sollen, z. B. über die Farbe (col), Form (shape für Symbole oder linetype für Linientypen) oder Größe (size) der geometrischen Objekte. Im folgenden Befehl legen wir fest, dass die Ausprägungen der Drittvariablen werbung durch unterschiedliche Formen der Datenpunkte visualisiert werden sollen. Damit wir die Form der Datenpunkte besser erkennen können, haben wir außerdem deren Größe auf 3 mm vergrößert (size = 3). > ggplot(data = vpn, aes(x = tag, y = n, shape = werbung)) + geom_point(size = 3)
Das damit erzeugte Diagramm ist in Abbildung 10.6 links dargestellt. Wir sehen, dass manche Datenpunkte als Kreise und andere als Dreiecke dargestellt werden. Besonders praktisch: Die Bedeutung dieser Symbole wird automatisch in einer Legende angegeben, die wir im Gegensatz zu den klassischen R-Funktionen also nicht selbst hinzufügen müssen. Wenn wir mit den von ggplot2 gewählten Formen, Farben oder Größen nicht einverstanden sind, können wir diese über zusätzliche Funktionen einstellen. Die Namen dieser Funktion beginnen immer mit scale, gefolgt von dem Namen des grafischen Elements, das wir beeinflussen möchten (z. B. _color_, _linetype_,
10.2
Einführung in ggplot2
_shape_ oder _size_) und einem Stichwort, das festlegt, auf welche Art die Einstel-
lungen festgelegt werden sollen (z. B. manual, wenn man die Werte selbst festlegen möchte). Mit dem folgenden Befehl erreichen wir, dass die Symbole 16 (gefüllter Kreis) und 18 (gefüllte Raute) und die Farben rot und blau verwendet werden sollen. > ggplot(data = vpn, aes(x = tag, y = n, col = werbung, shape = werbung)) + geom_point(size = 3) + scale_shape_manual(values = c(16, 18)) + scale_color_manual(values = c("red", "blue"))
Abbildung 10.6 Im Streudiagramm links sind Größe und Form der Datenpunkte abhängig von der Ausprägung auf der Drittvariablen werbung. Im Streudiagramm rechts wurden die Beschriftungen und Wertebereiche der Achsen geändert.
Achsenskalierung und Achsenbeschriftung Die Eigenschaften der beiden Achsen legen wir mit zusätzlichen Funktionen fest, die jeweils mit scale_x bzw. scale_y beginnen. Handelt es sich bei den Achsen um kontinuierliche Achsen, verwenden wir die Funktionen scale_x_continuous und scale_y_continuous. Man kann auch andere Achsen definieren, z. B. Achsen mit diskreten Werten, wenn eine Variable als Faktor definiert ist (scale_x_discrete bzw. scale_y_discrete), logarithmische Achsen (scale_x_log10 bzw. scale_y_log10) und viele andere.
155
156
10 Datenvisualisierung
Die Eigenschaften der Achsen legen wir mit Argumenten innerhalb dieser Funktionen fest, z. B. name für den Achsentitel, limits für den Wertebereich, breaks für die Wertemarkierungen (die sog. Tick Marks) und labels für die Wertebeschriftungen. Achsentitel können auch separat über die Funktionen xlab bzw. ylab geändert werden. Im folgenden Befehl ändern wir die Wertebereiche und Achsentitel für unser Diagramm (s. Abb. 10.6 rechts): > ggplot(data = vpn, aes(x = tag, y = n)) + geom_point() + geom_line() + scale_x_continuous(limits = c(.8, 5.2), name = "Tag") + scale_y_continuous(limits = c(0,100), name = "Anzahl Versuchspersonen")
Themen Bisher haben wir besprochen, wie man einzelne Elemente im Diagramm anpassen kann. Es ist aber auch möglich, das gesamte Erscheinungsbild zu verändern. Dazu verwenden wir sog. Themen, die sozusagen den Stil des Diagramms festlegen. Das Thema wird als neue Funktion zum Befehl hinzugefügt. Tabelle 10.6 gibt einen Überblick über verschiedene Themen, die im ggplot2-Paket enthalten sind. Das Paket ggthemes (Arnold, 2019) enthält eine Reihe weiterer Themen, die teilweise am Stil bekannter Publikationen angelehnt sind. Das Paket jtools (Long, 2019b) enthält das Thema theme_apa, das sich an den Formatierungsvorgaben der American Psychological Association (APA) orientiert. Tabelle 10.6 Ausgewählte ggplot2-Themen. Standardeinstellung ist theme_gray.
Thema
Beschreibung
theme_gray()
Grauer Hintergrund, weiße Hilfslinien
theme_bw()
Weißer Hintergrund, graue Hilfslinien
theme_minimal()
Weißer Hintergrund, minimale Elemente, keine Achsen
theme_classic()
Weißer Hintergrund, keine Hilfslinien
Im folgenden Befehl wenden wir das Thema theme_bw (kurz für black and white) auf das Diagramm an. > ggplot(data = vpn, aes(x = tag, y = n)) + geom_point() + geom_line() + theme_bw()
10.2
Einführung in ggplot2
Wenn uns kein Thema so richtig gefällt, können wir innerhalb der theme-Funktion weitere Einstellungen vornehmen. Nähere Informationen zu den möglichen Einstellungen finden wir unter help(theme).
10.2.3 Wie fügt man Elemente zum Diagramm hinzu? Zusätzliche Elemente, die aus Daten berechnet werden, fügt man mit der passenden geom-Funktion hinzu (s. Tab. 10.5). Wir haben das oben bereits getan, als wir sowohl Datenpunkte als auch Linien in das Diagramm eingefügt haben. Im entsprechenden Abschnitt zu den klassischen Grafik-Funktionen haben wir uns ausführlich angeschaut, wie man eine Legende zu einem Diagramm hinzufügt. In ggplot2 ist das nicht notwendig, da Legenden bereits automatisch hinzugefügt werden, sobald wir die Ausprägungen von Variablen grafisch unterscheiden. Das Aussehen der Legende kann über die scale-Funktion und über die theme-Funktion (s. Abschn. 10.2.2) gesteuert werden. Andere Elemente können wir mit der annotate-Funktion hinzufügen. In dieser Funktion gibt man zunächst an, was für eine Art von Element man hinzufügen möchte, z. B. "text" für Texte oder "segment" für Pfeile oder Flächen. Für das Hinzufügen von Diagrammtiteln gibt es eine eigene Funktion: ggtitle. Leider können wir aus Platzgründen diese Funktionen hier nicht im Detail besprechen. Einige werden uns aber an späterer Stelle begegnen. Wie immer hilft ansonsten ein Blick in die entsprechenden Hilfe-Dateien weiter.
10.2.4 Wie kann man mehrere Diagramme anordnen? Das patchwork-Paket (Pedersen, 2019) ist besonders geeignet, um mehrere Diagramme in einer Grafik anzuordnen. Dazu machen wir uns zunächst zunutze, dass man ggplot-Diagramme als Objekte speichern kann. Im folgenden Beispiel erstellen wir drei Diagramme, die wir zunächst unter den Objektnamen p1, p2 und p3 speichern. Es handelt sich jedesmal um unsere Beispieldaten, die in p1 als Punktediagramm, in p2 als Liniendiagramm und in p3 als Fläche dargestellt werden. > p1 p2 p3 (p1 + p2) / p3
Lassen wir die Klammern weg, wird p1 in der linken Spalte gezeigt und p2 und p3 untereinander in der rechten Spalte.
10.3 Ausgewählte Diagramme In diesem Abschnitt besprechen wir eine Reihe von Diagrammen, die in den Sozialwissenschaften besonders häufig zum Einsatz kommen. Die Diagramme werden jeweils sowohl mit klassischen Grafik-Funktionen als auch mit ggplot2 erstellt. Die Datenbeispiele in diesem Abschnitt beziehen sich auf den Datensatz erstis.RData.
10.3.1 Säulendiagramme für Häufigkeiten Säulendiagramme dienen dazu, die Häufigkeiten für die verschiedenen Ausprägungen einer Variablen darzustellen. Dabei werden die Ausprägungen der Variablen auf der x-Achse und die absoluten oder relativen Häufigkeiten für jede Ausprägung auf der y-Achse abgetragen. Die Häufigkeiten werden als Säulen dargestellt, d. h., je höher eine Säule ist, desto häufiger kommt diese Merkmalsausprägung vor. Im Folgenden möchten wir die Häufigkeiten der Variable wohnort.alt darstellen. Einfaches Säulendiagramm mit der barplot-Funktion Mit den R-Basisfunktionen erstellen wir Säulendiagramme mit der Funktion barplot. Aber Vorsicht: Wenn wir jetzt einfach den Variablennamen in die Funktion einsetzen, erhalten wir die folgende Fehlermeldung: > barplot(erstis$wohnort.alt) FEHLER: ‘height’ must be a vector or a matrix
Die Lösung besteht darin, dass wir auf die Häufigkeitstabelle zurückgreifen, die wir bereits in Abschnitt 8.1 kennengelernt haben. Wir speichern diese Tabelle in einem neuen Objekt, das wir hier als tab bezeichnen. > tab tab wohnort.alt alte BL neue BL 32 26
Berlin Ausland 86 18
159
160
10 Datenvisualisierung
Jetzt wenden wir die barplot-Funktion auf diese Häufigkeitstabelle an (s. Abb. 10.8 oben links): > barplot(tab)
Die barplot-Funktion baut auf der plot-Funktion auf. Wir können daher das Aussehen dieses Diagramms mit den in Abschnitt 10.1.2 besprochenen Argumenten anpassen. Im folgenden Beispiel wurden der Wertebereich und die Beschriftung der y-Achse sowie die Farbe der Säulen geändert (s. Abb. 10.8 oben rechts): > barplot(tab, ylim = c(0,100), ylab = "Häufigkeit", col = 1, las = 1)
Um statt der absoluten Häufigkeiten die relativen Häufigkeiten darzustellen, müssen wir auf die mit der table-Funktion erstellte Häufigkeitstabelle noch die prop.table-Funktion anwenden (s. Abschn. 9.1). Tipp
Mit dem Argument horiz = TRUE werden die Häufigkeiten nicht als vertikale Säulen, sondern als horizontale Balken dargestellt.
Gestapelte und gruppierte Säulendiagramme mit der barplot-Funktion Bisher haben wir uns nur die Häufigkeit einer einzigen Variablen angeschaut. Man kann aber auch die Häufigkeiten für zwei miteinander kombinierte Variablen grafisch darstellen. Dafür greifen wir auf die Kontingenztabelle zurück, die wir in Abschnitt 9.1 besprochen haben. Die Kontingenztabelle wird wieder mit der tableFunktion angefordert. Das folgende Beispiel zeigt eine Kontingenztabelle für die Variablen wohnort.alt und geschl: > tab2 tab2 alte BL neue BL Berlin Ausland weiblich 24 16 54 14 männlich 8 9 29 4
Auf diese Tabelle wenden wir nun wiederum die barplot-Funktion an: > barplot(tab2, legend = TRUE)
10.3
Ausgewählte Diagramme
Wir erhalten dann das gestapelte Säulendiagramm in Abbildung 10.8 unten links. In diesem Diagramm sind die Ausprägungen der Variablen wohnort.alt auf der x-Achse abgetragen. Für jede Spalte in der oben erstellten Kontingenztabelle erhalten wir hier also eine separate Säule. Die Säulen sind in unterschiedliche Farbschichten unterteilt. Jede Farbschicht symbolisiert eine Ausprägung der Variablen geschl. Welche Farbe zu welcher Ausprägung gehört, können wir der Legende entnehmen. Die Legende wurde mit dem Argument legend = TRUE angefordert. Wenn wir statt der Variablen wohnort.alt lieber die Variable geschl auf der x-Achse dargestellt haben möchten, müssen wir die Position der Variablen innerhalb der table-Funktion tauschen.
Abbildung 10.8 Verschiedene Säulendiagramme, erstellt mit der barplot-Funktion
161
162
10 Datenvisualisierung
Die Häufigkeiten für mehrere Variablen werden eher selten in den eben vorgestellten gestapelten Säulendiagrammen dargestellt. Stattdessen bevorzugt man für diesen Fall das gruppierte Säulendiagramm. Um ein gruppiertes Säulendiagramm zu erhalten, müssen wir den oben besprochenen Befehl um das Argument beside = TRUE ergänzen. Der vollständige Befehl lautet dann: > barplot(tab2), legend = TRUE, beside = TRUE)
Das gruppierte Säulendiagramm ist in Abbildung 10.8 unten rechts dargestellt. Auch hier ist die Variable wohnort.alt auf der x-Achse abgetragen. Wir erhalten jetzt aber für jede Ausprägung dieser Variablen mehrere Säulen, nämlich jeweils eine für jede Ausprägung der Variablen geschl. Einfaches Säulendiagramm mit ggplot2 In ggplot2 müssen wir wie immer zunächst die Daten und die Zuordnung von Variablen zu grafischen Elementen (Ästhetik) definieren. Die geometrische Art der Darstellung legen wir anschließend in der entsprechenden geom-Funktion fest. Im folgenden Befehl müssen wir in der aes-Funktion nur eine Variable aufführen, die auf der x-Achse dargestellt werden soll. Mit der geom_bar-Funktion fordern wir ein Säulendiagramm an. > ggplot(erstis, aes(x = wohnort.alt)) + geom_bar()
Das damit erstellte Diagramm ist in Abbildung 10.9 oben links dargestellt. Dieses Diagramm hat fünf Säulen, obwohl der Faktor wohnort.alt doch nur vier Ausprägungen hat. Wenn wir genau schauen, sehen wir, dass die fünfte Säule die Häufigkeit der NA’s, also der fehlenden Werte wiedergibt. Wenn wir keine fehlenden Werte im Diagramm haben möchten, müssen wir zunächst alle Personen mit fehlenden Werten entfernen, z. B. mit der na.omit-Funktion oder mit der filter-Funktion aus dem dplyr-Paket (Wickham et al., 2020; s. Abschn. 7.3.2). Da dplyr und ggplot2 jeweils Pakete aus dem sog. tidyverse sind, können wir die Funktionen aus diesen Paketen sehr gut mithilfe der Pipe (%>%) verknüpfen (s. Abschn. 7.1). So wird zwar unser Befehl etwas länger, aber dafür müssen wir nicht extra einen neuen Data Frame anlegen. Im folgenden Befehl nehmen wir die erstis-Daten, filtern diese nach allen Personen, die auf der Variablen wohnort.alt keinen fehlenden Wert haben (!is.na bedeutet »ist kein fehlender Wert«), und erstellen anschließend mit diesen gefilterten Daten das Säulendiagramm. In der ggplot-Funktion müssen wir nun nicht noch einmal die Daten aufführen, da durch das Verwenden der Pipe klar ist, welche Daten
10.3
Ausgewählte Diagramme
verwendet werden sollen. Wir erhalten damit ein Säulendiagramm mit vier Säulen (s. Abb. 10.9 oben rechts). > erstis %>% filter(!is.na(wohnort.alt)) %>% ggplot(aes(x = wohnort.alt)) + geom_bar()
Abbildung 10.9 Verschiedene Säulendiagramme, erstellt mit der ggplot-Funktion
Gestapelte und gruppierte Säulendiagramme mit ggplot2 Um eine zweite Variable in dem Säulendiagramm darzustellen, ergänzen wir diese Variable im Argument fill in der aes-Funktion. Damit drücken wir aus, dass die Ausprägungen der zweiten Variablen durch unterschiedliche Farbfüllungen abgebildet werden sollen.
163
164
10 Datenvisualisierung > ggplot(erstis, aes(x = wohnort.alt, fill = geschl)) + geom_bar()
Wir erhalten damit das in Abbildung 10.9 unten links dargestellte gestapelte Säulendiagramm. Auch hier werden zusätzlich zu den Häufigkeiten der einzelnen Ausprägungen auch die Häufigkeiten der fehlenden Werte angegeben, und zwar diesmal für beide Variablen. Um dies zu unterdrücken, müssen wir wieder die Daten so filtern, dass Fälle mit fehlenden Werten auf einer dieser Variablen entfernt werden. Das machen wir im folgenden Befehl. Außerdem ergänzen wir hier in der geom_bar-Funktion das Argument position = "dodge" (engl. ausweichen). Damit erreichen wir, dass die Ausprägungen der Variablen geschl nicht als gestapelte Säulen, sondern als gruppierte Säulen dargestellt werden (s. Abb. 10.9 unten rechts). > erstis %>% filter(!is.na(wohnort.alt) & !is.na(geschl)) %>% ggplot(aes(x = wohnort.alt, fill = geschl)) + geom_bar(position = "dodge")
10.3.2 Histogramme und Kerndichte-Diagramme Histogramme und Kerndichte-Diagramme (auch: Kernel-Dichtediagramm oder density plot) sind gut geeignet, um die Verteilung von kontinuierlichen Variablen zu betrachten. Ein Histogramm ähnelt auf dem ersten Blick einem Säulendiagramm. Allerdings geben die einzelnen Säulen nicht die Häufigkeiten aller einzelnen Werte der Variablen, sondern die Häufigkeiten der Werte innerhalb eines bestimmten Intervalls an. In einem Kerndichte-Diagramm wird die Verteilung der Variablen mit einer durchgezogenen Kurve dargestellt. In den folgenden Beispielen betrachten wir die Verteilung der Variablen alter aus dem Datensatz erstis.RData. Histogramm und Kerndichte-Diagramm mit klassischen R-Funktionen Für die Erstellung eines Histogramms gibt es in den R-Basispaketen eine eigene Funktion, die auf der plot-Funktion aufbaut. Für unser Datenbeispiel lautet der Befehl: > hist(erstis$alter)
Das Ergebnis ist in Abbildung 10.10 links dargestellt. Die Breite und Anzahl der Säulen wird automatisch festgelegt. Mit dem Argument breaks kann man die Anzahl der Säulen beeinflussen. Dabei hält sich R allerdings nicht immer genau an unsere Vorgaben. Wenn wir hier eine 10 eintragen, dann werden wir ungefähr zehn Säulen
10.3
Ausgewählte Diagramme
erhalten, es können aber auch 8 oder 15 Säulen werden. Wichtig ist vor allem: Je größer diese Zahl, desto schmaler sind die Intervalle und desto mehr Säulen werden gebildet. Geben wir z. B. breaks = 15 ein, erhöht sich die Anzahl der Säulen und der Wertebereich jeder Säule wird entsprechend kleiner. Dadurch kann sich auch die Form der Verteilung deutlich ändern. Es ist daher ratsam, die Anzahl der Säulen stets ein wenig zu variieren, um zu schauen, ob diese Einstellung einen Effekt auf die Form der Verteilung hat. Die hist-Funktion baut auf der plot-Funktion auf und kann daher mit den in Abschnitt 10.1.2 besprochenen Argumenten verändert werden. Ein Beispiel für ein angepasstes Histogramm finden Sie im R-Skript zu diesem Kapitel.
Abbildung 10.10 Histogramm (links) und Kerndichte-Diagramm (rechts) erstellt mit klassischen Grafik-Funktionen ohne weitere Anpassungen
Im Kerndichte-Diagramm wird die Form der Verteilung als durchgezogene Kurve dargestellt. Wir erstellen nun ein Kerndichte-Diagramm für die Variable alter. Dazu brauchen wir die plot-Funktion und die density-Funktion. > plot(density(erstis$alter, na.rm = TRUE))
Mit der density-Funktion werden die Dichtewerte für jede Stelle der Variablen alter berechnet. Ähnlich wie die mean-Funktion und andere Funktionen für deskriptive Statistiken muss hier das Argument na.rm = TRUE ergänzt werden, falls die Variable fehlende Werte enthält (s. Abschn. 8.2.3). Das Diagramm selbst erstellen wir dann mit der plot-Funktion. Das damit erstellte Diagramm ist in Abbildung 10.10
165
166
10 Datenvisualisierung
rechts dargestellt. Auch dieses Diagramm können wir wieder mit zusätzlichen Argumenten verschönern. Ein Beispiel dafür finden Sie im R-Skript zu diesem Kapitel. Da sowohl das Histogramm als auch das Kerndichte-Kurve jeweils Vor- und Nachteile haben, werden diese beiden Darstellungsarten gerne in einem Diagramm kombiniert. Dazu erstellen wir zunächst das Histogramm mit der hist-Funktion und fügen anschließend die Kerndichtekurve mit der lines-Funktion hinzu. Dabei gibt es aber noch ein Problem. Betrachten Sie mal die y-Achsen der beiden Diagramme oben. Im Histogramm werden auf der y-Achse die absoluten Häufigkeiten abgetragen, im Kerndichte-Diagramm dagegen die Dichtewerte, die so normiert sind, dass die gesamte Fläche unterhalb der Kurve den Wert 1 hat. Um die beiden Darstellungsformen in einem Diagramm kombinieren zu können, müssen wir zunächst die y-Achse vereinheitlichen. Das erreichen wir, indem wir in der hist-Funktion das Argument freq = FALSE ergänzen. Dadurch werden nicht mehr die Häufigkeiten (freq steht hier für frequencies), sondern die Dichtewerte abgetragen. Der vollständige Befehl lautet dann: > hist(erstis$alter, freq = FALSE, ylim = c(0, .1), col = 8, main = "Alter", xlab = "") > lines(density(erstis$alter, na.rm = TRUE), lwd = 2)
Abbildung 10.11 Histogramm mit Kerndichte-Kurve in einem Diagramm, erstellt mit klassischen Grafik-Funktionen
10.3
Ausgewählte Diagramme
Diese Befehle enthalten einige zusätzliche Argumente, um das Diagramm zu verschönern. Zwingend notwendig ist davon nur das Argument freq = FALSE in der histFunktion und das Argument na.rm = TRUE in der density-Funktion. Das mit diesen Befehlen erstellte Diagramm finden Sie in Abbildung 10.11. Histogramm und Kerndichte-Diagramm mit ggplot2 In ggplot2 setzen wir die geom_histogram-Funktion ein, um Histogramme zu erzeugen (s. Abb. 10.12 oben links): > ggplot(erstis, aes(x = alter)) + geom_histogram()
Um die Anzahl der Säulen zu verändern, geben wir im Argument binwidth an, wie breit die einzelnen Säulen jeweils sein sollen. Auch hier gilt: Je schmaler die Säulen, desto größer ist die Anzahl der Säulen. Für Kerndichte-Diagramme haben wir in ggplot2 zwei geometrische Funktionen zur Auswahl: > ggplot(erstis, aes(x = alter)) + geom_density() > ggplot(erstis, aes(x = alter)) + geom_line(stat = "density")
Das mit diesen Befehlen erzeugte Diagramm ist in Abbildung 10.12 oben rechts abgebildet. Um ein Histogramm und ein Kerndichte-Diagramm in einem Diagramm zu kombinieren, müssen wir auch in ggplot2 zunächst dafür sorgen, dass jeweils die Dichtewerte und nicht die absoluten Häufigkeiten auf der y-Achse abgetragen werden. Das erreichen wir mit dem Argument y = ..density.., das wir in der aesFunktion ergänzen. Anschließend wenden wir die beiden geometrischen Funktionen nacheinander an. Im folgenden Befehl wurde zusätzlich noch die Breite, Randfarbe und Füllung der Säulen sowie die Dicke der Kerndichtekurve verändert und ein Achsentitel für die y-Achse vergeben. Das damit erzeugte Diagramm ist in Abbildung 10.12 unten dargestellt. > ggplot(erstis, aes(x = alter, y = ..density..)) + geom_histogram(binwidth = 3, col = "grey80", fill = "grey50") + geom_line(stat = "density", size = 1.5) + ylab("Dichte")
167
168
10 Datenvisualisierung
Abbildung 10.12 Verschiedene Histogramme und Kerndichte-Diagramme, erstellt mit ggplot2
Gruppierte Histogramme und Kerndichtekurven Um zu prüfen, ob die Verteilung einer kontinuierlichen Variablen zwischen verschiedenen Gruppen unterschiedlich ausfällt, kann man Histogramme und KerndichteDiagramme separat für die verschiedenen Untergruppen anfordern. Mit den klassischen R-Funktionen erstellt man dazu zunächst für jede Untergruppe einen neuen Data Frame, der nur die Personen dieser Untergruppe enthält (s. Abschn. 7.3.2). Anschließend kann man die Histogramme oder Kerndichte-Diagramme wie oben beschrieben separat für jede Gruppe anfordern. In ggplot2 können wir entweder die Säulen bzw. Kurven ein einem Diagramm übereinanderlegen oder in unterschiedlichen Facetten neben- oder untereinander darstellen. Abbildung 10.13 zeigt ein Beispiel für ein Diagramm mit überlagerten
10.3
Ausgewählte Diagramme
Kerndichtekurven für zwei Untergruppen. Die Kerndichtekurven werden hier als transparent gefärbte Flächen dargestellt. Dieses Diagramm wurde mit dem folgenden Befehl erzeugt: > erstis %>% filter(!is.na(geschl)) %>% ggplot(aes(x = alter, fill = geschl)) + geom_density(alpha = .5, col = NA)
In diesem Befehl werden zunächst wieder die Personen ausgewählt, die auf der Gruppenvariablen geschl gültige Werte haben. Anschließend wird das Diagramm mit ggplot erstellt. In der aes-Funktion bewirkt das zusätzliche Argument fill = geschl, dass unterschiedlich gefärbte Flächen für die Ausprägungen dieser Variablen dargestellt werden sollen. In der geom_density-Funktion geben wir mit dem Argument alpha = .5 den Grad der Transparenz der beiden Farben an. Mit col = NA erreichen wir, dass die Flächen keinen Rand bekommen. Wenn uns die beiden standardmäßig verwendeten Farben nicht gefallen, können wir diese mit der zusätzlichen Funktion scale_fill_manual (s. Abschn 10.2.2) anpassen. Im R-Skript zu diesem Kapitel finden Sie dafür ein Beispiel.
0.075
0.050
density
geschl weiblich männlich
0.025
0.000 20
30
40
50
alter
Abbildung 10.13 Überlagerte Kerndichte-Kurven, erstellt mit ggplot2
Alternativ kann man die Gruppen auch in separaten Diagrammen darstellen, nämlich in sog. Facetten oder Panels. Das in Abbildung 10.14 gezeigte Diagramm enthält zwei Panels, die jeweils ein Histogramm mit Kerndichtekurve zeigen. Im oberen Panel wird die Verteilung der Variablen alter für weibliche Teilnehmerinnen gezeigt,
169
170
10 Datenvisualisierung
im unteren Panel die Verteilung dieser Variablen für männliche Teilnehmer. Dieses Diagramm wurde mit dem folgenden Befehl erzeugt: > erstis %>% filter(!is.na(geschl)) %>% ggplot(aes(x = alter, y = ..density..)) + geom_histogram(binwidth = 5, fill = "white", col = "grey") + geom_line(stat = "density", size = 1) + facet_grid(geschl ~ .)
Entscheidend ist in diesem Befehl die zusätzliche Funktion facet_grid am Ende. Hier legen wir fest, dass die Diagramme getrennt für die Ausprägungen der innerhalb dieser Funktion aufgeführte(n) Variable(n) dargestellt werden sollen. Mit dem Ausdruck geschl ~ . erreichen wir, dass die Panels untereinander angeordnet werden. Schreiben wir stattdessen facet_grid(~ geschl), werden die Panels nebeneinander angeordnet.
Abbildung 10.14 Histogramme mit Kerndichtekurven für zwei Untergruppen, dargestellt in unterschiedlichen Panels
10.3
Ausgewählte Diagramme
10.3.3 Boxplots Mit Boxplots kann man viele verschiedene Aspekte der Verteilung einer kontinuierlichen Variablen kompakt visualisieren. Ein Boxplot besteht aus einer Reihe von Elementen (vgl. Abb. 10.15): Box. Den rechteckigen Kasten bezeichnet man als Box. Die untere Kante der Box entspricht dem 1. Quartil. Die obere Kante der Box entspricht dem 3. Quartil. Die Höhe der Box entspricht damit genau dem Interquartilsabstand. Median. Der Median (bzw. das 2. Quartil) ist in der Box als fette horizontale Linie eingezeichnet. Whisker. Die vertikalen Linien unter und über der Box bezeichnet man als Whisker (englisch für Schnurrhaare, daher auch der Name einer bekannten Katzenfuttermarke). Die Enden der Whisker sind die Werte, die maximal 1.5-mal den Interquartilsabstand von der Box entfernt liegen. Die Whisker hören immer bei konkreten Werten auf, daher kann es sein, dass der Whisker kürzer als 1.5-mal die Boxhöhe ist. In der Abbildung ist dies bei dem unteren Whisker der Fall. Ausreißer. Die Datenpunkte unterhalb und oberhalb der Whiskers sind Ausreißerwerte. Ausreißer sind alle Werte, die mehr als 1.5-mal die Boxhöhe von der Box entfernt liegen, sowohl nach oben als auch nach unten. Im Beispiel in Abbildung 10.15 gibt es nur Ausreißer nach oben, aber theoretisch sind auch Ausreißer nach unten möglich. Boxplots mit der boxplot-Funktion Die boxplot-Funktion ist die klassische Funktion zur Erstellung von Boxplots. Mit dem folgenden Befehl erstellen wir einen Boxplot für eine einzelne Variable, in diesem Beispiel die Variable alter aus den erstis-Daten (s. Abb. 10.15 links): > boxplot(erstis$alter)
Man kann sich Boxplots auch für verschiedene Gruppen ausgeben lassen. Um solche gruppierten Boxplots zu erhalten, nutzen wir die Formelschreibweise von R: > boxplot(erstis$alter ~ erstis$geschl, xlab = "", ylab = "Alter")
Das Zeichen ~ nennt man Tilde. Auf den meisten Tastaturen findet man es direkt links von der Eingabetaste (ENTER ) zusammen mit den Symbolen + und *. Um die Tilde zu erhalten, muss man diese Taste zusammen mit der ALT GR -Taste (rechts neben der Leerzeichen-Taste) drücken. Auf Mac-Tastaturen ist die Tilde nicht abgebil-
171
172
10 Datenvisualisierung
det, sie kann aber über die Tastenkombination ALT + N , gefolgt von der Leertaste erzeugt werden. Die Tilde drückt aus, dass es sich bei dem Ausdruck um eine Formel für ein statistisches Modell handelt. Die Variable vor der Tilde ist die abhängige Variable. Sie wird durch die unabhängige(n) Variable(n) hinter der Tilde erklärt. In diesem Beispiel werden also für jede Ausprägung der (unabhängigen) kategorialen Variablen Geschlecht (geschl) jeweils getrennte Boxplots für die (abhängige) kontinuierliche Variable Alter (alter) erstellt (s. Abb. 10.15 rechts). Das Aussehen der Boxplots kann über verschiedene zusätzliche Argumente gesteuert werden (s. ?boxplot). Besonders erwähnenswert sind die Argumente notch und horizontal. Mit notch = TRUE erhalten wir Boxplots mit Taillen oder Kerben (engl. notch), auf deren Interpretation wir eingehen, wenn wir gleich Boxplots mit ggplot2 besprechen. Mit horizontal = TRUE werden die Boxplots horizontal statt vertikal dargestellt.
Abbildung 10.15 Einfacher Boxplot (links) und gruppierte Boxplots (rechts) erstellt mit der boxplot-Funktion
Boxplots mit ggplot2 Die geometrische Funktion für Boxplots lautet geom_boxplot. Im folgenden Befehl erstellen wir einen einfachen Boxplot für die Variable alter (s. Abb. 10.16 links): > ggplot(erstis, aes(y = alter)) + geom_boxplot()
10.3
Ausgewählte Diagramme
Abbildung 10.16 Einfacher Boxplot (links) und gruppierte Boxplots (rechts) erstellt mit ggplot2. Beim gruppierten Boxplot wurden Kerben (engl. notches) hinzugefügt.
Gruppierte Boxplots erhalten wir, indem wir in der aes-Funktion die Gruppierungsvariable im x-Argument angeben. Wir machen das hier für die Variable geschl. Da diese Variable fehlende Werte enthält, die wir nicht als eigene Boxplots darstellen möchten, filtern wir wieder zunächst die Daten so, dass nur Personen mit gültigen Werten auf der Variablen geschl berücksichtigt werden. Das mit diesem Befehl erstellte Diagramm ist in Abbildung 10.16 rechts dargestellt. Mit dem optionalen Argument notch = TRUE wurden hier sog. Kerben bzw. Notches zu den Boxplots hinzugefügt. Diese Kerben sind für Gruppenvergleiche interessant: Überlappen sich die Kerben nicht, unterscheiden sich die Mediane der Gruppen signifikant. > erstis %>% filter(!is.na(geschl)) %>% ggplot(aes(y = alter, x = geschl)) + geom_boxplot(notch = TRUE) + xlab("") + ylab("Alter")
Tipp
Viele modernere Diagrammtypen versuchen, die Eigenschaften von Histogrammen, Kerndichte-Diagrammen und Boxplots zu kombinieren. Beispiele dafür sind Violin-Diagramme (z. B. geom_violin in ggplot2 oder das vioplot-Paket; Adler & Kelly, 2019) und Piraten-Plots (Funktion pirateplot aus dem Paket yarrr; Phillips, 2017).
173
174
10 Datenvisualisierung
10.3.4 Mittelwerts-Diagramme Viele psychologische Fragestellungen beziehen sich auf Mittelwertsunterschiede zwischen verschiedenen Gruppen, z. B. zwischen Kontroll- und Therapiegruppe in einer Evaluationsstudie. Die Ergebnisse werden häufig in Mittelwerts-Diagrammen dargestellt. Früher wurden häufig Säulendiagramme dafür verwendet, also Diagramme, in denen die Höhe der Säulen den Mittelwert in der jeweiligen Gruppe widerspiegelte. Diese Diagramme sind aber mittlerweile so verpönt, dass es auf Twitter einen eigenen Hashtag dafür gibt: #barbarplots. Stattdessen sollten Mittelwerte als Punkte mit Fehlerbalken dargestellt werden. Die Fehlerbalken stellen dabei entweder den Standardfehler oder das Konfidenzintervall dar. Wir besprechen diese Art von Diagrammen ausführlich in Kapitel 13 und gehen hier daher nur kurz darauf ein. Es gibt zahlreiche spezielle Funktionen zur Erstellung von Mittelwerts-Diagrammen, z. B. die error.bars-Funktion und die error.bars.by-Funktion aus dem psych-Paket oder Funktionen aus den Paketen emmeans (Lenth, 2019) und afex (Singmann et al., 2020; s. Kapitel 13). Darüber hinaus kann man Mittelwerts-Diagramme auch in den folgenden Schritten per Hand erstellen. Zunächst berechnet man die Mittelwerte und die dazugehörigen Standardfehler bzw. Konfidenzintervalle für die verschiedenen Gruppen, z. B. mit der describeBy-Funktion aus dem psych-Paket. Anschließend stellt man die Mittelwerte grafisch dar, z. B. mit der plot-Funktion oder mit geom_point() in ggplot2. Schließlich fügt man die Fehlerbalken manuell ein. In den klassischen R-Funktionen eignet sich dazu die arrows-Funktion. In ggplot2 verwendet man die Funktion geom_errorbar(). Beide Funktionen benötigen vier Koordinaten: Die x- und y-Koordinaten des Anfangs des Pfeils und die x- und y-Koordinaten des Endes des Pfeils. Beispiel-Befehle für dieses manuelle Vorgehen finden Sie im R-Skript zu diesem Kapitel.
10.3.5 Einfaches Streudiagramm Streudiagramme sind geeignet, um den Zusammenhang zwischen zwei kontinuierlichen Variablen darzustellen. Durch das Hinzufügen von Regressionsgeraden und sog. Loess-Kurven kann man zudem eine Vorstellung über die Stärke und Form des Zusammenhangs zwischen den Variablen erhalten. Wir betrachten hier den Zusammenhang zwischen Neurotizismus (neuro) und Lebenszufriedenheit (lz.1) aus den erstis-Daten.
10.3
Ausgewählte Diagramme
Streudiagramme mit der plot-Funktion Mit den klassischen Grafik-Funktionen erstellt man Streudiagramme am einfachsten mit der plot-Funktion. Wenn man die beiden Variablen als getrennte Argumente eingibt (also durch ein Komma getrennt), wird die zuerst genannte Variable auf der x-Achse dargestellt, und die als zweite genannte Variable auf der y-Achse. Im mit dem folgenden Befehl erstellten Streudiagramm wird Neurotizismus (neuro) auf der x-Achse dargestellt und Lebenszufriedenheit (lz.1) auf der y-Achse: > plot(erstis$neuro, erstis$lz.1)
Das so angeforderte Streudiagramm ist in Abbildung 10.17 links dargestellt. Alternativ kann man die beiden Variablen in der plot-Funktion auch in Formelschreibweise angeben: > plot(erstis$lz.1 ~ erstis$neuro)
Wenn diese Schreibweise verwendet wird, wird die abhängige Variable (also die Variable, die links von der Tilde steht) immer auf der y-Achse und die unabhängige Variable (also die Variable, die rechts von der Tilde steht) immer auf der x-Achse dargestellt (s. Abschn. 10.3.3). Das Streudiagramm kann mit den in Abschnitt 10.1.2 beschriebenen zusätzlichen Argumenten verändert werden. Wir können z. B. die Form und Farbe der Datenpunkte mit den Argumenten pch bzw. col verändern.
Abbildung 10.17 Einfaches Streudiagramm (links) und Streudiagramm mit nachträglich hinzugefügter Regressionsgerade (durchgezogene Linie) und Loess-Kurve (gestrichelte Linie), erstellt mit klassischen Grafik-Funktionen
175
176
10 Datenvisualisierung
Um eine Regressionsgerade in das Streudiagramm einzufügen, müssen wir zunächst die Werte für Achsenabschnitt und Steigungskoeffizient schätzen. Dazu verwenden wir die lm-Funktion (s. Kap. 15). > lm(lz.1 ~ neuro, data = erstis) Call: lm(formula = lz.1 ~ neuro, data = erstis) Coefficients: (Intercept) 30.975
neuro -1.865
Den lm-Befehl setzen wir direkt in die abline-Funktion ein. Mit der abline-Funktion werden Geraden in das zuletzt erstellte Diagramm eingezeichnet. Verwendet man in dieser Funktion nur das Argument h = x bzw. v = x, so wird eine horizontale bzw. eine vertikale Gerade an der Stelle x eingefügt. Um eine Regressionsgerade einzuzeichnen, fügen wir die Regressionsgleichung in die abline-Funktion ein. Im folgenden Befehl haben wir außerdem noch den Linientyp dieser Geraden geändert. Die damit erstellte Gerade ist in dem in Abbildung 10.17 rechts gezeigten Diagramm zu sehen. > abline(lm(lz.1 ~ neuro, data = erstis), lty = 2)
Zum Schluss fügen wir noch eine Loess-Kurve zum Streudiagramm hinzu. Eine Loess-Kurve ist eine nonparametrische Kurve, die den Zusammenhang zwischen zwei Variablen in einem Streudiagramm nachzeichnet, ohne dabei eine bestimmte Form (z. B. linear oder quadratisch) vorzugeben. Somit ist diese Kurve gut geeignet, um kurvilineare Zusammenhänge aufzudecken. In den R-Basispaketen berechnen wir die Loess-Werte mit der lowess-Funktion. In diese Funktion dürfen nur Variablen ohne fehlende Werte eingehen, daher erstellen wir zunächst einen neuen Data Frame mit den Variablen neuro und lz.1, aus dem Personen mit fehlenden Werten entfernt wurden. Wir verwenden hier die select-Funktion aus dem dplyr-Paket (Wickham et al., 2020), das dazu geladen sein muss (s. Abschn. 7.3.3). > auswahl lines(lowess(auswahl$lz.1 ~ auswahl$neuro))
Die beiden Variablen werden in der lowess-Funktion in Formel-Schreibweise eingegeben, d. h., die Variable, die auf der y-Achse abgetragen wird, erscheint vor der Tilde (~), und die Variable, die auf der x-Achse abgetragen wird, erscheint hinter der Tilde. Wenn die so erstellte Loess-Kurve gar nicht zu den dargestellten Datenpunkten passt, sollte man überprüfen, ob man vielleicht die beiden Variablen vertauscht hat. Das Streudiagramm mit Loess-Kurve ist in Abbildung 10.17 rechts dargestellt. Streudiagramme mit ggplot2 In ggplot2 legen wir zunächst in der aes-Funktion fest, welche Variable auf der x-Achse und welche auf der y-Achse dargestellt werden soll. Mit der geom_pointFunktion erreichen wir anschließend, dass diese Daten als Punkte dargestellt werden (s. Abb. 10.18 links). > ggplot(erstis, aes(x = neuro, y = lz.1)) + geom_point()
Mit der Funktion stat_smooth können wir anschließend Kurven und Geraden in das Diagramm einfügen. Innerhalb der stat_smooth-Funktion geben wir an, mit welcher statistischen Methode die Kurve berechnet werden soll, z. B. method = lm für Regressionsgeraden oder method = loess für Loess-Kurven. Außerdem können wir in der stat_smooth-Funktion das Aussehen der Linien mit den in Abschnitt 10.2.2 besprochenen Argumenten steuern. Mit dem folgenden Befehl erstellen wir ein Streudiagramm mit einer durchgezogenen Loess-Kurve und einer gestrichelten Regressionsgeraden, jeweils mit Konfidenzband (s. Abb. 10.18 rechts): > ggplot(erstis, aes(x = neuro, y = lz.1)) + geom_point() + stat_smooth(method = lm, linetype = 2) + stat_smooth(method = loess)
Tipp
Wenn man nur die Loess-Kurve oder die Regressionsgerade ohne die Rohwerte darstellen möchte, lässt man die geom_point-Funktion weg und verwendet stattdessen die geom_smooth-Funktion.
177
178
10 Datenvisualisierung
Abbildung 10.18 Einfaches Streudiagramm (links) und Streudiagramm mit Regressionsgerade (durchgezogene Linie) und Loess-Kurve (gestrichelte Linie) mit Konfidenzbändern, erstellt mit ggplot2
10.3.6 Streudiagramm-Matrix Wenn einen die bivariaten Zusammenhänge zwischen mehr als nur zwei Variablen interessieren, kann man sich über eine Streudiagramm-Matrix einen schnellen Eindruck verschaffen. Eine solche Streudiagramm-Matrix wird automatisch erstellt, wenn man die plot-Funktion auf mehr als zwei Vektoren anwendet (s. Abschn. 10.1). Hier betrachten wir jedoch eine spezielle Funktion für Streudiagramm-Matrizen, die im psych-Paket (Revelle, 2019) zur Verfügung gestellt wird. Wir erstellen zunächst einen neuen Data Frame, der nur die Variablen enthält, die wir in der Streudiagramm-Matrix abbilden möchten. Im folgenden Beispiel wählen wir die Persönlichkeitsvariablen Neurotizismus (neuro), Gewissenhaftigkeit (gewiss) und Extraversion (extra) mithilfe der select-Funktion aus dem dplyr-Paket (Wickham et al., 2020) aus: > pers % select(extra, neuro, gewiss)
Anschließend wenden wir die pairs.panels-Funktion auf diesen Data Frame an. > pairs.panels(pers)
Das hiermit erstellte Diagramm ist in Abbildung 10.19 dargestellt. Es besteht aus 3 × 3 Kästchen mit Diagrammen oder Zahlen. In der Diagonalen sind die univariaten
10.3
Ausgewählte Diagramme
Verteilungen der einzelnen Variablen in Histogrammen mit Kerndichtekurven dargestellt. Unterhalb der Diagonalen finden wir Streudiagramme für jede Kombination der drei Variablen. Beispielsweise ist im Streudiagramm oben links die Variable neuro auf der x-Achse und die Variable gewiss auf der y-Achse dargestellt. Zudem sind eine Loess-Kurve sowie die Mittelwerte der beiden Variablen mitsamt Konfidenzbereich eingezeichnet. Die Werte oberhalb der Diagonalen geben die Korrelationskoeffizienten für die entsprechende Variablen-Kombination wieder. Dieses Diagramm ist somit ideal, um sich einen schnellen Überblick über die Richtung, Stärke und Form der bivariaten Zusammenhänge zwischen einer Reihe von Variablen zu verschaffen.
Abbildung 10.19 Mit pairs.panels erstellte Streudiagramm-Matrix. Die Bedeutung der einzelnen Diagramme und Werte wird im Text erläutert.
179
180
10 Datenvisualisierung
10.4 Die wichtigsten klassischen Grafik-Funktionen im Überblick Funktionen für zusätzliche Diagramm-Elemente sind in Abschn. 10.1.3 aufgeführt. Funktion
Erläuterung
plot()
Generische Funktion zur Erstellung von Diagrammen
barplot()
Säulendiagramm
hist()
Histogramm
plot(density())
Kerndichte-Diagramm
boxplot()
Boxplot
pairs.panels()
Streudiagramm-Matrix
par()
Grundsätzliche Grafik-Einstellungen
par(mfrow=c(a,b))
Legt die Anzahl der Diagramme pro Zeile (a) und Spalte (b) in der Ausgabe fest
error.bars()*, error.bars.by()*
Mittelwerts-Diagramme für einzelne Variablen oder für verschiedene Gruppen; Funktionen aus dem psych-Paket
afex_plot()*
Mittelwerts-Diagramm (s. Kap. 13); Funktion aus dem afex-Paket
* Funktionen aus zusätzlichen Paketen
10.5 Zusätzliche Argumente für klassische Grafik-Funktionen Funktion
Erläuterung
type
Diagrammtyp
pch
Darstellung der Datenpunkte
cex
Größe der Datenpunkte
lty
Linientyp
lwd
Linienstärke
col
Farben
xlim, ylim
Wertebereich der x-Achse bzw. der y-Achse
xlab, ylab
Titel der x-Achse bzw. der y-Achse
10.7
Zusätzliche Argumente für ggplot2-Funktionen
Funktion
Erläuterung
las
Ausrichtung der Achsenbeschriftung
font
Schriftschnitt
main, sub
Titel und Untertitel
10.6 Die wichtigsten ggplot2-Funktionen im Überblick Funktion
Erläuterung
ggplot()
Erstellt ein Diagramm mit ggplot2
aes()
Legt die Ästhetik des Diagramms fest, d. h., wo und wie die Variablen im Diagramm dargestellt werden sollen
geom_xxx()
Funktionen für die geometrische Form des Diagramms. Für verschiedene Varianten der geomFunktion s. Tabelle 10.5
scale_xxx()
Funktionen zur Änderung der geometrischen Aspekte des Diagramms, z. B. Farben, Achsen, Formen
scale_x_continuous(), scale_y_continuous()
Wertebereich und Beschriftung bei kontinuierlichen Achsen
theme_xxx()
Gestalten die Diagramme nach bestimmten Themen. Für verschiedene Themen s. Tabelle 10.6
xlab(), ylab()
Titel der x-Achse bzw. der y-Achse
facet_grid()
Erzeugt mehrere Diagramm-Panels für Untergruppen
stat_smooth()
Fügt statistische Kennwerte (z. B. Regressionsgeraden) hinzu
10.7 Zusätzliche Argumente für ggplot2-Funktionen Funktion
Erläuterung
size
Größe von geometrischen Elementen wie Datenpunkten oder Linien
shape
Form von Datenpunkten
linetype
Linientyp
col
Farben
181
182
10 Datenvisualisierung
Funktion
Erläuterung
alpha
Grad der Transparenz von Farben
10.8 Übungen Diese Übungen beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze). Verwenden Sie für diese Übungen jeweils sowohl die klassischen GrafikFunktionen als auch die entsprechenden ggplot2-Funktionen. So bekommen Sie am besten heraus, welchen Ansatz Sie in Zukunft für die Datenvisualisierung bevorzugen. (1) Fassen Sie die folgenden vier Diagramme auf einer Seite zusammen: a. Gruppierte Boxplots für die Variablen gruppe (x-Achse) und prok (yAchse). b. Streudiagramm für die Variablen prok (x-Achse) und lz.1 (y-Achse). Fügen Sie eine Loess-Kurve hinzu. c. Histogramm für die Variable alter. d. Säulendiagramm mit absoluten Häufigkeiten für die Variable gruppe. Die Säulen sollten blau sein. (2) Erstellen Sie ein Streudiagramm für die Variablen gewiss (x-Achse) und prok (y-Achse). Berücksichtigen Sie dabei die folgenden Punkte: a. Der Titel des Diagramms ist »Gewissenhaftigkeit und Prokrastination«. b. Die Beschriftung der x-Achse ist »Gewissenhaftigkeit«. c. Die Beschriftung der y-Achse ist »Prokrastination«. d. Die Achsenbeschriftungen sind rot und doppelt so groß wie normal. e. Sowohl die x-Achse als auch die y-Achse haben jeweils einen Wertebereich von 1 bis 5. f. Die Datenpunkte werden als ausgefüllte blaue Punkte dargestellt.
Powered by TCPDF (www.tcpdf.org)
11
11
Wahrscheinlichkeitsverteilungen
Wahrscheinlichkeitsverteilungen
In den meisten Statistikbüchern findet man im Anhang seitenlange Tabellen zu verschiedenen Wahrscheinlichkeitsverteilungen. Sicher mussten Sie auch schon mal mit einer solchen Tabellen den Flächenanteil für einen bestimmten z-Wert nachschlagen oder vielleicht die kritischen Werte für einen manuell durchgeführten Signifikanztest ermitteln. R kennt diese Wahrscheinlichkeitsverteilungen auch und kann somit genutzt werden, um Wahrscheinlichkeitsverteilungen grafisch darzustellen und bestimmte Werte zu ermitteln. Die Wahrscheinlichkeitsverteilungen, die uns am häufigsten begegnen, sind die Normalverteilung und Standardnormalverteilung, die t-Verteilung, die F-Verteilung und die χ²-Verteilung. Darüber hinaus stehen in R auch noch viele andere Wahrscheinlichkeitsverteilungen zur Verfügung (Tab. 11.1). Tabelle 11.1 Ausgewählte Wahrscheinlichkeitsverteilungen in R. Bei einigen Verteilungen müssen die Freiheitsgrade als zusätzliche Argumente aufgenommen werden.
Verteilung
Dichtefunktion
Quantile
Probability
Normalverteilung
dnorm
qnorm
pnorm
χ²-Verteilung
dchisq
qchisq
pchisq
t-Verteilung
dt
qt
pt
F-Verteilung
df
qf
pf
Log-normale Verteilung
dlnorm
qlnorm
plnorm
Poisson-Verteilung
dpois
qpois
ppois
Binomial-Verteilung
dbinom
qbinom
pbinom
Die Namen der Funktionen für Wahrscheinlichkeitsverteilungen setzen sich immer aus zwei Bestandteilen zusammen. Der hintere Teil des Namens bezieht sich auf die Wahrscheinlichkeitsverteilung, z. B. Normalverteilung (norm), t-Verteilung (t) oder χ²-Verteilung (chi). Der vordere Teil des Namens bezieht sich auf den gewünschten Output, z. B. die Dichte (d), Quantile (q) oder Flächenanteile bzw. probabilies (p). Mit der Dichtefunktion kann man die Dichtewerte einer Verteilung bestimmen, was besonders dann nützlich ist, wenn man die Form dieser Verteilung grafisch darstellen möchte. Die Quantile sind bestimmte Werte der Wahrscheinlichkeitsverteilung, die
183
184
11 Wahrscheinlichkeitsverteilungen
einen bestimmten Anteil der Fläche unterhalb bzw. oberhalb der Verteilung begrenzen. Sie werden z. B. benötigt, um kritische Werte für Signifikanztests zu bestimmen. Umgekehrt kann man für bestimmte Werte einer Wahrscheinlichkeitsverteilung den dazugehörigen Flächenanteil bestimmen lassen, also den Teil der Verteilung, der unterhalb dieses Werts liegt. Hiermit kann man z. B. p-Werte bestimmen. Wir demonstrieren diese drei Anwendungen anhand der t-Verteilung. Für andere Verteilungen werden die entsprechenden Funktionen analog eingesetzt.
11.1
Grafische Darstellung der Wahrscheinlichkeitsverteilung
Die Form einer Wahrscheinlichkeitsverteilung kann man über die Dichtefunktion bestimmen. Die Fläche unter der Kurve der Dichtefunktion gibt den Anteil dieser Werte unter der jeweiligen Wahrscheinlichkeitsverteilung an. In R kann man sich die Dichtefunktionen verschiedener Verteilungen grafisch darstellen lassen. Um die Dichte einer Verteilung zu erhalten, wird der Buchstabe d (density) vor dem Namen der Funktion ergänzt. Die Dichtefunktion der t-Verteilung wird mit der Funktion dt() angefordert. Um die Dichtefunktion grafisch darzustellen, verwenden wir die curve-Funktion. Mit der curve-Funktion können wir beliebige Funktionskurven grafisch darstellen. Die Form der Dichtefunktion der t-Verteilung hängt von den Freiheitsgraden ab. Mit dem folgenden Befehl veranschaulichen wir die Dichtefunktion für eine t-Verteilung mit 100 Freiheitsgraden: > curve(dt(x, df = 100), -3, 3)
Die curve-Funktion hat hier drei Argumente: dt(x, 100). Die Dichtefunktion der t-Verteilung. Im zweiten Argument werden die Freiheitsgrade festgelegt, hier also 100. -3. Der kleinste Wert der x-Achse. 3. Der größte Wert der x-Achse. Wir können nun untersuchen, wie sich die Dichtefunktion verändert, wenn wir die Freiheitsgrade verändern. Mit den folgenden Befehlen lassen wir uns die Dichtefunktionen für 1 und 10 Freiheitsgrade darstellen: > curve(dt(x, df = 1), lty = 2, add = TRUE) > curve(dt(x, df = 10), lty = 3, add = TRUE)
Mit dem Argument lty legen wir den Linientyp fest, damit die drei Dichtefunktionen unterschiedlich dargestellt werden (s. Abschn. 10.1.2). Durch das Argument
11.1
Grafische Darstellung der Wahrscheinlichkeitsverteilung
add = TRUE erreichen wir, dass diese Dichtefunktionen in das bereits erstellte Dia-
gramm eingefügt werden. Schließlich ergänzen wir noch eine Legende, damit wir nachvollziehen können, welche Linie zu welcher Dichtefunktion gehört (s. Abschn. 10.1.3). Wir erhalten das in Abbildung 11.1 dargestellte Diagramm: > legend("topright", c("df = 1", "df = 10", "df = 100"), lty = c(2,3,1))
Abbildung 11.1 Dichtefunktionen für t-Verteilungen mit 1, 10 und 100 Freiheitsgraden Tipp
In ggplot2 (Wickham, 2016) werden Funktionskurven mit der stat_function-Funktion erstellt. Mit dem folgenden Befehl stellen wir die drei t-Verteilungen aus Abbildung 11.1 mit ggplot2 dar. > ggplot(data.frame(x = c(-3,3)), aes(x = x)) + stat_function(fun = dt, args = list(df = 1), linetype = 2) + stat_function(fun = dt, args = list(df = 10), linetype = 3) + stat_function(fun = dt, args = list(df = 100), linetype = 1)
185
186
11 Wahrscheinlichkeitsverteilungen
11.2 Berechnung von Quantilen Ein Quantil ist ein Wert einer Wahrscheinlichkeitsverteilung, unterhalb dessen sich ein bestimmter Anteil der Fläche der Verteilung befindet. Wir benötigen Quantile z. B. dann, wenn wir die kritischen Werte für einen Signifikanztest bestimmen möchten. (Bevor jetzt Panik aufkommt: Natürlich kann man auch den gesamten Test von R durchführen lassen, sodass man sich die einzelnen Schritte sparen kann.) In R erhält man Quantile, indem man den Buchstaben q (quantile) vor den Namen der Wahrscheinlichkeitsverteilung setzt. Wir möchten nun die kritischen Werte für einen zweiseitigen t-Test mit 128 Freiheitsgraden und einem Signifikanzniveau von 5 % bestimmen. Wir suchen also die t-Werte, die auf beiden Seiten der Verteilung jeweils 2.5 % der Fläche abschneiden bzw. das 0.025-Quantil und das 0.975-Quantil der t-Verteilung. Dazu geben wir die folgenden Befehle ein: > qt(p = 0.025, df = 128) [1] -1.978671 > qt(p = 0.975, df = 128) [1] 1.978671
11.3 Berechnung von Flächenanteilen bzw. p-Werten Im vorherigen Abschnitt haben wir Quantile für bestimmte Flächenanteile ermittelt. Manchmal haben wir genau den umgekehrten Fall: Wir haben einen bestimmten Wert einer Wahrscheinlichkeitsverteilung und möchten herausfinden, welcher Anteil der Fläche unterhalb bzw. oberhalb dieses Werts liegt. Ein Beispiel für diesen Fall ist die Interpretation von individuellen z-Werten. Wenn wir den z-Wert einer Person auf einer Variablen kennen, können wir für diesen z-Wert den Anteil der Personen ermitteln, die einen niedrigeren bzw. höheren Wert als die uns interessierende Person haben, und somit den individuellen z-Wert besser interpretieren. Ein weiteres Beispiel betrachten wir jetzt genauer: Wenn wir einen statistischen Test durchführen, wird das Ergebnis üblicherweise in Form eines exakten p-Werts ausgedrückt. Der p-Wert ist die Wahrscheinlichkeit, mit der wir die vorliegende oder eine extremere Prüfgröße erhalten würden, wenn die Nullhypothese gilt. Nehmen wir an, wir haben einen t-Test durchgeführt und eine Prüfgröße von -1.8 erhalten (bei 128 Freiheitsgraden). Wir bestimmen nun für diesen t-Wert, wie groß der Anteil der Fläche ist, der unterhalb dieses Werts liegt. Dazu setzen wir den Buchstaben p (probability) vor den Namen der Wahrscheinlichkeitsverteilung.
11.4
Tests für die Prüfung der Normalverteilungsannahme
> pt(q = -1.8, df = 128) [1] 0.03710796
Unterhalb des t-Werts -1.8 liegen also ca. 0.037 % der Verteilung. Die Wahrscheinlichkeit, diese oder eine extremere Prüfgröße zu erhalten, wenn die Nullhypothese gilt, ist also (gerundet) p = .037. Bei einem Signifikanzniveau von 5 % würden wir daher die Nullhypothese verwerfen. Wichtig: Die p-Funktion gibt immer den Anteil der Fläche unterhalb des eingegebenen Werts der Wahrscheinlichkeitsverteilung an. Wenn wir stattdessen den Anteil der Fläche oberhalb dieses Werts erfahren möchten, ziehen wir das Ergebnis dieser Funktion von 1 ab: > 1 - pt(q = -1.8, df = 128) [1] 0.962892
11.4 Tests für die Prüfung der Normalverteilungsannahme Viele statistische Verfahren setzen normalverteilte Variablen voraus. Das Paket nortest (Gross & Ligges, 2015) enthält verschiedene statistische Tests, mit denen die Normalverteilungsannahme überprüft werden kann: den Anderson-Darling-Test (ad.test), den Cramer-von Mises-Test (cvm.test), den Lilliefors-Test (lillie.test), den χ²-Test nach Pearson (pearson.test) sowie den Shapiro-FranciaTest (sf.test). Grundsätzlich sollte man sich nie alleine auf diese Tests verlassen, denn sie sind sehr sensibel und schlagen schon bei minimalen Abweichungen von der Normalverteilung Alarm. Für die meisten statistischen Tests sind leichte Abweichungen aber unproblematisch, besonders bei großen Stichproben. Durch die zusätzliche grafische Prüfung der Verteilung der Variablen bekommen wir einen besseren Eindruck, wie stark die Abweichung von der Normalverteilung ist. Dafür eignen sich Diagramme wie das Histogramm oder das Kerndichte-Diagramm (s. Abschn. 10.3.2).
187
188
11 Wahrscheinlichkeitsverteilungen
11.5 Die wichtigsten Funktionen im Überblick Funktion
Beschreibung
dt(x, df)
Dichtefunktion der t-Verteilung für einen bestimmten Wertebereich x und eine bestimmte Anzahl an Freiheitsgraden df. Die entsprechenden Funktionen für andere Verteilungen sind in Tabelle 11.1 zusammengefasst.
qt(p, df)
Gibt für eine bestimmte Wahrscheinlichkeit p das Quantil der t-Verteilung mit df Freiheitsgraden aus.
pt(q, df)
Gibt für ein bestimmtes Quantil q der t-Verteilung mit df Freiheitsgraden den p-Wert aus.
11.6 Übungen (1) Stellen Sie die folgenden Wahrscheinlichkeitsverteilungen in einem Diagramm (Wertebereich der x-Achse von -3 bis 3) dar: a. Standardnormalverteilung b. t-Verteilung mit 20 Freiheitsgraden c. t-Verteilung mit 100 Freiheitsgraden (2) Bestimmen Sie die kritischen Werte für die folgenden Tests. Verwenden Sie im Zweifelsfall die help-Funktion, um herauszufinden, welche Argumente in die einzelnen Funktionen einfließen. a. zweiseitiger t-Test mit α = 5 % und df = 19 b. einseitiger z-Test mit α = 1 % c. F-Test mit α = 10 %, df1 = 3 und df2 = 150 d. χ²-Test mit α = 2.5 % und df = 4 (3) Bestimmen Sie die Flächenanteile rechts von den folgenden Quantilen. a. z = 1.35 b. t = 1.35, df = 20 c. F = 2.9, df1 = 1, df2 = 38
Powered by TCPDF (www.tcpdf.org)
12.1
12
Einstichproben-t-Test
Mittelwertsvergleiche mit t-Tests
In diesem Kapitel werden verschiedene t-Tests für Mittelwertsvergleiche behandelt: der Einstichproben-t-Test (Abschn. 12.1), der t-Test für unabhängige Stichproben (Abschn. 12.2) sowie der t-Test für abhängige Stichproben (Abschn. 12.3). Wir besprechen außerdem, wie man die Voraussetzungen für diese Tests überprüfen kann. Die Beispiele in diesem Kapitel beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze).
12.1 Einstichproben-t-Test Mit dem Einstichproben-t-Test kann man den Stichprobenmittelwert einer Variablen mit einem bekannten Populationsmittelwert vergleichen. Als Beispiel möchten wir überprüfen, ob sich unsere studentische Stichprobe in ihrem Neurotizismus (Variable neuro) von Personen mit Abschluss unterscheidet. Wir nehmen an, dass der mittlere Neurotizismuswert in der Population der Personen mit Abschluss bei µ = 3.3 liegt.
12.1.1
Stichprobengröße und deskriptive Statistiken
In den t-Test werden nur Personen einbezogen, die gültige Werte auf der Variablen haben. Um die Stichprobengröße für diesen Test zu ermitteln, verwenden wir die describe-Funktion aus dem psych-Paket (Revelle, 2019; s. Abschn. 8.2.1). Damit erhalten wir auch gleich nützliche deskriptive Statistiken wie den Mittelwert und die Standardabweichung. > describe(erstis$neuro) vars n mean sd median trimmed mad min max range skew 1 1 188 3.45 0.75 3.5 3.45 0.74 1.5 5 3.5 -0.02 kurtosis se -0.56 0.05
189
190
12 Mittelwertsvergleiche mit t-Tests
12.1.2 Durchführung des Einstichproben-t-Tests Wir können zwei Arten von Hypothesen testen, die wir beide in diesem Abschnitt betrachten: Ungerichtete Hypothese. Der mittlere Neurotizismuswert unserer Stichprobe unterscheidet sich vom mittleren Neurotizismus der Population. Gerichtete Hypothese. Der mittlere Neurotizismuswert unserer Stichprobe ist höher (bzw. niedriger) als der mittlere Neurotizismuswert der Population. Ungerichtete Hypothese: Zweiseitiger Test Bei der ungerichteten Hypothese wird nur angenommen, dass ein Unterschied existiert. Sie wird mit einem zweiseitigen t-Test überprüft. In diesem Fall lauten die statistischen Hypothesen wie folgt: H0: µ = 3.3 und H1: µ ≠ 3.3 Der Einstichproben-t-Test wird mit der t.test-Funktion angefordert. Im Argument mu (für das griechische µ) wird der Populationsmittelwert eingegeben, mit dem wir unsere Stichprobe vergleichen wollen: > t.test(erstis$neuro, mu = 3.3) One Sample t-test data: erstis$neuro t = 2.824, df = 187, p-value = 0.005256 alternative hypothesis: true mean is not equal to 3.3 95 percent confidence interval: 3.346661 3.562914 sample estimates: mean of x 3.454787
Die Ausgabe besteht aus den folgenden Bestandteilen: One Sample t-test. Die englische Bezeichnung des durchgeführten Tests, in diesem Fall also der Einstichproben-t-Test. data: erstis$neuro. Der Name der abhängigen Variablen. t = 2.824, df = 187, p-value = 0.005256. Das Ergebnis des statistischen Tests, genauer gesagt, die empirische Prüfgröße t, die Freiheitsgrade df und der p-Wert p-value.
12.1
Einstichproben-t-Test
alternative hypothesis: true mean is not equal to 3.3. Die ausformulierte Alternativhypothese des Tests, die auch den zu testenden Vergleichswert enthält. 95 percent confidence interval: 3.346661 3.562914. Das 95 %-Konfidenzintervall für den Stichprobenmittelwert. Liegt der angenommene Populationsmittelwert nicht in diesem Intervall, kann die Nullhypothese auf einem Signifikanzniveau von 5 % verworfen werden. sample estimates: mean of x 3.454787. Der beobachtete Stichprobenmittelwert. Aus dem Ergebnis des t-Tests können wir folgern, dass sich unsere Stichprobe in ihrem mittleren Neurotizismuswert (M = 3.45, SD = 0.75) signifikant von dem Neurotizismus-Mittelwert in der Population unterscheidet, t(187) = 2.824, p = .005, 95 % CI [3.35; 3.56]. Tipp
Die Stichprobengröße ist in der Ausgabe nicht enthalten. Wir können sie aber aus den Freiheitsgraden erschließen, denn beim Einstichproben-t-Test sind die Freiheitsgrade definiert mit N – 1. In diesem Beispiel haben wir 187 Freiheitsgrade, d. h., die Stichprobe umfasste N = 188 Personen. Gerichtete Hypothese: Einseitiger Test Bei der gerichteten Hypothese wird eine konkrete Annahme formuliert, in welcher Richtung der Unterschied zu erwarten ist. Sie wird mit einem einseitigen t-Test überprüft. Wir möchten nun die gerichtete Alternativhypothese prüfen, dass Studierende neurotischer sind als Personen mit Abschluss. In diesem Fall lauten die statistischen Hypothesen wie folgt: H0: µ ≤ 3.3 und H1: µ > 3.3 Bei einer gerichteten Hypothese wird der Einstichproben-t-Test einseitig durchgeführt. Wenn wir annehmen, dass der Stichprobenmittelwert größer als der Populationsmittelwert ist, ergänzen wir in der t.test-Funktion das Argument alternative = "greater" oder kurz alt = "g". Wenn wir umgekehrt annehmen, dass der Stichprobenmittelwert kleiner als der Populationsmittelwert ist, ergänzen wir das Argument alternative = "less" oder kurz alt = "l". Im folgenden Beispiel überprüfen wir die gerichtete Hypothese, dass die Stichprobe im Mittel höhere Neurotizismuswerte als die Population hat:
191
192
12 Mittelwertsvergleiche mit t-Tests > t.test(erstis$neuro, mu = 3.3, alternative = "greater") One Sample t-test data: erstis$neuro t = 2.824, df = 187, p-value = 0.002628 alternative hypothesis: true mean is greater than 3.3 95 percent confidence interval: 3.364183 Inf sample estimates: mean of x 3.454787
An drei Stellen unterscheidet sich diese Ausgabe von der Ausgabe des zweiseitigen t-Tests im vorherigen Abschnitt: Wir haben einen anderen p-Wert, der genau halb so groß ist wie der p-Wert des zweiseitigen Tests. Die Alternativhypothese lautet jetzt true mean is greater than 3.3. Das Konfidenzintervall ist jetzt ebenfalls einseitig und hat die Grenzen 3.36 (untere Grenze) bis unendlich (obere Grenze). Da der p-Wert kleiner als .05 ist und das Konfidenzintervall den Populationsmittelwert von 3.3 nicht enthält, verwerfen wir die Nullhypothese und nehmen die Alternativhypothese an: Der mittlere Neurotizismuswert unserer Stichprobe (M = 3.45, SD = 0.75) ist signifikant höher als der mittlere Neurotizismuswert in der Population (µ = 3.3), t(187) = 2.824, p = .003, 95 % CI [3.36; ∞]. Konfidenzintervall anpassen Mit der Voreinstellung wird immer ein 95 %-Konfidenzintervall ausgegeben. Wir können die Breite des Konfidenzintervalls mit dem Argument conf.level verändern. Im folgenden Beispiel wird ein 99 %-Konfidenzintervall angefordert: > t.test(erstis$neuro, mu = 3.3, conf.level = 0.99)
12.1.3 Effektgröße Eine standardisierte Effektgröße für den Einstichproben-t-Test erhalten wir, indem wir die Mittelwertsdifferenz durch die Standardabweichung teilen. Diese Effektgröße ist auch als Cohens d bekannt (Cohen, 1988). Die Effektgröße ist in der Ausgabe der t.test-Funktion nicht enthalten. Es gibt jedoch mehrere Pakete, die Funktionen für die Berechnung von Effektgrößen enthalten, z. B. die Pakete MBESS (Kelley, 2019),
12.1
Einstichproben-t-Test
effectsize (Makowski, Ben-Shachar & Lüdecke, 2019) und effsize (Torchiano,
2020). Aus dem Paket effsize schauen wir uns nun die Funktion cohen.d an. Mit dieser Funktion wird nicht nur die Effektgröße selbst, sondern auch ein Konfidenzintervall für die Effektgröße berechnet. Da auch das psych-Paket (Revelle, 2019) eine Funktion mit diesem Namen enthält, geben wir hier immer auch den Namen des Pakets mit an, damit es zu keinen Verwechslungen kommt (s. Kap. 3). > effsize::cohen.d(d = erstis$neuro, f = NA, mu = 3.3, na.rm = TRUE) Cohen's d (single sample) d estimate: 0.2059642 (small) Reference mu: 3.3 95 percent confidence interval: lower upper -0.08255012 0.49447850
Die Funktion enthält hier vier Argumente. Die Argumente d und f sind Pflicht, d. h., die Funktion läuft nicht, wenn man diese Argumente weglässt. Bei d geben wir die abhängige Variable an. Das Argument f erwartet eine unabhängige Variable (z. B. beim t-Test für unabhängige Stichproben, s. Abschn. 12.2.6). Da wir hier keine haben, geben wir NA an. Das Argument mu kennen wir schon von der t.test-Funktion. Auch hier wird in diesem Argument der Mittelwert der Population angegeben, mit dem wir unseren Stichprobenmittelwert vergleichen möchten. Und auch das Argument na.rm ist uns schon begegnet (s. Abschn. 12.2). Dieses Argument müssen wir auf TRUE setzen, wenn wir wollen, dass fehlende Werte bei der Berechnung übersprungen werden – sonst würden wir nur fehlende Werte (NA) in der Ausgabe erhalten. Die Ausgabe enthält die Effektgröße (d estimate) sowie die untere (lower) und obere (upper) Grenze des 95 %-Konfidenzintervalls der Effektgröße. Hinter der Effektgröße steht in diesem Beispiel (small). Nach traditionellen Konventionen (Cohen, 1988) handelt es sich hierbei also um einen kleinen Effekt. Diese Konventionen werden jedoch in einigen psychologischen Disziplinen derzeit hinterfragt (Funder & Ozer, 2019), daher sollte man sich bei der Interpretation der Effektgröße nicht alleine auf die alten Daumenregeln verlassen. Auch bemerkenswert ist hier, dass das Konfidenzintervall in diesem Beispiel den Wert 0 enthält, obwohl der t-Test mit p = .003 signifikant war – es kommt also nicht immer zum selben statistischen Schluss.
193
194
12 Mittelwertsvergleiche mit t-Tests
12.2 t-Test für unabhängige Stichproben Mit dem t-Test für unabhängige Stichproben vergleicht man zwei Gruppen (bzw. Stichproben) in Bezug auf den jeweiligen Mittelwert auf der abhängigen Variablen. Im Folgenden möchten wir prüfen, ob sich Frauen und Männer hinsichtlich ihrer mittleren Neurotizismuswerte sowie hinsichtlich ihrer mittleren Gewissenhaftigkeitswerte unterscheiden. Wir führen also zwei t-Tests durch. Die unabhängige Variable ist in beiden Fällen das Geschlecht mit den Ausprägungen weiblich und männlich, die abhängigen Variablen sind Neurotizismus und Gewissenhaftigkeit.
12.2.1 Stichprobengröße und deskriptive Statistiken Beim t-Test werden nur Personen berücksichtigt, die sowohl auf der unabhängigen Variablen als auch auf der abhängigen Variablen gültige Werte (also keine fehlenden Werte) haben. Um die Anzahl der Personen zu ermitteln, auf die dies zutrifft, nutzen wir die describeBy-Funktion aus dem psych-Paket (Revelle, 2019; s. Abschn. 8.3). Mit dieser Funktion erhalten wir zusätzlich die deskriptiven Statistiken für die beiden Gruppen. > describeBy(erstis$neuro, erstis$geschl, mat = TRUE)
11 12
item group1 var n mean sd median trimmed 1 weiblich 1 112 3.587054 0.7068757 3.625 3.588889 2 männlich 1 55 3.181818 0.7208125 3.250 3.188889
mad min max range skew kurtosis se 0.555975 2.0 5.00 3.00 0.002857482 -0.6090882 0.06679347 0.741300 1.5 4.75 3.25 -0.068721840 -0.4781228 0.09719434
Personen mit fehlenden Werten auf einer der Variablen werden in dieser Tabelle ignoriert. Für 112 Frauen und 55 Männer liegen sowohl die Angaben zum Geschlecht als auch die Neurotizismuswerte vor. Diese Personen gehen in die Analyse ein. Wenn wir die Gewissenhaftigkeit als abhängige Variable untersuchen, erhalten wir dieselbe Stichprobengröße: > describeBy(erstis$gewiss, erstis$geschl, mat = TRUE)$n [1] 112 55
12.2
t-Test für unabhängige Stichproben
12.2.2 Überprüfung der Varianzhomogenität Die Annahme der Varianzhomogenität besagt, dass die Varianzen der abhängigen Variablen in beiden Populationen gleich sein müssen. Diese Annahme kann mit dem Levene-Test überprüft werden. Dieser Test prüft die Nullhypothese, dass die Varianzen gleich sind. Ein signifikantes Ergebnis bedeutet also, dass sich die Varianzen signifikant unterscheiden und damit die Voraussetzung der Varianzhomogenität für den t-Test nicht gegeben ist. Wenn dies der Fall ist, steht mit dem Welch-Test ein alternativer Test zur Verfügung, der gegenüber Verletzungen der Varianzhomogenität robust ist (s. Abschn. 12.2.4). Wir überprüfen nun die Varianzhomogenität für die Variable neuro. Dazu verwenden wir die leveneTest-Funktion aus dem car-Paket (Fox & Weisberg, 2019). > leveneTest(erstis$neuro, erstis$geschl) Levene's Test for Homogeneity of Variance (center = median) Df F value Pr(>F) group 1 0.0062 0.9372 165
Die leveneTest-Funktion hat zwei Argumente: Das erste Argument ist der Name der abhängigen Variablen (hier neuro), das zweite Argument ist der Name der unabhängigen Variablen (hier geschl). Der Levene-Test basiert auf der F-Verteilung. Daher erhalten wir in der Ausgabe einen F-Wert als Prüfgröße (F value) und zwei Freiheitsgrade. Darüber hinaus wird der p-Wert für das Ergebnis angegeben (Pr(>F)). In unserem Beispiel erhalten wir das Ergebnis F(1, 165) = 0.0062, p = .9372. Wir behalten also die Nullhypothese bei und nehmen Varianzhomogenität an. Das heißt, dass wir im nächsten Schritt den ganz normalen t-Test für unabhängige Stichproben rechnen können. Anders sieht es aus, wenn wir uns die Varianzen für die Gewissenhaftigkeit anschauen. Hier liegt keine Varianzhomogenität vor, F(1, 165) = 5.5552, p = .0196. Das heißt, anstelle des normalen t-Tests sollte lieber der robuste Welch-Test durchgeführt werden. Der t-Test und der Welch-Test werden in den nächsten Abschnitten beschrieben. > leveneTest(erstis$gewiss, erstis$geschl) Levene's Test for Homogeneity of Variance (center = median) Df F value Pr(>F) group 1 5.5552 0.0196 * 165
195
196
12 Mittelwertsvergleiche mit t-Tests
12.2.3 t-Test für unabhängige Stichproben bei Varianzgleichheit Wir möchten nun prüfen, ob sich Frauen und Männer in ihren mittleren Neurotizismuswerten unterscheiden. Im vorherigen Abschnitt haben wir bereits gesehen, dass Varianzhomogenität gegeben ist, d. h., wir können den normalen t-Test für unabhängige Stichproben durchführen. Dafür verwenden wir wieder die t.test-Funktion. Im ersten Argument geben wir die Variablen in Formelschreibweise an. Diese Schreibweise wird in R üblicherweise verwendet, um die Beziehung zwischen unabhängigen und abhängigen Variablen darzustellen. Das Herz der Formel ist die Tilde (~). Dieses Symbol kann man als Gleichheitszeichen in einer Modellgleichung interpretieren oder lesen als »wird erklärt / vorhergesagt durch«. Links von der Tilde stehen immer die abhängigen Variablen, rechts die unabhängigen Variablen. Für unseren Test lautet die Formel also neuro ~ geschl. Man beachte, dass wir hier nicht mehr den Namen des Data Frames und das Dollarzeichen aufführen. Wenn wir die Formelschreibweise verwenden, können wir nämlich den Namen des Data Frames auch im zusätzlichen Argument data angeben. Mit dem Argument var.equal = TRUE stellen wir ein, dass wir von Varianzhomogenität ausgehen und somit der normale t-Test durchgeführt werden soll. > t.test(neuro ~ geschl, data = erstis, var.equal = TRUE) Two Sample t-test data: neuro by geschl t = 3.4593, df = 165, p-value = 0.0006893 alternative hypothesis: true difference in means is not equal to 0 95 percent confidence interval: 0.1739396 0.6365312 sample estimates: mean in group weiblich mean in group männlich 3.587054 3.181818
Diese Ausgabe ist so aufgebaut wie die Ausgabe des Einstichproben-t-Tests (s. Abschn. 12.1.2), daher gehen wir hier nicht auf alle Elemente ein. Der Test ist signifikant, t(165) = 3.4593, p < .001, 95 % CI [0.17, 0.64]. Das heißt, Frauen und Männer unterscheiden sich signifikant in ihren mittleren Neurotizismuswerten. Am Ende der Ausgabe sehen wir, dass der Mittelwert der Frauen (M = 3.59) höher ist als der Mittelwert der Männer (M = 3.18).
12.2
t-Test für unabhängige Stichproben
Tipp
Die Stichprobengröße ist in der Ausgabe nicht enthalten. Wir können sie aber aus den Freiheitsgraden erschließen, die beim t-Test für zwei unabhängige Stichproben mit n1 + n2 – 2 definiert sind. In diesem Beispiel haben wir 165 Freiheitsgrade, d. h., die Stichprobe umfasste insgesamt N = 167 Personen. Wie sich diese Personen auf die beiden Gruppen aufteilen, wissen wir jedoch nicht. Dazu müssen wir uns die Stichprobengrößen wie in Abschn. 12.2.1 beschrieben ausgeben lassen.
12.2.4 Welch-Test für unabhängige Stichproben bei Varianzungleichheit Uns interessiert, ob sich Frauen und Männer auch in ihrer mittleren Gewissenhaftigkeit unterscheiden. Der Levene-Test (s. Abschn. 12.2.2) hat ergeben, dass die Varianzhomogenitäts-Annahme für diese Variable nicht erfüllt ist. Anstelle des t-Tests für unabhängige Stichproben möchten wir daher den Welch-Test durchführen. Der Welch-Test ist robust gegenüber Verletzungen der Varianzhomogenität. In R wird der Welch-Test ebenfalls mit der t.test-Funktion angefordert. Das Argument var.equal (s. o.) wird entweder auf FALSE gesetzt oder einfach weggelassen: > t.test(gewiss ~ geschl, data = erstis) Welch Two Sample t-test data: gewiss by geschl t = 2.5441, df = 87.131, p-value = 0.01272 alternative hypothesis: true difference in means is not equal to 0 95 percent confidence interval: 0.07775722 0.63311941 sample estimates: mean in group weiblich mean in group männlich 3.700893 3.345455
Der Welch-Test ergibt ein signifikantes Ergebnis, t(87.13) = 2.54, p = .013, 95 % CI [0.08, 0.63]. Das heißt, Frauen und Männer unterscheiden sich signifikant in ihrer mittleren Gewissenhaftigkeit. Am Ende des Outputs sehen wir, dass der Mittelwert der Frauen (M = 3.70) höher ist als der Mittelwert der Männer (M = 3.35).
197
198
12 Mittelwertsvergleiche mit t-Tests
12.2.5 Weitere Einstellungen Alle Einstellungen, die wir beim t-Test für eine Stichprobe kennengelernt haben, funktionieren auch beim t-Test für unabhängige Stichproben, da in beiden Fällen die t.test-Funktion in R verwendet wird. Einseitiger vs. zweiseitiger Test Standardmäßig wird der t-Test zweiseitig durchgeführt, d. h., es wird eine ungerichtete Alternativhypothese getestet. Wenn man eine gerichtete Alternativhypothese prüfen möchte, kann man auch hier mit den Argumenten alternative = "less" bzw. alternative = "greater" einen einseitigen Test anfordern. Um dieses Argument korrekt anzuwenden, muss man die Reihenfolge der Ausprägungen kennen. Diese können wir uns z. B. mit der levels-Funktion ausgeben lassen: > levels(erstis$geschl) [1] "weiblich" "männlich"
Die Ausprägung weiblich wird hier zuerst aufgeführt. Diese Reihenfolge wird in den statistischen Hypothesen übernommen. Wenn man also prüfen will, ob Männer höhere Werte als Frauen haben, muss man in unserem Fall die Option alternative = "less" verwenden. Konfidenzintervall anpassen Die Breite des Konfidenzintervalls können wir mit dem Argument conf.level verändern (s. Abschn. 12.1.2).
12.2.6 Effektgröße Als standardisierte Effektgröße für zwei Mittelwerte wird üblicherweise die standardisierte Mittelwertsdifferenz bzw. Cohens d berechnet (Cohen, 1988). Dazu wird die Mittelwertsdifferenz durch die gepoolte Standardabweichung geteilt. Auch hier können wir wieder auf Funktionen aus verschiedenen Paketen zurückgreifen (s. Abschn. 12.1.3). Wir verwenden hier erneut die cohen.d-Funktion aus dem Paket effsize (Torchiano, 2020), die uns neben der Effektgröße auch das Konfidenzintervall für die Effektgröße ausgibt. Für zwei unabhängige Stichproben geben wir die Formel sowie den Namen des Data Frames genauso ein wie oben bei der t.test-Funktion: > effsize::cohen.d(neuro ~ geschl, data = erstis)
12.3
t-Test für abhängige Stichproben
Cohen's d d estimate: 0.5695773 (medium) 95 percent confidence interval: lower upper 0.2387077 0.9004469
12.3 t-Test für abhängige Stichproben Mit dem t-Test für abhängige Stichproben vergleicht man zwei Mittelwerte aus gepaarten bzw. abhängigen Stichproben miteinander. Abhängige Stichproben erkennt man daran, dass man Wertepaare bilden kann, d. h., jedem Wert kann genau ein bestimmter anderer Wert zugeordnet werden. Ein typisches Beispiel sind Längsschnittdaten, bei denen jede Person zweimal untersucht wurde.
12.3.1 Stichprobengröße und deskriptive Statistiken Wir möchten nun untersuchen, ob sich die Zufriedenheit mit den Studieninhalten vom 1. Semester (zuf.inh.1) zum 2. Semester (zuf.inh.2) verschlechtert hat. Für jede Person liegen zwei Werte vor, d. h., wir haben abhängige Stichproben. Bevor wir die Stichprobengröße bestimmen und deskriptive Statistiken anfordern, müssen wir sicherstellen, dass nur Personen, die auf beiden Variablen gültige Werte haben, berücksichtigt werden. Wir erstellen dazu einen neuen Data Frame, der nur die uns interessierenden Variablen enthält (hier mit der select-Funktion aus dem dplyrPaket), und entfernen Personen mit fehlenden Werten mit der na.omit-Funktion (s. Abschn. 7.3.3): > auswahl describe(auswahl) vars n mean sd median trimmed mad min max zuf.inh.1 1 49 3.31 0.50 3.33 3.34 0.49 2.33 4 zuf.inh.2 2 49 3.14 0.69 3.00 3.21 0.49 1.00 4
Bei abhängigen Stichproben interessiert uns außerdem häufig die Korrelation:
199
200
12 Mittelwertsvergleiche mit t-Tests > cor(auswahl) zuf.inh.1 zuf.inh.2 zuf.inh.1 1.0000000 0.3656918 zuf.inh.2 0.3656918 1.0000000
12.3.2 Durchführung des t-Tests für abhängige Stichproben Da wir eine gerichtete Hypothese haben, führen wir einen einseitigen Test durch. Für den t-Test für abhängige Stichproben verwenden wir in R wieder die t.test-Funktion: > t.test(erstis$zuf.inh.1, erstis$zuf.inh.2, paired = TRUE, alternative = "greater")
Die ersten beiden Argumente in dieser Funktion sind die beiden Variablen, die wir miteinander vergleichen wollen. Anders als beim t-Test für unabhängige Stichproben brauchen wir hier keine Tilde, müssen aber wieder das Dollarzeichen einsetzen. Mit dem Argument paired = TRUE fordern wir den t-Test für abhängige Stichproben an. Wenn wir dieses Argument nicht verwenden, werden die Mittelwerte mit einem t-Test für unabhängige Stichproben verglichen! Mit dem Argument alternative = "greater" wird der einseitige Test angefordert. Konkret stellen wir die Alternativhypothese auf, dass der Mittelwert der ersten Variablen (hier die Studienzufriedenheit im 1. Semester zuf.inh.1) höher ist als der Mittelwert der zweiten Variablen (hier die Studienzufriedenheit im 2. Semester zuf.inh.2). Wir erhalten die folgende Ausgabe: Paired t-test data: erstis$zuf.inh.1 and erstis$zuf.inh.2 t = 1.8008, df = 48, p-value = 0.03901 alternative hypothesis: true difference in means is greater than 0 95 percent confidence interval: 0.01213668 Inf sample estimates: mean of the differences 0.1768707
12.3
t-Test für abhängige Stichproben
Diese Ausgabe kennen wir schon von den vorherigen t-Tests, daher besprechen wir sie hier nicht im Detail, sondern gehen nur auf einige ausgewählte Werte ein. Am Ende der Ausgabe wird die Differenz der Mittelwerte angegeben (mean of the differences). In diesem Fall ist sie zuf.inh.1 – zuf.inh.2 = 0.18. Da der Wert positiv ist, können wir hier schon erkennen, dass die Studienzufriedenheit im 1. Semester höher war als im 2. Semester. Ob dieser Unterschied signifikant ist, erkennen wir oben in der Ausgabe: Die Studienzufriedenheit hat signifikant abgenommen, t(48) = 1.80, p = .039, 95 % CI [0.01, ∞]. Tipp
Auch hier können wir die Stichprobengröße aus den Freiheitsgraden erschließen, die beim t-Test für zwei abhängige Stichproben mit N – 1 definiert sind. In diesem Beispiel haben wir 48 Freiheitsgrade, d. h., die Stichprobe umfasste insgesamt N = 49 Personen.
12.3.3 Effektgröße Nach Cohen (1988) wird die Effektgröße für zwei abhängige Stichproben berechnet, indem man die Mittelwertsdifferenz durch die Standardabweichung dieser Mittelwertsdifferenz teilt. In den Nenner fließen also nicht die Standardabweichungen der Rohdaten ein, sondern die Standardabweichung der Differenzvariablen (vgl. auch Eid et al., 2017). Wichtig: Dies ist nicht die einzige mögliche Effektgröße für abhängige Stichproben. Je nach Fragestellung ist es häufig auch sinnvoll, die Mittelwertsdifferenz an anderen Standardabweichungen zu standardisieren, z. B. an der Standardabweichung des ersten Messzeitpunkts bei messwiederholten Daten (Morris & DeShon, 2002). Wir vertiefen diese verschiedenen Möglichkeiten hier nicht, sondern betrachten nur die in der cohen.d-Funktion aus dem effsize-Paket (Torchiano, 2020) vorgeschlagene Variante. Hier wird die Formel von Gibbons et al. (1993) verwendet, bei der die Mittelwertsdifferenz durch die Standardabweichung der Differenzvariablen geteilt wird. Bei zwei abhängigen Stichproben geben wir die beiden zu vergleichenden Variablen in die Argumente d und f ein. Mit dem Argument paired = TRUE geben wir an, dass es sich um abhängige Stichproben handelt. Falls eine der Variablen fehlende Werte enthält, müssen wir auch hier wieder das Argument na.rm auf TRUE setzen. Die Ausgabe haben wir bereits in den Abschnitten 12.1.3 und 12.2.6 besprochen und gehen an dieser Stelle nicht noch einmal im Detail darauf ein. > effsize::cohen.d(d = erstis$zuf.inh.1, f = erstis$zuf.inh.2, paired = TRUE, na.rm = TRUE)
201
202
12 Mittelwertsvergleiche mit t-Tests Cohen's d d estimate: 0.2897549 (small) 95 percent confidence interval: lower upper -0.03627215 0.61578202
12.4 Die wichtigsten Funktionen im Überblick Funktion
Beschreibung
t.test
Funktion für verschiedene t-Tests, z. B. t-Test für eine Stichprobe, t-Test für unabhängige Stichproben und t-Test für abhängige Stichproben.
t.test(av, mu = x)
t-Test für eine Stichprobe. av ist die abhängige Variable. Für x wird der Populationswert eingegeben, mit dem die Stichprobe verglichen werden soll.
t.test(av ~ uv)
Welch-Test für unabhängige Stichproben. av ist die abhängige Variable, uv ist die unabhängige Gruppenvariable.
t.test(av ~ uv, var.equal = TRUE)
t-Test für unabhängige Stichproben. av ist die abhängige Variable, uv ist die unabhängige Gruppenvariable.
t.test(av1, av2, paired = TRUE)
t-Test für abhängige Stichproben. av1 und av2 sind die beiden miteinander zu vergleichenden Variablen.
leveneTest(av, uv)*
Levene-Test für Varianzgleichheit für zwei unabhängige Stichproben. Die durch die Variable uv definierten Gruppen werden bezüglich der Variable av verglichen. Funktion aus dem car-Paket.
effsize::cohen.d()*
Berechnet eine standardisierte Effektgröße und deren Konfidenzintervall für Mittelwertsvergleiche. Funktion aus dem effsize-Paket.
* Funktionen aus zusätzlichen Paketen
12.5
Übungen
12.5 Übungen Diese Übungen beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze). Überprüfen Sie die folgenden Hypothesen. Berechnen Sie für jede Fragestellung auch immer die Mittelwerte, Standardabweichungen, Stichprobengrößen sowie eine geeignete Effektgröße. (1) Die Zufriedenheit mit der Belastung im Studium hat sich vom ersten Semester (zuf.bel.1) zum zweiten Semester (zuf.bel.2) verschlechtert. (2) Frauen sind gewissenhafter (gewiss) als Männer (geschl). (3) Personen mit Kindern und Personen ohne Kinder (kinder) unterscheiden sich in ihrer Lebenszufriedenheit (lz.1). (4) Im zweiten Semester sind die Studierenden häufiger guter Stimmung (gs.2) als im ersten Semester (gs.1). (5) Die mittlere Lebenszufriedenheit in der Stichprobe (lz.1) ist höher als die mittlere Lebenszufriedenheit von Studierenden aus anderen Studiengängen (µ = 20.95).
Powered by TCPDF (www.tcpdf.org)
203
204
13 Varianzanalyse ohne Messwiederholung
13
Varianzanalyse ohne Messwiederholung
Mit der Varianzanalyse werden Mittelwerte aus mehreren Gruppen miteinander verglichen. Wenn die zu vergleichenden Mittelwerte aus unabhängigen Stichproben stammen, wird eine Varianzanalyse ohne Messwiederholung durchgeführt. Stammen die zu vergleichenden Mittelwerte dagegen aus abhängigen Stichproben, wird die Varianzanalyse mit Messwiederholung durchgeführt (Kap. 14). Wir lernen in diesem Kapitel zwei Arten der Varianzanalyse ohne Messwiederholung kennen: die einfaktorielle Varianzanalyse (Abschn. 13.1) und die mehrfaktorielle Varianzanalyse (Abschn. 13.2). Die Beispiele in diesem Kapitel beziehen sich auf die Datensätze haustier.RData und therapie.RData (s. Anhang A: Datensätze).
13.1 Einfaktorielle Varianzanalyse ohne Messwiederholung Die einfaktorielle Varianzanalyse ohne Messwiederholung dient dem Vergleich der Mittelwerte einer Variablen aus mehreren unabhängigen Stichproben bzw. Gruppen. Genau wie beim t-Test für unabhängige Stichproben wird auch hier die Gruppenzugehörigkeit durch eine nominalskalierte unabhängige Variable definiert. Im Gegensatz zum t-Test für unabhängige Stichproben muss die unabhängige Variable jedoch nicht dichotom sein, sondern kann auch mehr als zwei Ausprägungen haben. In der Varianzanalyse wird die unabhängige Variable auch als Faktor bezeichnet. Im folgenden Beispiel untersuchen wir, ob sich drei Gruppen von Haustierbesitzern (Hunde-, Katzen- und Pferdebesitzer; Variable tierart) in ihren mittleren Wohlbefindenswerten (Variable wohlbefinden) unterscheiden.
13.1.1
Stichprobengröße und deskriptive Statistiken
Wir bestimmen zunächst die Stichprobengröße und deskriptivstatistische Kennwerte der abhängigen Variablen getrennt für jede Gruppe. Dazu greifen wir auf die describeBy-Funktion aus dem psych-Paket zurück (Revelle, 2019; s. Abschn. 8.3). Wir haben hier die Ausgabe noch auf zwei Nachkommastellen gerundet: > desk print(desk, digits = 2) item group1 vars n mean sd median trimmed mad min max range X11 1 Hund 1 30 5.2 1.8 5.2 5.1 1.8 2.1 9.1 7.1 X12 2 Katze 1 30 5.3 1.7 5.1 5.2 1.5 1.7 9.1 7.4 X13 3 Pferd 1 25 6.5 2.0 6.6 6.6 2.1 2.0 9.7 7.7 skew kurtosis se X11 0.21 -0.69 0.33 X12 0.35 -0.36 0.31 X13 -0.31 -0.81 0.40
13.1.2 Durchführung der einfaktoriellen Varianzanalyse Die R-Basispakete verfügen zwar mit der aov-Funktion über eine eigene Funktion für Varianzanalysen, diese ist jedoch etwas unhandlich, besonders bei der mehrfaktoriellen Varianzanalyse. Daher gibt es eine Reihe von Paketen, die alternative Funktionen für Varianzanalysen enthalten. In diesem Buch verwenden wir die Funktionen aus den Paketen afex (Singmann et al., 2020) und emmeans (Lenth, 2019). Eine gute Alternative ist auch das Paket ez (ausgesprochen wie das englische Wort »easy«; Lawrence, 2016), das wir hier aber nicht vertiefen. Für die Durchführung der Varianzanalyse verwenden wir die aov_car-Funktion aus dem afex-Paket (Singmann et al., 2020). Die Abkürzung aov steht für Analysis of Variance. Wir geben hier die Beziehung zwischen abhängiger und unabhängiger Variable wieder in Formelschreibweise ein, wie wir es bereits beim t-Test für unabhängige Stichproben kennengelernt haben (s. Abschn. 12.2). Vor der Tilde (~) steht die abhängige Variable (hier: wohlbefinden); hinter der Tilde steht die unabhängige Variable (hier: tierart). Außerdem muss am Ende der Formel immer ein Fehlerterm aufgeführt sein. Dieser Fehlerterm wird eigentlich erst für die messwiederholte Varianzanalyse wichtig, die wir ebenfalls mit der aov_car-Funktion durchführen können (s. Kap. 14). Die Funktion erwartet aber auch dann einen Fehlerterm, wenn keine Messwiederholung vorliegt. Der Fehlerterm heißt immer Error(). In den Klammern geben wir hier den Namen der ID-Variablen an, über die die einzelnen Fälle identifiziert werden. Sollte unser Data Frame eine solche Variable nicht enthalten (was bei echten Daten unwahrscheinlich ist), müssen wir eine ID-Variable erzeugen. Im Datenbeispiel hier heißt die ID-Variable ID. Ein weiteres Pflichtargument ist das data-Argument, in dem wir den Data Frame nennen, aus dem die Variablen stammen. Es ist damit nicht notwendig, die Herkunft der Variablen zusätzlich mit der Dollarzeichen-Funktion zu kennzeichnen.
205
206
13 Varianzanalyse ohne Messwiederholung
Anders als bisher führen wir den Befehl nicht direkt aus, sondern speichern die Ausgabe in einem neuen Objekt, das wir hier anova.1 nennen. Der vollständige Befehl sieht dann so aus: > anova.1 anova.1 Anova Table (Type 3 tests) Response: wohlbefinden Effect df MSE F ges p.value 1 tierart 2, 82 3.34 4.15 * .092 .019 --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1
Der Hinweis Type 3 tests bezieht sich darauf, wie die Quadratsummen bestimmt wurden; in diesem Fall als Typ III-Quadratsummen. Das ist bei der einfaktoriellen Varianzanalyse allerdings noch nicht relevant, wir gehen aber in Abschnitt 13.2 genauer darauf ein. Jetzt schon interessant ist aber der Rest der Ausgabe. Die Tabelle enthält die folgenden Spalten: Effect. Nennung des Effekts, der hier getestet wird. Bei der einfaktoriellen Varianzanalyse handelt es sich dabei immer um den Effekt der unabhängigen Variablen. df. Zähler- und Nennerfreiheitsgrade des F-Tests. MSE. Mittlere quadrierte Abweichung (engl. mean squared error). F. Empirische Prüfgröße des F-Tests. Signifikante F-Werte werden entsprechend der Legende unterhalb der Tabelle mit einem oder mehreren Sternchen gekennzeichnet.
13.1
Einfaktorielle Varianzanalyse ohne Messwiederholung
ges. Effektgröße η² (engl. generalized eta-squared). p.value. p-Wert für den F-Test. In unserem Datenbeispiel ist der F-Test signifikant, F(2, 82) = 4.15, p = .019, η² = .092. Das heißt, dass sich mindestens zwei der drei Haustierbesitzer-Gruppen statistisch bedeutsam in ihren mittleren Wohlbefindenswerten unterscheiden. Wie genau sich die Gruppen unterscheiden, wissen wir aber noch nicht. Dazu führen wir später Post-hoc-Vergleiche durch (s. Abschn. 13.1.3). Die Standardausgabe der aov_car-Funktion ist bereits publikationsfertig formatiert, z. B. sind alle Zahlen bereits auf eine bestimmte Anzahl von Nachkommastellen gerundet. Das ist praktisch, aber nicht immer wünschenswert. Man kann sich die Ausgabe auch anders darstellen lassen. Wendet man die summary-Funktion auf das Objekt an, erhält man eine ähnlich strukturierte Tabelle, die aber noch nicht formatiert wurde: > summary(anova.1) Anova Table (Type 3 tests) Response: wohlbefinden num Df den Df MSE F ges Pr(>F) tierart 2 82 3.3387 4.1519 0.091954 0.01916 * --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Klassische Varianzanalyse-Tabellen enthalten häufig auch die Quadratsummen für alle Effekte. Diese Art von Ausgabe erhält man über die folgende Variante: > anova.1$Anova Anova Table (Type III tests) Response: dv Sum Sq Df F value Pr(>F) (Intercept) 2709.37 1 811.5161 < 2e-16 *** tierart 27.72 2 4.1519 0.01916 * Residuals 273.77 82 --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Diese Tabelle besteht aus drei Zeilen. Die erste Zeile enthält Angaben zum Achsenabschnitt (englisch: intercept), die hier nicht weiter interessant sind. Die zweite Zeile enthält die Angaben zum Effekt des Faktors tierart (bzw. Variation zwischen den Gruppen). Die dritte Zeile enthält die Angaben zum Fehler. Residuals steht für Rest
207
208
13 Varianzanalyse ohne Messwiederholung
und bezieht sich hier auf den Anteil der Varianz des Fehlers (bzw. Variation innerhalb der Gruppen). Wir gehen nun die Spalten von links nach rechts durch: Sum Sq. Die Quadratsummen zwischen den Gruppen (zweite Zeile) bzw. innerhalb der Gruppen (dritte Zeile). Df. Die Freiheitsgrade des F-Tests. Beim F-Test gibt es immer zwei Freiheitsgrade: die des Zählers (zweite Zeile) und die des Nenners (dritte Zeile). F value. Die empirische Prüfgröße F. Pr(>F). Der p-Wert für den F-Test.
13.1.3 Post-hoc-Tests und Kontraste Ein statistisch signifikanter F-Test sagt uns noch nichts darüber aus, welche Gruppen sich signifikant unterscheiden und in welche Richtung. Daher führen wir bei einem signifikanten F-Test anschließend Post-hoc-Tests durch. Bei diesen Tests werden die einzelnen Mittelwerte direkt miteinander verglichen. Da damit mehrere Tests durchgeführt werden, müssen wir das Signifikanzniveau für die paarweisen Mittelwertsvergleiche so korrigieren, dass sich die gesamte Wahrscheinlichkeit für einen α-Fehler (die sog. familywise error rate) nicht erhöht. Auch für Post-hoc-Tests gibt es viele verschiedene Funktionen und Pakete. Besonders beliebt ist derzeit das Paket emmeans (Lenth, 2019), das inbesondere für komplexere Kontraste geeignet ist (s. Abschn. 13.2.3). Für paarweise Mittelwertsvergleiche bei der einfaktoriellen Varianzanalyse verwenden wir die emmeans-Funktion aus dem emmeans-Paket: > ph.1 ph.1 ph.1 tierart emmean SE df lower.CL upper.CL Hund 5.2 0.334 82 4.54 5.86 Katze 5.3 0.334 82 4.64 5.96 Pferd 6.5 0.365 82 5.77 7.23 Confidence level used: 0.95
Diese Ausgabe enthält für jede Ausprägung der unabhängigen Variablen – also für jede Gruppe – die jeweiligen Mittelwerte sowie Standardfehler und 95 %-Konfidenzintervalle der Mittelwerte. Post-hoc-Tests werden hier aber nicht angezeigt. Dazu müssen wir die pairs-Funktion auf das Objekt ph.1 anwenden: > pairs(ph.1) contrast estimate SE df t.ratio Hund - Katze -0.1 0.472 82 -0.212 Hund - Pferd -1.3 0.495 82 -2.627 Katze - Pferd -1.2 0.495 82 -2.425
p.value 0.9755 0.0274 0.0456
P value adjustment: tukey method for comparing a family of 3 estimates
Diese Ausgabe enthält die drei paarweisen Mittelwertsvergleiche. In der Spalte estimate werden die jeweiligen Mittelwertsdifferenzen angegeben. Die folgenden Spalten enthalten die dazugehörigen Standardfehler (SE), Freiheitsgrade (df), t-Werte (t.ratio) und p-Werte (p.value). Wichtig: Die p-Werte wurden bereits für multiple Vergleiche korrigiert, und zwar mit der Tukey-Methode, wie es am Ende der Ausgabe angegeben wird. In diesem Datenbeispiel finden wir signifikante Unterschiede zwischen Hunde- und Pferdebesitzern sowie zwischen Katzen- und Pferdebesitzern, nicht jedoch zwischen Hunde- und Katzenbesitzern.
13.1.4 Grafische Ergebnisdarstellung Die hier verwendeten Pakete enthalten eigene Funktionen für die Erstellung von Diagrammen. Im afex-Paket (Singmann et al., 2020) setzen wir die afex_plot-Funktion ein. Damit wir diese Funktion verwenden können, müssen wir ggf. beim ersten Mal noch das Paket ggbeeswarm (Clarke & Sherrill-Mix, 2017) installieren. Danach reicht es aber, das afex-Paket zu laden. > afex_plot(anova.1, x = "tierart")
209
210
13 Varianzanalyse ohne Messwiederholung
Das erste Argument ist wieder das oben erstelle Varianzanalyse-Objekt. Im Argument x geben wir an, welche Variable auf der x-Achse dargestellt werden soll. Bei der einfaktoriellen Varianzanalyse kommt dafür nur die unabhängige Variable infrage, hier also der Faktor tierart. Wir erhalten damit ein schönes Diagramm, das nicht nur die Mittelwerte, sondern auch Fehlerbalken (95 %-Konfidenzintervalle) sowie die Rohdaten enthält (s. Abb. 13.1 links).
Abbildung 13.1 Diagramme für die einfaktorielle Varianzanalyse ohne Messwiederholung, erstellt mit der Funktion afex_plot aus dem Paket afex (links) und mit der Funktion plot aus dem Paket emmeans (rechts)
Auch das emmeans-Paket (Lenth, 2019) verfügt über eine Funktion zur Erstellung von Diagrammen. Wir wenden dazu einfach die generische plot-Funktion auf das mit der emmeans-Funktion erstellte Objekt an: > plot(ph.1)
Wir erhalten dadurch ein Diagramm, in dem die Gruppen auf der y-Achse und die abhängige Variable auf der x-Achse dargestellt ist (s. Abb. 13.1 rechts). Die schwarzen Punkte sind die jeweiligen Mittelwerte. Die horizontalen Balken stellen die 95 %Konfidenzintervalle für die Mittelwerte dar. Rohwerte werden hier nicht dargestellt. Beide hier vorgestellte Funktionen basieren auf dem ggplot2-Paket (Wickham, 2016) und können daher wie üblich modifiziert werden (s. Abschn. 10.2). Bei der afex_plot-Funktion können Modifikationen sowohl innerhalb der Funktion vorgenommen werden als auch durch zusätzliche Funktionen, die mit dem Symbol + hinter dem Befehl ergänzt werden oder nachträglich auf das Objekt angewandt werden, das den Befehl für das Diagramm enthält. Im folgenden Beispiel wird die Art des
13.2
Mehrfaktorielle Varianzanalyse ohne Messwiederholung
Diagramms innerhalb der afex_plot-Funktion im Argument data_geom geändert (zu einem Violin-Diagramm). Die farbliche Gestaltung des Diagramms wird in einem zusätzlichen Befehl verändert. In diesem Beispiel wird das APA-Thema aus dem Paket jtools (Long, 2019b) angewandt: > p1 p1 + jtools::theme_apa()
13.2 Mehrfaktorielle Varianzanalyse ohne Messwiederholung Bei der mehrfaktoriellen Varianzanalyse ohne Messwiederholung werden im Gegensatz zur einfaktoriellen Varianzanalyse nicht nur eine, sondern mehrere unabhängige Variablen (Faktoren) betrachtet. In diesem Kapitel betrachten wir lediglich den Fall der zweifaktoriellen Varianzanalyse. Für mehr als zwei Faktoren können die hier vorgestellten Befehle aber einfach erweitert werden. Bei einer zweifaktoriellen Varianzanalyse liegen zwei kategoriale unabhängige Variablen (zwei Faktoren) und eine kontinuierliche abhängige Variable vor. Im folgenden Beispiel möchten wir untersuchen, ob Höhenangst durch eine Therapie verringert werden kann, und ob der Erfolg dieser Therapie von der Ausprägung der Höhenangst abhängt. Dazu wurde eine Evaluationsstudie durchgeführt, in der die Teilnehmenden randomisiert der Therapiegruppe oder der Kontrollgruppe zugeordnet wurden. Der erste Faktor ist also die gruppe mit den Ausprägungen Therapiegruppe und Kontrollgruppe. Außerdem wurde bei allen Teilnehmenden das Ausmaß der Höhenangst vor Beginn der Studie diagnostiziert. Dieser zweite Faktor diagnose hat hier die Ausprägungen Leichte Angst und Schwere Angst. Wir führen also eine 2 × 2 Varianzanalyse durch (zwei Faktoren mit jeweils zwei Ausprägungen). Insgesamt werden vier Gruppen verglichen. Als abhängige Variable wurde nach der Therapiephase gemessen, wie hoch die Patientinnen und Patienten auf einen Turm klettern konnten. Die erreichte Höhe wurde in Metern gemessen, wobei mehr Höhenmeter einer geringeren Höhenangst entsprechen. Diese abhängige Variable hat in den Daten den Namen meter. Alle Variablen sind im Data Frame therapie aus der Datei therapie.RData enthalten. Mit einer zweifaktoriellen Varianzanalyse können wir für dieses Beispiel die folgenden Effekte testen: Haupteffekt für den ersten Faktor. Unterscheiden sich Personen aus der Kontrollgruppe von Personen aus der Therapiegruppe bezüglich der erreichten Höhenmeter?
211
212
13 Varianzanalyse ohne Messwiederholung
Haupteffekt für den zweiten Faktor. Unterscheiden sich Personen mit leichter Höhenangst von Personen mit schwerer Höhenangst bezüglich der erreichten Höhenmeter? Interaktionseffekt. Hängt der Unterschied in den erreichten Höhenmetern zwischen Personen aus der Kontrollgruppe und Personen aus der Therapiegruppe davon ab, ob vorher eine leichte oder schwere Höhenangst diagnostiziert wurde?
13.2.1 Stichprobengröße und deskriptive Statistiken Um die Stichprobengrößen und deskriptive Statistiken für jede der vier Untergruppen zu bestimmen, die sich aus der Kombination der Ausprägungen der zwei Faktoren ergeben, erweitern wir die uns schon bekannte describeBy-Funktion: > desk print(desk, digits = 2)
X11 X12 X13 X14
item 1 2 3 4
group1 Angst Angst Angst Angst
Leichte Schwere Leichte Schwere
group2 vars n mean sd median Kontrollgruppe 1 25 8 2.6 8.5 Kontrollgruppe 1 25 4 2.4 3.7 Therapiegruppe 1 25 19 2.5 18.9 Therapiegruppe 1 25 10 2.4 9.7
13.2
X11 X12 X13 X14
trimmed 8.1 3.9 19.1 10.1
Mehrfaktorielle Varianzanalyse ohne Messwiederholung
mad min max range skew kurtosis se 2.5 3.265 12.3 9.0 -0.14 -0.95 0.52 2.7 0.029 8.2 8.2 0.26 -1.16 0.48 3.5 14.008 22.9 8.9 -0.14 -1.20 0.50 2.7 4.887 14.3 9.4 -0.32 -0.61 0.48
13.2.2 Durchführung der mehrfaktoriellen Varianzanalyse Wir verwenden auch hier wieder die aov_car-Funktion aus dem afex-Paket (Singmann et al., 2020). > anova.2 anova.2
213
214
13 Varianzanalyse ohne Messwiederholung
Anova Table (Type Response: meter Effect 1 diagnose 2 gruppe 3 diagnose:gruppe --Signif. codes: 0
3 tests) df MSE F ges p.value 1, 96 6.13 172.24 *** .642 F) (Intercept) 4375.1 1 101.007 93 4028.224 < 2.2e-16 mzp 45.4 2 91.113 186 46.327 < 2.2e-16 --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1
14.2
Einfaktorielle Varianzanalyse mit Messwiederholung
Mauchly Tests for Sphericity
mzp
Test statistic p-value 0.90317 0.0092362
Greenhouse-Geisser and Huynh-Feldt Corrections for Departure from Sphericity GG eps Pr(>F[GG]) mzp 0.91172 9.136e-16 *** --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 HF eps Pr(>F[HF]) mzp 0.9289873 5.116173e-16
Diese lange Ausgabe beginnt mit einer etwas anderen Darstellung des Ergebnisses der messwiederholten Varianzanalyse. In der dersten Tabelle werden uns für den Achsenabschnitt (Zeile Intercept) und die unabhängige Variable (Zeile mzp) jeweils die Quadratsummen (Sum Sq), die unkorrigierten Zähler-Freiheitsgrade (num Df), die Quadratsummen der Fehler (Error SS), die unkorrigierten Nenner-Freiheitsgrade (den Df), die F-Werte (F value) sowie die p-Werte (Pr(>F)) ausgegeben. Darunter erscheint der Mauchly-Test mit Prüfgröße (Test statistic) und pWert (p-value). In unserem Fall ist der Test auf einem Signifikanzniveau von 5 % signifikant, d. h., die Annahme der Sphärizität muss verworfen werden. In so einem Fall müssen die Freiheitsgrade um den Faktor Epsilon korrigiert werden. Dieser Korrektur-Faktor kann mit der Greenhouse-Geisser-Methode oder mit der HuynhFeldt-Methode berechnet werden, die zu leicht unterschiedlichen Ergebnissen kommen, die praktisch jedoch meistens keinen Unterschied machen. Welche Werte für Epsilon jeweils berechnet wurden, erfahren wir im unteren Teil der Ausgabe. Hier steht GG für Greenhouse-Geisser und HF für Huynh-Feldt. In beiden Fällen ist Epsilon kleiner als 1, d. h., die Freiheitsgrade werden durch die Korrektur kleiner. In der Konsequenz werden p-Werte jeweils größer. Wie man sieht, ist der Effekt des Messzeitpunkts aber auch dann signifikant, wenn man eine der beiden Korrekturen durchführt. Tipp
Es ist auch möglich, das Ergebnis der messwiederholten Varianzanalyse in Form einer multivariaten Varianzanalyse (MANOVA) mit Pillai-Tests darzustellen. Diese Art der Darstellung erhalten wir mit anova.1$Anova.
225
226
14 Varianzanalyse mit Messwiederholung
14.2.3 Post-hoc-Tests und Kontraste Ein signifikantes Ergebnis der messwiederholten Varianzanalyse bedeutet nur, dass sich mindestens zwei der Mittelwerte unterscheiden. Es bedeutet jedoch nicht zwangsläufig, dass sich alle Mittelwerte voneinander unterscheiden. Daher sollte man bei einem signifikanten F-Test anschließend (also post hoc) paarweise Vergleiche der Mittelwerte durchführen. So wie bei der Varianalyse ohne Messwiederholung (s. Kap. 13) verwenden wir auch hier wieder die emmeans–Funktion aus dem emmeans-Paket (Lenth, 2019). Wir können dafür eine der folgenden beiden Schreibweisen verwenden: > ph.1 ph.1 ph.1 mzp emmean SE df lower.CL upper.CL X1 3.46 0.0856 239 3.29 3.63 X2 3.91 0.0856 239 3.74 4.08 X3 4.44 0.0856 239 4.28 4.61 Warning: EMMs are biased unless design is perfectly balanced Confidence level used: 0.95
Wir erhalten hier die Mittelwerte (emmeans), Standardfehler (SE), Freiheitsgrade (df) und das Konfidenzintervall (lower.CL und upper.CL) für die Mittelwerte der drei Messzeitpunkte. Darunter werden wir gewarnt, dass diese Kennwerte nur dann unverzerrt sind, wenn das Design perfekt balanciert ist, wenn also die Anzahl der Datenpunkte für jede Ausprägung von mzp gleich ist. Das ist hier der Fall, denn oben wurden ja alle Fälle entfernt, die fehlende Werte hatten. Um die Mittelwerte paarweise miteinander zu vergleichen, wenden wir die pairs-Funktion auf das Objekt an. Dabei wird standardmäßig die Tukey-Methode zur Adjustierung der p-Werte angewandt. In der Ausgabe erhalten wir für alle paar-
14.2
Einfaktorielle Varianzanalyse mit Messwiederholung
weisen Mittelwertsvergleiche, die Differenzen der beiden Mittelwerte (estimate) sowie deren Standardfehler (SE), Freiheitsgrade (df), t-Werte (t.ratio) und p-Werte (p.value). > pairs(ph.1) contrast estimate SE df t.ratio X1 - X2 -0.447 0.102 186 -4.377 X1 - X3 -0.981 0.102 186 -9.613 X2 - X3 -0.535 0.102 186 -5.236
p.value 0.0001 desk print(desk[,1:7], digits = 2) item group1 group2 vars n mean sd X11 1 1 weiblich 1 78 3.4 0.98 X12 2 2 weiblich 1 76 3.8 0.70 X13 3 3 weiblich 1 76 4.4 0.88 X14 4 1 männlich 1 18 3.9 0.76 X15 5 2 männlich 1 18 4.1 0.55 X16 6 3 männlich 1 18 4.6 0.53
Bei der Betrachtung der Stichprobengrößen fällt auf, dass die Gruppe der Männer wesentlich kleiner ist als die Gruppe der Frauen. Wir haben es hier also mit unbalancierten Gruppen zu tun und müssen dies später bei der Interpretation der Ergebnisse berücksichtigen.
229
230
14 Varianzanalyse mit Messwiederholung
14.3.2 Durchführung der gemischten Varianzanalyse Die gemischte Varianzanalyse führen wir wieder mit der aov_car-Funktion aus dem afex-Paket (Singmann et al., 2020) durch, die wir auch für die einfaktorielle Varianzanalyse mit Messwiederholung verwendet haben. Bei der gemischten Varianzanalyse kommt nun der Faktor sex als weitere unabhängige Variable hinzu. Da es sich dabei um eine nicht-messwiederholte Variable handelt, wird diese Variablen direkt hinter der Tilde aufgeführt. Merke: Nicht-messwiederholte Variablen (bzw. BetweenFaktoren) erscheinen direkt hinter der Tilde und vor dem Error-Term, messwiederholte Variablen (bzw. Within-Faktoren) erscheinen im Error-Term hinter dem Schrägstrich. > anova.2 anova.2 Anova Table (Type 3 tests) Response: gs Effect df MSE F ges p.value 1 sex 1, 90 1.03 4.92 * .027 .029 2 mzp 1.83, 164.81 0.55 23.34 *** .113 ph.2a ph.2a ph.2a mzp emmean SE df lower.CL upper.CL X1 3.50 0.0975 266 3.31 3.69 X2 3.88 0.0975 266 3.69 4.07 X3 4.39 0.0975 266 4.20 4.58 Results are averaged over the levels of: sex Warning: EMMs are biased unless design is perfectly balanced Confidence level used: 0.95
Auch hier erhalten wir wieder eine Warnmeldung: Die geschätzten Mittelwerte (EMMs) sind verzerrt, es sei denn, das Design ist perfekt balanciert, d. h., alle Mittel-
14.3
Mehrfaktorielle gemischte Varianzanalyse
werte basieren auf derselben Stichprobengröße. Wir haben hier kein balanciertes Design, da wir mehr Frauen als Männer in der Stichprobe haben. Die durch emmeans geschätzten Mittelwerte entsprechen daher nicht exakt den beobachteten Mittelwerten, sondern sind die Mittelwerte, die wir erwarten würden, wenn die Anzahl der Frauen und Männer in der Stichprobe gleich gewesen wäre. Die paarweisen Mittelwertsvergleiche mit Tukey-adjustierten p-Werten erhalten wir, indem wir die pairs-Funktion auf das Objekt anwenden: > pairs(ph.2a) contrast estimate SE df t.ratio X1 - X2 -0.386 0.131 180 -2.933 X1 - X3 -0.895 0.131 180 -6.811 X2 - X3 -0.510 0.131 180 -3.877
p.value 0.0105 ph.2b pairs(ph.2b) contrast X1,weiblich X1,weiblich X1,weiblich X1,weiblich -
X2,weiblich X3,weiblich X1,männlich X2,männlich
estimate -0.4932 -1.0541 -0.5199 -0.7977
SE 0.116 0.116 0.216 0.216
df 180 180 237 237
t.ratio -4.242 -9.066 -2.403 -3.686
p.value 0.0005 ggplot(erstis, aes(x = neuro, y = lz.1)) + geom_jitter() + stat_smooth(method = loess) + xlab("Neurotizismus") + ylab("Lebenszufriedenheit")
Das damit erstellte Diagramm ist in Abbildung 15.1 dargestellt. Die beiden Variablen sind hier auf zwei Arten dargestellt: als Datenpunkte und als Loess-Kurve mit Konfidenzband. Für die Darstellung der Datenpunkte haben wir hier die Funktion geom_jitter verwendet. Diese Funktion ist dann sinnvoll, wenn viele Datenpunkte dieselben Werte haben und daher im Streudiagramm direkt übereinander liegen. Wenn wir die Datenpunkte normal darstellen würden (z. B. mit geom_point), könnten wir nicht erkennen, ob es sich bei einem Datenpunkt um einen oder um mehrere handelt. Das ist in unseren Daten der Fall, deshalb werden die einzelnen Datenpunkten zufällig ein wenig verschoben und somit entzerrt. Der Vorteil dieser Art der Darstellung ist, dass wir einen besseren Eindruck der tatsächlichen Verteilung der beiden Variablen erhalten. Ein Nachteil ist allerdings, dass die Datenpunkte nicht mehr exakt an der richtigen Stelle liegen – das darf man also nicht vergessen. Wichtig ist außerdem, dass die Entzerrung wirklich zufällig erfolgt und daher jedes Mal etwas anders aussieht. Führen Sie den Befehl mal mehrmals hintereinander aus und vergleichen Sie die Diagramme!
Abbildung 15.1 Streudiagramm mit Loess-Kurve
239
240
15 Grundlagen der Regressionsanalyse
Die Loess-Kurve ist besonders gut geeignet, um die Form des Zusammenhangs darzustellen. Je stärker diese Kurve von einer Geraden abweicht, umso stärker ist das ein Hinweis darauf, dass der Zusammenhang möglicherweise nicht linear ist. Dann wäre eine einfache lineare Regression nicht angemessen. Wie man nicht-lineare Zusammenhänge regressionsanalytisch untersuchen kann, besprechen wir in Abschnitt 16.4.
15.1.2 Berechnung der unstandardisierten Regressionskoeffizienten Für die Durchführung der Regressionsanalyse verwenden wir die lm-Funktion (linear models). In dieser Funktion verwenden wir wieder die Formelschreibweise, um das Regressionsmodell zu beschreiben. Vor der Tilde ~ steht der Name der abhängigen Variable, hinter der Tilde steht der Name der unabhängigen Variablen. Im Argument data geben wir den Namen des Data Frames an, der diese Variablen enthält. Wenn man diesen Befehl ausführt, erhält man die folgende Ausgabe: > lm(lz.1 ~ neuro, data = erstis) Call: lm(formula = lz.1 ~ neuro, data = erstis) Coefficients: (Intercept) 30.975
neuro -1.865
Wie so häufig ist die Ausgabe auf das Notwendigste beschränkt. Sie enthält lediglich die beiden Regressionsparameter. Intercept ist der englische Begriff für Achsenabschnitt. Der Wert unter neuro ist das Regressionsgewicht für diese Variable.
15.1.3 Berechnung der standardisierten Regressionskoeffizienten Manchmal kann es nützlich sein, die standardisierten Regressionskoeffizienten zu interpretieren. Dabei werden die Variablen vor der Durchführung der Regressionsanalyse z-standardisiert. In R tun wir das direkt in der lm-Funktion. Die Standardisierung wird mit der scale-Funktion durchgeführt (s. Abschn. 7.2.4). Der vollständige Befehl für die Regression lautet dann: > lm(scale(lz.1) ~ scale(neuro), data = erstis)
15.1
Einfache lineare Regression
Call: lm(formula = scale(lz.1) ~ scale(neuro), data = erstis) Coefficients: (Intercept) scale(neuro) -0.0004409 -0.2495026
Tipp
Streng genommen sollten die für die Standardisierung benötigten statistischen Kennwerte (also Mittelwert und Standardabweichung) nur mit den Personen berechnet werden, die auch in die Regressionsanalyse einfließen. Dazu speichert man alle verwendeten Variablen in einem neuen Data Frame und wendet anschließend die na.omit-Funktion an, um alle Personen mit mindestens einem fehlenden Wert auf einer der Variablen zu entfernen (s. Abschn. 7.3.3). Der Achsenabschnitt ist dann exakt 0 und das Regressionsgewicht entspricht dann exakt der Produkt-Moment-Korrelation der beiden Variablen.
15.1.4 Signifikanztests für die Regression Signifikanztests für die Regression erhalten wir, indem wir die summary-Funktion auf das Regressionsmodell anwenden. Dazu speichern wir zunächst das Modell in einem neuen Objekt. Im folgenden Beispiel nennen wir das Objekt einf.reg. Anschließend wenden wir die summary-Funktion auf das Objekt an. > einf.reg summary(einf.reg) Call: lm(formula = lz.1 ~ neuro, data = erstis) Residuals: Min 1Q -14.515 -3.914
Median 1.019
3Q 4.019
Max 9.951
Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 30.9753 1.8816 16.462 < 2e-16 *** neuro -1.8651 0.5323 -3.504 0.000574 *** --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1
241
242
15 Grundlagen der Regressionsanalyse
Residual standard error: 5.47 on 186 degrees of freedom (3 observations deleted due to missingness) Multiple R-squared: 0.06192, Adjusted R-squared: 0.05688 F-statistic: 12.28 on 1 and 186 DF, p-value: 0.0005742
Diese Ausgabe gehen wir Schritt für Schritt durch: Call. An dieser Stelle wird die Modellgleichung noch einmal aufgeführt. Residuals. Dies ist eine Fünf-Punkte-Zusammenfassung der Residuen, d. h., wir erhalten Minimum, 1. Quartil, Median, 3. Quartil und Maximum der Residuen. Hier kann man sich einen ersten Eindruck davon verschaffen, wie stark die Residuen streuen und ob die Verteilung der Residuen symmetrisch ist. In unserem Fall liegen die mittleren 50 % der Residuen zwischen -3.914 und 4.019. Coefficients. In dieser Tabelle werden die Regressionskoeffizienten (Estimate) sowie die dazugehörigen Standardfehler (Std. Error), t-Werte (t value) und p-Werte (Pr(>|t|)) aufgeführt. Die erste Zeile bezieht sich auf den Achsenabschnitt (Intercept), die zweite Zeile bezieht sich auf das Regressionsgewicht für den Prädiktor neuro. Residual standard error. Dies ist der englische Begriff für Standardschätzfehler. Dabei handelt es sich um die Standardabweichung der Residuen. Inhaltlich sagt uns dieser Wert, um wie viele Einheiten der abhängigen Variablen wir uns mit der Regression im Durchschnitt verschätzen. Je kleiner der Standardschätzfehler ist, desto besser passt das Modell. Degrees of freedom. Die Freiheitsgrade sind definiert mit df = N – k – 1, wobei N die Stichprobengröße und k die Anzahl der Prädiktoren ist. Diese Freiheitsgrade sind genau die Freiheitsgrade der t-Tests für die Regressionskoeffizienten. Schließlich werden noch der Determinationskoeffizient R² (Multiple Rsquared), der korrigierte Determinationskoeffizient (Adjusted R-squared) und der dazugehörige F-Test (F-statistic) mit Freiheitsgraden (Df) und pWert (p-value) aufgeführt. Auf diese Werte gehen wir ein, wenn wir die multiple Regression besprechen (Abschn. 15.2).
15.1.5 Konfidenzintervalle für die Regressionskoeffizienten Konfidenzintervalle für die Regressionskoeffizienten werden nicht automatisch ausgegeben, sondern müssen explizit angefordert werden. Dazu wenden wir die confint-Funktion auf das Regressionsmodell an:
15.2
Multiple Regression
> confint(einf.reg) 2.5 % 97.5 % (Intercept) 27.263163 34.6873802 neuro -2.915106 -0.8149971
Gemäß der Voreinstellung wird ein 95 %-Konfidenzintervall ausgegeben. Dies können wir mit dem Argument level verändern. Mit level = .99 fordern wir z. B. die 99 %-Konfidenzintervalle an.
15.1.6 Vorhergesagte Werte und Residuen Wenn wir eine Regressionsanalyse durchgeführt haben, haben wir für jede Person zwei neue Werte: (1) die durch die Regression vorhergesagten Werte und (2) die Residuen, d. h., die Abweichungen der vorhergesagten von den beobachteten Werten. Die vorhergesagten Werte kann man sich über die fitted-Funktion ausgeben lassen. Die Residuen fordert man über die resid-Funktion an. Wenn man diese Funktionen ausführt, erhält man die vorhergesagten Werte bzw. Residuen für jede einzelne Person (hier nicht dargestellt): > fitted(einf.reg) > resid(einf.reg)
Man kann sich auch den vorhergesagten Wert auf der Kriteriumsvariablen für einen bestimmten Wert auf der Prädiktorvariablen ausgeben lassen. Dazu wird die predict-Funktion eingesetzt. Im folgenden Beispiel lassen wir uns den vorhergesagten Wert für einen Neurotizismus-Wert von 4 ausgeben: > predict(einf.reg, data.frame(neuro = 4)) 1 23.51506
15.2 Multiple Regression Bei der multiplen Regression analysieren wir zwei oder mehr Prädiktoren. Die multiple Regression wird in R ebenfalls mit der lm-Funktion durchgeführt. Im folgenden Beispiel wird die Kriteriumsvariable Lebenszufriedenheit (lz.1) durch Neurotizismus (neuro) und Extraversion (extra) vorhergesagt. Wir speichern das Modell in
243
244
15 Grundlagen der Regressionsanalyse
einem neuen Objekt mit dem Namen mult.reg. Die beiden Prädiktoren werden mit einem + verknüpft: > mult.reg summary(mult.reg) Call: lm(formula = lz.1 ~ neuro + extra, data = erstis) Residuals: Min 1Q -14.6501 -3.1183
Median 0.6572
3Q 3.9054
Max 10.4845
Coefficients: Estimate Std. Error t value (Intercept) 24.7046 2.8364 8.710 neuro -1.9200 0.5274 -3.641 extra 1.7964 0.6103 2.944 --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01
Pr(>|t|) 1.73e-15 *** 0.000353 *** 0.003663 ** ‘*’ 0.05 ‘.’ 0.1
Residual standard error: 5.374 on 184 degrees of freedom (4 observations deleted due to missingness) Multiple R-squared: 0.1039, Adjusted R-squared: 0.09414 F-statistic: 10.66 on 2 and 184 DF, p-value: 4.146e-05
Diese Ausgabe kennen wir schon von der einfachen linearen Regression. Daher besprechen wir nur einige ausgewählte Elemente: Coefficients. In dieser Tabelle stehen alle Regressionskoeffizienten sowie ihre Standardfehler und die jeweiligen Ergebnisse des t-Tests. Multiple R-squared. Dies ist der Determinationskoeffizient R², ein Maß für die Modellgüte. Im Beispiel ist R² = .1039, d. h., die beiden Prädiktoren erklären zusammen 10.39 % der beobachteten Varianz in der Lebenszufriedenheit. Adjusted R-squared. Der Determinationskoeffizient R² ist kein erwartungstreuer Schätzer für die Varianzaufklärung in der Population. Daher wird zusätzlich noch das korrigierte R² berichtet. Das korrigierte R² ist immer kleiner als das normale R².
15.3
Hierarchische Regression
F statistic. Der Determinationskoeffizient kann inferenzstatistisch geprüft werden. Dies geschieht über einen F-Test. In unserer Ausgabe liefert der F-Test ein signifikantes Ergebnis, F(2, 184) = 10.66, p < .001, d. h., der Determinationskoeffizient ist signifikant von Null verschieden. Tipp
Wendet man die str-Funktion auf das Regressions-Objekt an, erhält man eine Liste mit allen Elementen, die man per Dollarzeichen-Funktion gezielt anfordern kann (s. Abschn. 5.3.1). Das ist z. B. dann praktisch, wenn man die Koeffiziententabelle exportieren möchte (s. Kap. 22). Diese Tabelle erhält man mit summary(mult.reg)$coefficients.
15.3 Hierarchische Regression Anstatt alle Prädiktoren auf einmal in das Regressionsmodell aufzunehmen, kann man auch schrittweise vorgehen. Dabei werden die Prädiktoren in zwei oder mehr Blöcke aufgeteilt und nacheinander in das Modell aufgenommen. Diese Vorgehensweise ist als blockweise oder hierarchische Regression bzw. hierarchical regression bekannt. Das zentrale statistische Maß beim hierarchischen Vorgehen ist der Determinationskoeffizient. Vergleicht man den Determinationskoeffizienten des sparsameren Modells mit weniger Prädiktoren (Modell 1) mit dem Determinationskoeffizienten des komplexeren Modells mit mehr Prädiktoren (Modell 2), kann man bestimmen, wie viel Varianz die im komplexeren Modell aufgenommenen Prädiktoren über die im sparsameren Modell enthaltenen Prädiktoren hinaus erklären. Man kann diesen Zuwachs des Determinationskoeffizienten über einen F-Test prüfen. Ein signifikantes Ergebnis bedeutet, dass das komplexere Modell signifikant mehr Varianz aufklärt als das sparsamere Modell. Ein nicht-signifikantes Ergebnis dagegen bedeutet, dass das komplexere Modell nicht signifikant mehr Varianz aufklärt als das sparsamere Modell, obwohl es mehr Prädiktoren enthält. In diesem Fall sollte man das sparsamere Modell bevorzugen. Stichprobe auswählen Damit zwei Regressionsmodelle miteinander verglichen werden können, ist es wichtig, dass beide auf derselben Stichprobe basieren. Um dies sicherzustellen, wählen wir zunächst die Personen aus, die gültige Werte auf allen Variablen haben, die in den beiden Regressionsmodellen vorkommen. Diese Teilstichprobe wird in einem neuen Data Frame gespeichert.
245
246
15 Grundlagen der Regressionsanalyse
Im folgenden Beispiel möchten wir in das oben analysierte Modell mit den Prädiktoren neuro und extra zusätzlich die restlichen Big-Five-Persönlichkeitsvariablen als Prädiktoren aufnehmen, also Gewissenhaftigkeit (gewiss), Verträglichkeit (vertraeg) und Intellekt/Offenheit (intell). Zunächst speichern wir diese Variablen und die abhängige Variable lz.1 in einem neuen Data Frame. Dazu verwenden wir in diesem Beispiel die select-Funktion aus dem dplyr-Paket (Wickham et al., 2020), das wir vorher laden müssen. Mit der na.omit-Funktion erreichen wir, dass alle Personen gelöscht werden, die irgendwo in diesem neuen Data Frame fehlende Werte haben (s. Abschn. 7.3.3). Der reduzierte neue Data Frame wird unter dem Namen data.red gespeichert: > data.red nrow(data.red) [1] 183
Regressionsmodelle anlegen Nun legen wir die beiden Regressionsmodelle an, die wir miteinander vergleichen möchten. Wichtig: Die beiden Modelle müssen nicht nur mit derselben Stichprobe geschätzt werden, sondern zudem geschachtelt sein. Das bedeutet: Ein Regressionsmodell muss sich in das andere überführen lassen, indem man entweder Prädiktoren hinzunimmt oder Prädiktoren wegstreicht. In unserem Datenbeispiel ist das der Fall: Das kleinere Modell lässt sich in das größere Modell überführen, indem man zwei zusätzliche Prädiktoren aufnimmt. Wir legen nun beide Regressionsmodelle an. Modell 1 ist das sparsamere Modell mit wenigen Prädiktoren. Modell 2 ist das komplexere Modell mit mehr Prädiktoren. > modell.1 modell.2 summary(modell.1)$r.squared [1] 0.0962475 > summary(modell.2)$r.squared [1] 0.1564048
Der Determinationskoeffizient für das erste Modell ist (gerundet) R² = .10. Der Determinationskoeffizient für das zweite Modell ist (gerundet) R² = .16. Die Differenz der beiden Determinationskoeffizienten rechen wir so aus: > summary(modell.2)$r.squared - summary(modell.1)$r.squared [1] 0.06015729
Das zweite Modell erklärt also ca. 6 % zusätzliche Varianz in der abhängigen Variablen. Etwas inhaltlicher ausgedrückt: Die Persönlichkeitsvariablen Gewissenhaftigkeit, Verträglichkeit und Offenheit/Intellekt erklären gemeinsam 6 % zusätzliche Varianz in der Lebenszufriedenheit, über Neurotizismus und Extraversion hinaus. Modell 2 erklärt also mehr Varianz als Modell 1. Das ist immer so: Je mehr Prädiktoren ein Modell enthält, umso mehr Varianz erklärt es, es sei denn, die zusätzlichen Prädiktoren sind perfekt unkorreliert mit dem Kriterium. Modell 2 ist aber auch komplexer, und eigentlich bevorzugen wir (zumindest in der Psychologie) einfachere Modelle mit weniger Prädikoren. Um uns für ein Modell zu entscheiden, führen wir daher zusätzlich einen Signifikanztest durch, mit dem wir prüfen, ob die Änderung in R² signifikant größer als 0 ist. Nur wenn das komplexere Modell signifikant mehr Varianz aufklärt als das sparsame Modell, sollten wir uns für dieses Modell als endgültiges Modell entscheiden. Ist der Zuwachs dagegen nicht signifikant, sollten wir das sparsamere Modell mit weniger Prädiktoren bevorzugen. Der Zuwachs in R² wird mit einem F-Test auf Signifikanz geprüft, den wir mit der anova-Funktion anfordern. Diese Funktion wird in R sehr häufig für Modellvergleiche eingesetzt und wird uns u. a. bei der logistichen Regression (s. Abschn. 16.5), den Strukturgleichungsmodellen (Kap. 19) und der Mehrebenenanalyse (Kap. 20) wieder begegnen. In die Funktion setzen wir die beiden Modelle ein, die wir miteinander vergleichen möchten: > anova(modell.1, modell.2)
247
248
15 Grundlagen der Regressionsanalyse Analysis of Variance Table Model 1: lz.1 ~ Model 2: lz.1 ~ Res.Df RSS 1 180 5221.6 2 177 4874.0 --Signif. codes:
neuro + extra neuro + extra + gewiss + vertraeg + intell Df Sum of Sq F Pr(>F) 3
347.57 4.2073 0.006646 **
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Die Ausgabe beginnt mit einer Zusammenfassung der beiden Modelle, die hier verglichen wurden. Die anschließende Tabelle enthält die folgenden Informationen: Res.Df. Nennerfreiheitsgrade für die beiden Modelle. Diese sind jeweils mit df2 = n − k − 1 definiert, wobei n für die Stichprobengröße und k für die Anzahl der Prädiktoren im jeweiligen Modell steht. Die Nennerfreiheitsgrade in der zweiten Zeile sind gleichzeitig die Nennerfreiheitsgrade des F-Tests für den Modellvergleich. RSS. Die Residual-Quadratsummen der beiden Modelle. Df. Zählerfreiheitsgrade für den F-Test. Diese sind mit df1 = k2 − k1 definiert. Dabei ist k2 die Anzahl der Prädiktoren im größeren Modell und k1 die Anzahl der Prädiktoren im kleineren Modell. Die Zählerfreiheitsgrade entsprechen also genau der Anzahl zusätzlich aufgenommener Prädiktoren (hier 3). Sum of Sq. (Zwischen-)Quadratsumme des F-Tests. F. Empirische Prüfgröße F. Pr(>F). p-Wert für den F-Test. In diesem Beispiel ist der F-Test signifikant, d. h., das zweite Modell erklärt signifikant mehr Varianz als das erste Modell, F(3, 177) = 4.21, p = .007. Tipp
Der Vergleich zweier Regressionsmodelle mit dem F-Test ist nur möglich, wenn diese Modelle ineinander geschachtelt sind. Um nicht-geschachtelte Regressionsmodelle zu vergleichen, kann man auf Informationskriterien zurückgreifen, z. B. Akaikes Information Criterion (AIC). Dabei bevorzugen wir das Modell mit dem kleineren AIC. > AIC(modell.1, modell.2)
15.4
Modellannahmen prüfen
15.4 Modellannahmen prüfen Die lineare Regressionsanalyse beruht auf einer Reihe von Annahmen, die erfüllt sein sollten, damit man korrekte Ergebnisse erhält. Eid et al. (2017) zählen unter anderem die folgenden Annahmen auf: Korrekte Spezifikation des Modells. Enthält das Modell alle relevanten und keine überflüssigen Prädiktoren? Dazu gehört auch, dass ggf. kurvilineare Zusammenhänge sowie Interaktionseffekte modelliert wurden. Normalverteilung der Residuen. Sind die Residuen normalverteilt, d. h., kommen mittlere Residuen häufiger vor als sehr kleine und sehr große Residuen? Homoskedastizität der Residuen. Ist die Varianz der Residuen über alle Ausprägungen der Prädiktoren hinweg gleich? Ausreißer und einflussreiche Datenpunkte. Gibt es Ausreißer oder andere Datenpunkte, die einen starken Einfluss auf die Schätzung haben und diese daher verzerren können? Diese Annahmen können in R mit verschiedenen Diagrammen grafisch geprüft werden (Abschn. 15.4.1). Darüber hinaus gibt es noch einige Annahmen, die man meist mithilfe statistischer Kennwerte prüft: Keine Multikollinearität. Sind die Prädiktoren untereinander nur gering korreliert? (Abschn. 15.4.3) Unabhängigkeit der Residuen. Sind die Residuen unkorreliert? (Abschn. 15.4.4)
15.4.1 Diagramme zur Prüfung der Annahmen In Kapitel 10 haben wir die plot-Funktion kennengelernt. Diese Funktion ist eine generische Funktion, d. h., je nachdem, auf welche Art von Objekten man sie anwendet, erhält man ganz unterschiedliche Diagramme. Die plot-Funktion kann man auch auf ein Regressionsmodell anwenden, das mit der lm-Funktion erstellt wurde. Wir wenden nun die plot-Funktion auf das Regressionsmodell modell.2 an, das wir in Abschnitt 15.3 angelegt haben. Wir erhalten damit vier Diagramme. Um die Diagramme gleichzeitig darstellen zu können, ändern wir zunächst die Grafik-Parameter so, dass die Diagramme in zwei Zeilen und zwei Spalten angeordnet werden (s. Abschn. 10.1.4). > par(mfrow = c(2,2)) > plot(modell.2)
249
250
15 Grundlagen der Regressionsanalyse
Bei den vier Diagrammen in Abbildung 15.2 handelt es sich um sog. Residuenplots, d. h., hier werden die Residuen des Regressionsmodells auf verschiedene Weisen grafisch dargestellt. Mit diesen Diagrammen kann man die korrekte Spezifikation, die Normalverteilung der Residuen und die Homoskedastizitätsannahme prüfen sowie Ausreißer und einflussreiche Werte identifizieren.
Abbildung 15.2 Verschiedene Residuenplots für ein Regressionsmodell. Diese Diagramme werden erstellt, wenn man die plot-Funktion auf ein lineares Modell anwendet.
Korrekte Spezifikation des Modells Im Residuals vs. Fitted-Diagramm (Abb. 15.2 oben links) werden die vorhergesagten Werte (fitted values) auf der x-Achse und die unstandardisierten Residuen (Residuals) auf der y-Achse abgetragen. Die durchgezogene Linie ist eine Loess-Kurve, die eine nonparametrische Anpassung des Zusammenhangs zwischen den beiden
15.4
Modellannahmen prüfen
Variablen darstellt. In diesem Diagramm können wir prüfen, ob das Modell korrekt spezifiziert wurde. Dies ist dann der Fall, wenn die Werte möglichst unsystematisch verteilt sind und die Loess-Kurve möglichst parallel zur x-Achse verläuft. Wichtig: Dieses Diagramm gibt keine Aussage darüber, ob theoretisch wichtige Variablen im Modell fehlen. Normalverteilung der Residuen Im Normal-Q-Q-Plot (Abb. 15.2 oben rechts) kann überprüft werden, ob die Residuen normalverteilt sind. Auf der x-Achse werden die Quantile abgetragen, die man erwarten würde, wenn Normalverteilung gegeben ist. Auf der y-Achse werden die tatsächlich beobachteten Quantile abgetragen. Wenn die Residuen normalverteilt sind, liegen sie genau auf einer Diagonalen. Homoskedastizität Das Scale-Location-Diagramm (Abb. 15.2 unten links) dient zur Überprüfung der Homoskedastizitätsannahme. In diesem Diagramm werden die vorhergesagten Werte (Fitted values) auf der x-Achse und die standardisierten Residuen (Standardized Residuals) auf der y-Achse abgetragen. Homoskedastizität ist dann gegeben, wenn die Residuen möglichst unsystematisch im Diagramm verteilt sind. Ausreißer und einflussreiche Werte In den ersten drei Diagrammen werden Ausreißerwerte automatisch mit ihrer Zeilennummer markiert. Besonders geeignet zur Identifikation von Ausreißern und einflussreichen Werten ist jedoch das Residual vs. Leverage-Diagramm (Abb. 15.2 unten rechts). Auf der x-Achse dieses Diagramms werden die Hebelwerte (Leverage) abgetragen. Der Hebelwert ist ein Maß für die Abweichung einzelner Werte auf den unabhängigen Variablen. Ausreißer kann man an ihren großen Hebelwerten erkennen. Ausreißerwerte sind aber an sich noch nicht schlimm, solange sie sich einigermaßen konform verhalten – das heißt, nicht zu sehr von den durch die Regression vorhergesagten Werten abweichen. Diese Abweichung ist auf der y-Achse in Form der standardisierten Residuen (Standardized Residuals) abgetragen. In diesem Diagramm kann man also für Ausreißer (definiert durch hohe Hebelwerte) erkennen, ob sie auffällige Residuen haben. In unserem Beispiel werden die extremsten Werte (d. h., die Werte mit großen Residuen und großen Hebelwerten) über ihre Zeilennummer identifiziert. In manchen Diagrammen sind außerdem eine oder mehrere rote gestrichelte Linien unten bzw. oben rechts eingetragen. Diese Linien markieren bestimmte Werte für Cook’s Distance. Mit diesem Maß können einflussreiche Werte
251
252
15 Grundlagen der Regressionsanalyse
identifiziert werden. Liegen einzelne Datenpunkte jenseits dieser gestrichelten Linien, so handelt es sich dabei um Werte, die die Regressionsgleichung in einem hohen Maß beeinflussen. In unserem Beispiel trifft dies auf keine Datenpunkte zu.
15.4.2 Identifizierung von Ausreißern und einflussreichen Werten Zusätzlich zu den oben dargestellten Diagrammen kann man auch spezielle Funktionen verwenden, um Ausreißer und einflussreiche Werte zu identifizieren. Diese Funktionen sind in Tabelle 15.1 zusammengefasst. Zur Interpretation der Werte siehe Eid et al. (2017). Tabelle 15.1 Funktionen zur Identifizierung von Ausreißern und einflussreichen Werten
Funktion
Beschreibung
resid(modell)
Unstandardisierte Residuen
rstandard(modell)
Standardisierte Residuen
rstudent(modell)
Ausgeschlossene studentisierte Residuen
dfbeta(modell)
DfBETA
dfbetas(modell)
DfBETAS
dffits(modell)
DfFits
cooks.distance(modell)
Cook’s Distance
15.4.3 Kollinearitätsdiagnosen Unter Multikollinearität versteht man die multiple Korrelation eines Prädiktors mit allen anderen (unabhängig davon, wie stark die Prädiktoren jeweils mit der abhängigen Variable korrelieren). Das Ausmaß der Multikollinearität wird über die Toleranz und den Variance Inflation Factor (VIF) quantifiziert (vgl. Eid et al., 2017). Die Toleranz hat einen Wertebereich von 0 bis 1 und sollte möglichst nahe 1 liegen und nicht kleiner als 0.10 werden. Der VIF ist der Kehrwert der Toleranz. Auch der VIF sollte nahe 1 liegen und nicht größer als 10 werden. Den VIF kann man mit der vif-Funktion aus dem car-Paket (Fox & Weisberg, 2019) berechnen. Diese Funktion wird auf das Regressionsmodell angewandt: > vif(modell.2) neuro extra gewiss vertraeg intell 1.040712 1.151644 1.157277 1.261203 1.171001
15.4
Modellannahmen prüfen
Die Toleranz ist der Kehrwert des VIF (s. o.) und kann daher folgendermaßen berechnet werden: > 1/vif(modell.2) neuro extra gewiss vertraeg intell 0.9608807 0.8683241 0.8640977 0.7928938 0.8539699
15.4.4 Unabhängigkeit der Residuen Die Annahme der Unabhängigkeit der Residuen ist in den folgenden Fällen häufig verletzt: (1) Die Stichprobe besteht aus mehreren Gruppen, d. h., die Daten haben eine hierarchische Struktur. (2) Bei Längsschnittdaten stehen die Werte der einzelnen Messzeitpunkte in einer serialen Abhängigkeit. Bei diesen Fällen handelt es sich um Spezialfälle, die wir hier aus Platzgründen nicht detailliert behandeln. Wir gehen daher nur kurz auf die Besonderheiten dieser Fälle ein und nennen die Funktionen, mit denen man die Unabhängigkeit der Residuen in beiden Fällen prüfen kann. Nähere Informationen zu den Funktionen findet man wie immer mit der help-Funktion. Hierarchische Daten Die Unabhängigkeit der Residuen ist meistens verletzt, wenn wir geschachtelte (hierarchische) Designs haben. In solchen Designs besteht die Gesamtstichprobe aus mehreren Gruppen, z. B. Schulklassen, Organisationseinheiten oder Therapiegruppen. Die einzelnen Personen lassen sich eindeutig bestimmten Gruppen zuordnen, z. B. gehören Schüler zu bestimmten Schulklassen, Mitarbeiter gehören zu bestimmten Teams und Patienten gehören zu einzelnen Therapiegruppen. Die einzelnen Personen sind ihren Gruppenmitgliedern häufig ähnlicher als Personen aus anderen Gruppen. Diese Ähnlichkeit drückt sich statistisch in der Intraklassenkorrelation aus. Die Berechnung der Intraklassenkorrelation wird in Abschnitt 20.1 besprochen. Je größer die Intraklassenkorrelation ist, desto unterschiedlicher sind die einzelnen Gruppen und desto ähnlicher sind sich die Personen innerhalb der Gruppen. Wenn die Intraklassenkorrelation größer als Null ist, muss man die Gruppenzugehörigkeit im Regressionsmodell berücksichtigen, z. B. indem man Mehrebenenanalysen durchführt (s. Kap. 20). Seriale Abhängigkeit Bei längsschnittlichen Erhebungen kann es vorkommen, dass die Ausprägung eines Residuums zu einem bestimmten Messzeitpunkt von den zeitlich früheren Residuen
253
254
15 Grundlagen der Regressionsanalyse
beeinflusst wird. Dies nennt man auch Autokorrelation der Residuen. Wenn eine solche Abhängigkeit vorliegt, sollte man geeignete längsschnittliche Verfahren einsetzen. Die seriale Abhängigkeit der Residuen wird mit dem Durbin-Watson-Test überprüft. Dieser Test kann mit der durbinWatsonTest-Funktion aus dem car-Paket (Fox & Weisberg, 2019) angefordert werden.
15.5 Die wichtigsten Funktionen im Überblick Funktion
Beschreibung
lm(y ~ x)
Einfache lineare Regression mit einer abhängigen Variablen y und einem Prädiktor x.
lm(y ~ x1 + x2)
Multiple Regression mit einer abhängigen Variablen y und zwei Prädiktoren x1 und x2.
summary()
Wird diese generische Funktion auf ein Regressionsmodell angewandt, erhält man die Ergebnisse der Regressionsanalyse.
confint()
Konfidenzintervalle für die einzelnen Regressionskoeffizienten des Regressionsmodells.
fitted()
Vorhergesagte Werte des Regressionsmodells.
resid()
Residuen des Regressionsmodells.
predict()
Vorhergesagte Werte für bestimmte Werte auf den Prädiktorvariablen.
anova()
Vergleicht die Determinationskoeffizienten von zwei Regressionsmodellen mit einem F-Test.
plot()
Wird diese generische Funktion auf ein lineares Modell angewandt, erhält man verschiedene Diagramme zur Überprüfung der Modellannahmen des Regressionsmodells.
vif()*
Gibt die Variance Inflation Factors (VIF) für jeden Prädiktor des Regressionsmodells an. Funktion aus dem car-Paket.
* Funktionen aus zusätzlichen Paketen
15.6
Übungen
15.6 Übungen Diese Übungen beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze). (1) Modell 1. Berechnen Sie eine lineare Regression mit guter vs. schlechter Stimmung (gs.1) als abhängige Variable und ruhiger vs. unruhiger Stimmung (ru.1) als Prädiktor. Bestimmen Sie den vorhergesagten gs.1-Stimmungswert für eine Person mit einem ru.1-Stimmungswert von 4. (2) Modell 2. Nehmen Sie zusätzlich den Prädiktor wm.1 (wache vs. müde Stimmung) auf. Überprüfen Sie die Modellannahmen. (3) Modell 3. Nehmen Sie zusätzlich die Variable neuro als Prädiktor auf. Prüfen Sie, ob der Zuwachs des Determinationskoeffizienten R² signifikant ist, indem Sie einen F-Test durchführen. Tipp: Damit eine solche hierarchische Regressionsanalyse funktioniert, dürfen keine Personen mit fehlenden Werten auf den zu analysierenden Variablen im Data Frame enthalten sein (s. Abschn. 7.3.3).
Powered by TCPDF (www.tcpdf.org)
255
256
16 Spezielle Regressionsmodelle
16
Spezielle Regressionsmodelle
Die multiple Regressionsanalyse lässt sich auf verschiedene Arten erweitern. In diesem Kapitel besprechen wir, wie man kategoriale Variablen als Prädiktoren aufnimmt (Abschn. 16.1) und in der Kovarianzanalyse mit metrischen Prädiktoren kombiniert (Abschn. 16.2). Darüber hinaus ist es möglich, Interaktionen zwischen Prädiktoren (Abschn. 16.3) und nicht-lineare Zusammenhänge (Abschn. 16.4) zu modellieren. Zum Schluss behandeln wir die logistische Regression, bei der eine dichotome abhängige Variable vorliegt (Abschn. 16.5). Die Beispiele in diesem Kapitel beziehen sich auf die Datensätze haustier.RData und samstag.RData (s. Anhang A: Datensätze).
16.1 Kategoriale Prädiktoren Im Rahmen des allgemeinen linearen Modells (ALM) lassen sich sowohl kontinuierliche Prädiktoren (wie in der einfachen Regressionsanalyse) als auch kategoriale Prädiktoren (wie in der Varianzanalyse) analysieren. Im folgenden Beispiel analysieren wir die Variablen tierart und wohlbefinden aus dem Datensatz haustier.RData. Die Variable tierart gibt an, welches Haustier die Personen besitzen. Es handelt sich um eine kategoriale Variable mit den Ausprägungen Hund, Katze und Pferd. Diese Variable ist unsere unabhängige Variable bzw. unser Prädiktor. Die Variable wohlbefinden gibt das Wohlbefinden der Versuchspersonen an. Diese metrisch skalierte Variable wird unsere abhängige Variable bzw. Kriteriumsvariable sein. Falls Sie dieses Buch von vorne bis hinten durcharbeiten, kommt Ihnen dieses Beispiel vielleicht bekannt vor: Wir haben diese Variablen schon in Kapitel 13 mit einer einfaktoriellen Varianzanalyse analysiert. Hieran kann man gut erkennen, dass Regressionsanalyse und Varianzanalyse eigentlich dasselbe sind – beide sind Varianten des ALM und lassen sich ineinander überführen. Wir werden das gleich direkt sehen.
16.1
Kategoriale Prädiktoren
16.1.1 Codierung von kategorialen Prädiktoren Kategoriale Variablen werden häufig als Dummyvariablen codiert. In R werden für einen als Faktor definierten Prädiktor in einer Regression automatisch Dummyvariablen angelegt. Das heißt, man muss die Dummyvariablen nicht selbst erstellen. Da die Variable tierart bereits als Faktor definiert ist, wird R diese Variable automatisch dummycodieren. Die von R automatisch gewählte Codierung erhalten wir mit der contrasts-Funktion: > contrasts(haustier$tierart) Katze Pferd Hund 0 0 Katze 1 0 Pferd 0 1
In dieser Tabelle kann man erkennen, dass für die drei Ausprägungen der Variablen tierart (Zeilen) zwei Dummyvariablen (Spalten) gebildet wurden. Dummyvariablen können nur die Werte 0 oder 1 annehmen. Die Referenzkategorie (hier die Ausprägung Hund) wird auf allen Dummyvariablen mit 0 codiert. Die anderen Kategorien erhalten auf je einer der Dummyvariablen den Wert 1 und auf allen anderen Dummyvariablen den Wert 0. Tipp
Die Auswahl der Referenzgruppe sollte am besten auf der Grundlage theoretischer Überlegungen geschehen. R kann zwar viel, aber sozialwissenschaftliche Theorien gehören nicht dazu. Daher wählt R die Ausprägung als Referenzkategorie, die bei den deskriptiven Statistiken zuerst aufgeführt wird. Wenn man eine andere Ausprägung als Referenzkategorie haben möchte, kann man diese Einstellung mit der relevel-Funktion verändern: > haustier$tierart.r contr.sum(3) [,1] [,2] 1 1 0 2 0 1 3 -1 -1
Wir erhalten damit eine Matrix, die wir mithilfe der contrasts-Funktion auf die kategoriale Variable übertragen: > contrasts(haustier$tierart) contrasts(haustier$tierart) [,1] [,2] Hund 1 0 Katze 0 1 Pferd -1 -1
Darüber hinaus gibt es komplexere Codierschemata wie z. B. Helmert-Kontraste (Funktion contr.helmert) oder nicht-lineare Kontraste (Funktion contr.poly). Die standardmäßige Dummycodierung kann man mit der Funktion contr.treatment erstellen. Wir machen im Folgenden mit der ursprünglichen Codierung weiter.
16.1.2 Durchführung der Regression mit kategorialen Prädiktoren Nun nehmen wir die kategoriale Variable wie gewohnt als Prädiktor in die lm-Funktion auf. R erkennt, dass es sich um einen Faktor handelt und das Codierschema automatisch an (hier: Dummycodierung). > reg.kat summary(reg.kat) Call: lm(formula = wohlbefinden ~ tierart, data = haustier)
16.1 Residuals: Min 1Q Median -4.4533 -1.2266 -0.0406
3Q 1.1370
Kategoriale Prädiktoren
Max 3.9187
Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 5.2000 0.3336 15.588 haustier$geld.c kov summary(kov) Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 5.331609 0.307719 17.326 < 2e-16 *** tierartKatze 0.072494 0.432808 0.167 0.867397 tierartPferd 0.885538 0.465234 1.903 0.060537 . geld.c 0.000925 0.000228 4.057 0.000114 *** --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1
261
262
16 Spezielle Regressionsmodelle
Der Achsenabschnitt ist immer der vorhergesagte Wert auf der abhängigen Variablen, wenn alle Prädiktoren den Wert 0 annehmen. Hier ist der Achsenabschnitt also der vorhergesagte Wohlbefindenswert für Hundebesitzer (tierart = 0) mit genau durchschnittlichem Einkommen (geld.c = 0). Man sagt auch: Dies ist der adjustierte Mittelwert für Hundebesitzer, d. h., der Mittelwert, den wir für Hundebesitzer mit einem bestimmten Einkommen erwarten würden. Die Regressionskoeffizienten für die Dummyvariablen tierartKatze und tierartPferd geben jeweils an, wie stark sich der vorhergesagte Wert für diese Katzen- bzw. Pferdebesitzer von dem der Hundebesitzer unterscheidet, wenn Einkommen konstant gehalten wird. Wir tun also so, als würden wir Tierbesitzer mit genau gleichem Einkommen miteinander vergleichen. Schauen Sie mal das Ergebnis für die Pferdebesitzer genauer an: Anders als in Abschnitt 16.1 ist dieser Regressionskoeffizient jetzt nicht mehr signifikant von Null verschieden. Wenn man also für Einkommensunterschiede kontrolliert, sind die noch verbleibenden Unterschiede im Wohlbefinden zwischen Pferde- und Hundebesitzern nicht mehr signifikant von Null verschieden. Der Regressionskoeffizient für geld.c ist positiv und signifikant, d. h., Tierbesitzer mit einem höheren Einkommen haben tendenziell auch ein höheres Wohlbefinden, kontrolliert für die Art des Haustieres.
16.2.3 Adjustierte Mittelwerte Adjustierte Mittelwerte sind die Mittelwerte, die man für verschiedene Gruppen erhalten würde, wenn die Kovariaten bestimmte Werte annähmen. Meistens wird für die Kovariaten der Wert 0 eingesetzt. Wir haben eben schon den adjustierten Mittelwert für die Referenzgruppe ermittelt – es war der Achsenabschnitt der Kovarianzanalyse. Die adjustierten Mittelwerte der anderen beiden Gruppen könnten wir bestimmen, indem wir den jeweiligen Regressionskoeffizienten zum Achsenabschnitt addieren. Zum Beispiel ist der Regressionskoeffizient der Katzenbesitzer ca. 0.07, d. h., der adjustierte Mittelwert für Katzenbesitzer mit einem genau durchschnittlichen Einkommen wäre 5.33 + 0.07 = 5.40. Wir müssen aber die adjustierten Mittelwerte nicht selbst ausrechnen, sondern können stattdessen das emmeans-Paket (Lenth, 2019) verwenden, das wir bei den Varianzanalysen schon für Post-hoc-Paarvergleiche eingesetzt haben (s. Kap. 13 und Kap. 14). Damit erhalten wir nicht nur die adjustierten Mittelwerte, sondern auch deren Standardfehler und Konfidenzintervalle. In der emmeans-Funktion geben wir im ersten Argument den Namen des Regressions-Objekts an, und im Argument specs den Namen der Variablen, für die wir adjustierte Mittelwerte bestimmen wollen.
16.3
Moderierte Regression
> emmeans(kov, specs = "tierart") tierart emmean SE df lower.CL upper.CL Hund 5.33 0.308 81 4.72 5.94 Katze 5.40 0.307 81 4.79 6.02 Pferd 6.22 0.342 81 5.54 6.90 Confidence level used: 0.95
Alternativ können wir auch die Formelschreibweise verwenden (s. Abschn. 13.1.3). Das machen wir im folgenden Befehl. Außerdem speichern wir hier die Ausgabe als Objekt. > kov.m pairs(kov.m) contrast estimate SE df t.ratio Hund - Katze -0.0725 0.433 81 -0.167 Hund - Pferd -0.8855 0.465 81 -1.903 Katze - Pferd -0.8130 0.464 81 -1.753
p.value 0.9847 0.1443 0.1921
P value adjustment: tukey method for comparing a family of 3 estimates
In diesem Beispiel gibt es keine signifikanten Unterschiede zwischen den adjustierten Mittelwerten.
16.3 Moderierte Regression Mit der moderierten Regression kann man überprüfen, ob die Stärke des Zusammenhangs zwischen zwei Variablen von der Ausprägung einer dritten Moderatorvariablen abhängt. Statistisch entspricht dies einer Interaktion zwischen der Moderatorvariablen und einer der anderen beiden Variablen. Interaktionen zwischen zwei Variablen werden mathematisch immer als das Produkt zwischen den Variablen behandelt:
263
264
16 Spezielle Regressionsmodelle
Y = b0 + b1 ⋅ X + b2 ⋅ Z + b3 ⋅ X ⋅ Z + E
(Formel 16.1)
Wir betrachten in diesem Abschnitt zwei relativ einfache Fälle der moderierten Regression: Interaktion zwischen einer kategorialen und einer metrischen Variablen und Interaktion zwischen zwei metrischen Variablen. Die hier verwendeten Funktionen lassen sich auch auf komplexere Modelle mit Interaktionen höherer Ordnung (z. B. Dreifach-Interaktionen) oder mit zusätzlichen Kovariaten anwenden. In beiden Datenbeispielen verwenden wir die haustier-Daten. Im ersten Datenbeispiel möchten wir herausfinden, ob sich Stärke des Zusammenhangs zwischen Einkommen (metrischer Prädiktor geld) und Wohlbefinden (abhängige Variable wohlbefinden) zwischen den drei Gruppen der Haustierbesitzer (kategorialer Prädiktor tierart) unterscheidet. Im zweiten Datenbeispiel untersuchen wir, ob der Zusammenhang zwischen Einkommen (metrischer Prädiktor geld) und Wohlbefinden (abhängige Variable wohlbefinden) von der Ausprägung von Neurotizismus (metrischer Prädiktor neuro) abhängt.
16.3.1 Prädiktoren zentrieren Wie schon bei der Kovarianzanalyse ist es auch bei der moderierten Regression sinnvoll, dass alle metrischen Prädiktoren interpretierbare Nullpunkte haben. Das ist bei uns noch nicht der Fall, daher zentrieren wir beide metrischen Prädiktoren mit der scale-Funktion. Zudem wenden wir die as.numeric-Funktion auf die beiden zentrierten Variablen an. Die scale-Funktion ändert nämlich den Variablentyp, was den meisten anderen Funktionen egal ist, nicht aber der interact_plot-Funktion, die wir in Abschnitt 16.3.3 einsetzen werden. Diese Funktion erwartet eine numerische Variable, daher müssen wir dies hier direkt richtig machen. > haustier$geld.c haustier$neuro.c mod.reg.1 Anova(mod.reg.1) Anova Table (Type II tests) Response: wohlbefinden Sum Sq Df F value Pr(>F) tierart 12.065 2 2.2063 0.1168 geld.c 46.228 1 16.9073 9.539e-05 *** tierart:geld.c 11.538 2 2.1099 0.1280 Residuals 216.004 79 --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Hier wird die Interaktion mit einem F-Test geprüft. Im Grunde handelt es sich hierbei um eine hierarchische Regression, bei der geprüft wird, ob die Interaktion über die anderen Prädiktoren hinaus signifikant zusätzliche Varianz aufklärt (vgl. Abschn. 15.3). In diesem Datenbeispiel ist dieser Effekt nicht signifikant von Null verschieden. Tipp
Die Anova-Funktion verwendet standardmäßig Typ-II-Quadratsummen, d. h., die Signifikanztests für die beiden Haupteffekte tierart und geld.c geben an, ob diese Prädiktoren signifikant mit der abhängigen Variablen zusammenhängen, bevor die Interaktion kontrolliert wird. Wir könnten auch Typ-III-Quadratsummen anfordern, indem wir das Argument type = 3 ergänzen. Das würde an
265
266
16 Spezielle Regressionsmodelle
dem Signifikanztest für die Interaktion nichts ändern, wohl aber an den Signifikanztests für die anderen beiden Haupteffekte. Diese geben dann nämlich an, ob die beiden Prädiktoren über die Interaktion hinaus noch zusätzliche Varianz in der abhängigen Variablen erklären. Wir können außerdem das Ergebnis in Form von Regressionskoeffizienten anfordern. Dazu verwenden wir wie gewohnt die summary-Funktion. Wir haben uns hier nur die auf drei Nachkommastellen gerundeten Koeffizienten ausgeben lassen: > round(summary(mod.reg.1)$coef, 3) Estimate Std. Error t value Pr(>|t|) (Intercept) 5.381 0.306 17.608 0.000 tierartKatze 0.038 0.432 0.088 0.930 tierartPferd 1.078 0.471 2.288 0.025 geld.c 0.001 0.000 3.820 0.000 tierartKatze:geld.c 0.000 0.001 -0.403 0.688 tierartPferd:geld.c -0.001 0.001 -2.020 0.047
Was ist denn hier passiert – warum haben wir so viele Regressionskoeffizienten, wo wir doch oben nur zwei Variablen in die Formel eingegeben haben? Keine Sorge, es hat alles seine Richtigkeit. Der kategoriale Prädiktor tierart hat drei Ausprägungen, daher werden automatisch zwei Dummyvariablen angelegt. Die Interaktion zwischen dem metrischen Prädiktor geld.c und tierart wird dann für jede der beiden Dummyvariablen getrennt bestimmt. Aber gehen wir die Tabelle von oben nach unten durch. Der Achsenabschnitt (Intercept) ist der vorhergesagte Wohlbefindenswert für Hundebesitzer mit durchschnittlichen Einkommen (da durch die Zentrierung von Einkommen der Wert 0 genau dem Mittelwert entspricht). Die Regressionskoeffizienten der Dummyvariablen tierartKatzen und tierartPferd sind die bedingten Haupteffekte dieser Variablen, d. h., sie geben an, wie stark sich diese Gruppen jeweils von der Referenzgruppe der Hundebesitzer unterscheiden, wenn alle genau durchschnittliches Einkommen haben. Der Regressionskoeffizient für geld.c gibt den bedingten Haupteffekt für Einkommen an, d. h., den Zusammenhang zwischen Einkommen und Wohlbefinden, wenn die Variable tierart den Wert 0 annimmt. In unserem Fall gibt dieser Koeffizient also den Zusammenhang zwischen Einkommen und Wohlbefinden für Hundebesitzer (tierart = 0) an. Ist der Zusammenhang zwischen Einkommen und Wohlbefinden für Katzenund Pferdebesitzer stärker oder schwächer als für Hundebesitzer? Diese Frage können wir mit den Regressionskoeffizienten der jeweiligen Interaktionseffekte beantworten. Der Regressionskoeffizient für tierartKatze:geld.c ist sehr klein und
16.3
Moderierte Regression
nicht signifikant von Null verschieden, d. h., Hunde- und Katzenbesitzer unterscheiden sich nicht signifikant darin, wie stark Einkommen und Wohlbefinden zusammenhängen. Anders sieht das (mal wieder) bei den Pferdebesitzern aus. Der Regressionskoeffizient für tierartPferd:geld.c ist signifikant von Null verschieden. Genauer gesagt ist er kleiner als Null, d. h., der Zusammenhang zwischen Einkommen und Wohlbefinden ist bei den Pferdebesitzern schwächer ausgeprägt als bei den Hundebesitzern. Obwohl der F-Test oben ergeben hatte, dass die Interaktion insgesamt nicht signifikant war, kann es also vorkommen, dass die Regressionskoeffizienten einzelner Interaktionseffekte (knapp) signifikant sind. Wenn wir alle Interaktionseffekte einzeln betrachten, haben wir aber durch die multiplen Tests ein Problem mit der α-Fehler-Kumulierung (s. Kap. 13). Fanden Sie die Interpretation der einzelnen Regressionskoeffizienten schwierig nachzuvollziehen? Damit sind Sie nicht alleine. Die Regressionskoeffizienten enthalten zwar alle notwendigen Informationen, um die Interaktion interpretieren zu können, aber das ist nicht leicht, besonders bei komplexeren Modellen. In Abschnitt 16.3.3 berechnen wir daher bedingte Regressionskoeffizienten und stellen diese grafisch dar, um uns die Interpretation zu erleichtern. Interaktion zwischen zwei metrischen Prädiktoren Der Befehl für die moderierte Regression mit Interaktion zwischen den metrischen Prädiktoren Einkommen und Neurotizismus sieht folgendermaßen aus: > mod.reg.2 Anova(mod.reg.2) Anova Table (Type II tests) Response: wohlbefinden Sum Sq Df F value Pr(>F) geld.c 29.564 1 15.4267 0.0001794 neuro.c 69.535 1 36.2838 4.782e-08 geld.c:neuro.c 14.842 1 7.7445 0.0067021 Residuals 155.230 81 --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’
*** *** **
0.05 ‘.’ 0.1 ‘ ’ 1
267
268
16 Spezielle Regressionsmodelle
Da wir hier Typ-II-Quadratsummen verwendet haben, geben die F-Tests für die Variablen geld.c und neuro.c an, ob diese Variablen jeweils einen signifikanten Anteil der Varianz im Wohlbefinden erklären, kontrolliert für die jeweils andere Variable, aber noch unabhängig von der Interaktion. Wenn wir eine multiple Regression ohne Interaktion durchführen würden, erhielten wir für die Regressionskoeffizienten der beiden Prädiktoren dieselben p-Werte wie in dieser Tabelle. Mit dem Argument type = 3 fordern wir Typ-III-Quadratsummen an. Die F-Tests für die Variablen geld.c und neuro.c würden dann angeben, ob diese Variablen über die Interaktion hinaus signifikant zusätzliche Varianz im Wohlbefinden erklären würden. Der F-Test für die Interaktion ist bei beiden Quadratsummen-Typen derselbe: Er ist signifikant, d. h., der Zusammenhang zwischen Einkommen und Wohlbefinden unterscheidet sich je nach Ausprägung von Neurotizismus. Wie stark und in welche Richtung wissen wir allerdings nicht. Dazu betrachten wir die Regressionskoeffizienten. Diese erhalten wir wie immer mit der summary-Funktion (hier verkürzte Darstellung der Ausgabe): > summary(mod.reg.2) Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 5.7410551 0.1565651 36.669 < 2e-16 *** geld.c 0.0006734 0.0001909 3.527 0.000695 *** neuro.c -0.5778297 0.1601902 -3.607 0.000534 *** geld.c:neuro.c 0.0005051 0.0001815 2.783 0.006702 **
Wir gehen diese Tabelle von oben nach unten durch. Der Achsenabschnitt (Intercept) gibt den vorhergesagten Wohlbefindenswert für Personen mit durchschnittlichem Einkommen (geld.c = 0) und durchschnittlichem Neurotizismus (neuro = 0) an. Der Regressionskoeffizient der Variablen geld.c ist der bedingte Effekt von Einkommen auf Wohlbefinden, d. h., der Zusammenhang zwischen Einkommen und Wohlbefinden für Personen mit einem Neurotizismuswert von 0. Dieser Regressionskoeffizient ist signifikant von Null verschieden, d. h., bei Personen mit durchschnittlichem Neurotizismus (neuro.c = 0) hängt das Einkommen signifikant positiv mit dem Wohlbefinden zusammen. Vorsicht: Der p-Wert hier bezieht sich auf genau diesen bedingten Zusammenhang. Der p-Wert für diese Variable oben in der Ausgabe der Anova-Funktion gibt dagegen an, ob diese Variable insgesamt mit dem Wohlbefinden zusammenhängt, unabhängig von der Interaktion.
16.3
Moderierte Regression
Für neuro.c haben wir einen negativen und signifikant von Null verschiedenen Regressionskoeffizienten. Das bedeutet: Für Personen mit durchschnittlichem Einkommen (geld.c = 0) besteht ein signifikanter negativer Zusammenhang zwischen Neurotizismus und Wohlbefinden. Der p-Wert für den t-Test für den Regressionskoeffizienten des Interaktionsterms geld.c:neuro.c ist identisch mit dem p-Wert, den wir oben beim F-Test für die Interaktion erhalten haben. Dieser Regressionskoeffizient gibt an, um wie viele Einheiten sich der Zusammenhang zwischen einem der beiden Prädiktoren und der abhängigen Variablen verändert, wenn wir den anderen Prädiktor um eine Einheit erhöhen. Wir können also sagen: Wenn wir Neurotizismus um eine Einheit erhöhen, erhöht sich die Stärke des Zusammenhangs zwischen Einkommen und Wohlbefinden um 0.0005 Einheiten – je neurotischer die Personen sind, desto stärker hängt ihr Einkommen mit ihrem Wohlbefinden zusammen. Auch hier gilt wieder: Es ist zwar möglich, die Interaktion nur anhand der Regressionskoeffizienten zu verstehen, aber nicht einfach. Um die Interpretation zu erleichtern, bestimmen wir daher im nächsten Abschnitt bedingte Regressionskoeffizienten und stellen diese grafisch dar.
16.3.3 Bedingte Regressionsgleichungen und Interaktionsdiagramm Interaktionseffekte sind häufig schwierig zu interpretieren. Um die Interpretation zu vereinfachen, werden daher gerne sog. bedingte Regressionsgleichungen (simple regression equations) berechnet. Dabei wird der Zusammenhang zwischen dem einen Prädiktor (X) und der abhängigen Variablen (Y) für verschiedene Ausprägungen der Moderatorvariablen (Z) berechnet. Für die Berechnung und Darstellung bedingter Regressionsgleichungen wurden in den letzten Jahren eine ganze Reihe von Paketen entwickelt. Wir verwenden hier zunächst das Paket emmeans (Lenth, 2019), das wir bei der Varianzanalyse (s. Kap. 13 und Kap. 14) und in diesem Kapitel bei der Kovarianzanalyse (s. Abschn. 16.2.3) schon oft verwendet haben. Für die grafische Darstellung setzen wir das Paket interactions (Long, 2019a) ein. Auch empfehlenswert ist das Paket sjPlot (Lüdecke, 2020a), das wir hier aber nicht vertiefen. Bedingte Regressionskoeffizienten für eine kategoriale Moderatorvariable Ist einer der beiden Prädiktoren eine kategoriale Variable, wird meistens diese Variable als Moderator gewählt und der Zusammenhang zwischen dem anderen (sog. fokalen) Prädiktor X und der abhängigen Variablen Y für jede Ausprägung der kategorialen Variablen Z bestimmt.
269
270
16 Spezielle Regressionsmodelle
Mit der emtrends-Funktion aus dem emmeans-Paket (Lenth, 2019) bestimmen wir bedingte Regressionskoeffizienten für verschiedene Ausprägungen der kategorialen Variablen. Das erste Argument in der Funktion ist das Regressionsobjekt, das wir oben gespeichert haben. Im Argument var wird der fokale Prädiktor angegeben, also der metrische Prädiktor, dessen Regressionskoeffizienten uns interessieren. Im Argument specs geben wir die Moderatorvariable an, also die Variable, von deren Ausprägungen die Höhe der Regressionskoeffizienten abhängt. > mod.em.1 mod.em.1 tierart geld.c.trend SE df lower.CL upper.CL Hund 0.001269 0.000332 79 0.000608 0.00193 Katze 0.001055 0.000416 79 0.000227 0.00188 Pferd 0.000136 0.000451 79 -0.000762 0.00104
Wir erhalten hier für jede Ausprägung der Variablen tierart den bedingten Regressionskoeffizienten der Variablen geld.c (trend) sowie deren Standardfehler (SE), Freiheitsgrade (df) und Konfidenzintervalle (lower.CL und upper.CL). Wir können hier erkennen, dass der Zusammenhang zwischen Einkommen und Wohlbefinden für Hunde- und Katzenbesitzer jeweils signifikant von Null verschieden ist (da das Konfidenzintervall den Wert 0 nicht enthält), nicht jedoch für Pferdebesitzer (da das Konfidenzintervall den Wert 0 enthält). Ob sich aber die bedingten Regressionskoeffizienten signifikant voneinander unterscheiden, erkennen wir hier nicht. Dazu wenden wir die pairs-Funktion auf das Objekt an: > pairs(mod.em.1) contrast estimate SE df t.ratio Hund - Katze 0.000214 0.000532 79 0.403 Hund - Pferd 0.001132 0.000561 79 2.020 Katze - Pferd 0.000918 0.000614 79 1.496
p.value 0.9144 0.1140 0.2982
P value adjustment: tukey method for comparing a family of 3 estimates
16.3
Moderierte Regression
Wir sehen, dass keiner der paarweisen Vergleiche der bedingten Regressionskoeffizienten signifikant ist, wenn wir den α-Fehler mit der Tukey-Methode adjustieren. Das deckt sich mit dem nicht-signifikanten F-Test, den wir oben erhalten haben. Wir könnten die bedingten Regressionskoeffizienten mit der plot-Funktion visualisieren, wie wir es bei der Varianzanalyse getan haben. Besonders schön ist diese Art der Darstellung aber nicht (probieren Sie es aus, dann wissen Sie warum). Für die grafische Darstellung der bedingten Regressionsgleichungen verwenden wir daher hier die Funktion interact_plot aus dem Paket interactions (Long, 2019a). Im einfachsten Fall sieht der Befehl so aus: > interact_plot(mod.reg.1, pred = geld.c, modx = tierart)
Das erste Argument ist der Name des Regressionsobjekts. Im Argument pred geben wir den fokalen Prädiktor an, der auf der x-Achse dargestellt werden soll. Im Argument modx geben wir die Moderatorvariable an. Das damit erstellte Diagramm ist in Abbildung 16.1 oben links dargestellt. Hier wird für jede Ausprägung der Moderatorvariablen eine eigene Regressionsgerade dargestellt. Das Aussehen des Diagramms kann durch eine Reihe von Argumenten innerhalb der interact_plot-Funktion beeinflusst werden. Da diese Funktion auf ggplot2 (Wickham, 2016) aufbaut, können außerdem die üblichen ggplot2-Funktionen verwendet werden (s. Abschn. 10.2). Im folgenden Beispiel lassen wir die Datenpunkte darstellen (plot.points = TRUE), und zwar mit unterschiedlichen Symbolen je nach Ausprägung der Moderatorvariablen (point.shape = TRUE) und ergänzen Konfidenzbänder für die Regressionsgeraden (interval = TRUE). Das damit erstellte Diagramm ist in Abbildung 16.1 oben rechts dargestellt. > interact_plot(mod.reg.1, pred = geld.c, modx = tierart, plot.points = TRUE, point.shape = TRUE, interval = TRUE)
Bedingte Regressionskoeffizienten für eine metrische Moderatorvariable Wenn es sich bei der Moderatorvariablen um eine metrische Variable handelt, macht es keinen Sinn, die bedingten Regressionsgleichungen für alle Ausprägungen dieser Variablen zu bestimmen. Stattdessen legt man bestimmte Werte der Moderatorvariablen fest, für die die bedingten Regressionsgleichungen berechnet werden sollen. Oft nimmt man den Mittelwert (M) sowie die Werte, die genau eine Standardabweichung unterhalb bzw. oberhalb des Mittelwerts liegen: M – 1 SD und M + 1 SD. Je nach Fragestellung und Verteilung der Variablen können aber auch andere Werte Sinn machen.
271
272
16 Spezielle Regressionsmodelle
Abbildung 16.1 Verschiedene Interaktionsdiagramme für moderierte Regressionsanalysen, erstellt mit der interact_plot-Funktion
Wir verwenden wieder die emtrends-Funktion. Wie beim Beispiel mit der kategorialen Moderatorvariablen geben wir zunächst den Namen des Regressionsobjekts, den fokalen Prädiktor (Argument var) und die Moderatorvariable (Argument specs) an. Zusätzlich geben wir im at-Argument an, für welche Werte der Variablen neuro.c die bedingten Regressionsgleichungen berechnet werden sollen. Wir nehmen hier die Werte -1.15 und 1.15, was genau M – 1 SD und M + 1 SD entspricht. Diese Werte haben wir hier vorher selbst berechnet; eleganter wäre es, diese Berechnung direkt in den Befehl zu integrieren. Das at-Argument erwartet immer eine Liste. > mod.em.2 mod.em.2 neuro.c geld.c.trend SE df lower.CL upper.CL -1.15 9.25e-05 0.000301 81 -0.000506 0.000691 1.15 1.25e-03 0.000264 81 0.000730 0.001779 Confidence level used: 0.95
16.3
Moderierte Regression
Wir erhalten nun die bedingten Regressionskoeffizienten (trend) sowie die dazugehörigen Standardfehler (SE), Freiheitsgrade (df) und Konfidenzintervalle (lower.CL und upper.CL). Wir sehen, dass der Zusammenhang für höhere Neurotizismuswerte stärker ist als für niedrigere Neurotizismuswerte. Da es sich bei den beiden Werten der Moderatorvariablen um ziemlich willkürliche Werte handelt, macht es meistens wenig Sinn, diese beiden bedingten Regressionskoeffizienten direkt inferenzstatistisch miteinander zu vergleichen, wie wir es eben bei der kategorialen Moderatorvariablen mit der pairs-Funktion getan haben. Um die bedingten Regressionsgleichungen grafisch darzustellen, greifen wir wieder auf die interact_plot-Funktion aus dem interactions-Paket (Long, 2019a) zurück. Wir erstellen zunächst eine einfache Variante des Diagramms: > interact_plot(mod.reg.2, pred = geld.c, modx = neuro.c)
Im ersten Argument geben wir den Namen des Regressionsobjekts an. Im Argument pred wird die fokale Variable aufgeführt, im Argument modx die Moderatorvariable. Das damit erstellte Diagramm ist in Abbildung 16.1 unten links zu sehen. Wir erhalten hier drei Regressiongeraden: für -1 SD, M und +1 SD. Auch dieses Diagramm können wir wieder durch zusätzliche Argumente verändern. Im folgenden Beispiel legen wir fest, dass nur die Regressionsgeraden für die Werte -1 SD und +1 SD dargestellt werden (modx.values = "plus-minus"), dass Konfidenzbänder hinzugefügt werden (interval = TRUE) und dass die Datenpunkte dargestellt werden sollen (plot.points = TRUE). Das damit erstellte Diagramm ist in Abbildung 16.1 unten rechts abgebildet. > interact_plot(mod.reg.2, pred = geld.c, modx = neuro.c, modx.values = "plus-minus", interval = TRUE, plot.points = TRUE)
Johnson-Neyman-Intervall Das Johnson-Neyman-Intervall gibt den Bereich der Moderatorvariablen an, für den der Zusammenhang zwischen der fokalen Variablen und der abhängigen Variablen signifikant von Null verschieden ist. Wir bestimmen dieses Intervall mit der johnson_neyman-Funktion aus dem interactions-Paket (Long, 2019a). Die ersten drei Argumente in dieser Funktion sind dieselben wie in der interact_plot-Funktion. Das Argument alpha bezieht sich auf den Grad der Transparenz der Farben in dem Diagramm, das mit dieser Funktion erstellt wird. Die Argumente sig.color und insig.color ändern die im Diagramm verwendeten Farben in schwarz und grau, damit das Diagramm in Grautönen gedruckt werden kann.
273
274
16 Spezielle Regressionsmodelle > johnson_neyman(mod.reg.2, pred = geld.c, modx = neuro.c, alpha = .05, sig.color = "black", insig.color = "grey") JOHNSON-NEYMAN INTERVAL When neuro.c is OUTSIDE the interval [-5.27, -0.47], the slope of geld.c is p < .05. Note: The range of observed values of neuro.c is [-1.78, 2.22]
In der Ausgabe wird uns das Johnson-Neyman-Interval angegeben und, zur besseren Einordnung, auch der beobachtete Wertebereich der Moderatorvariablen. In diesem Beispiel ist der Zusammenhang zwischen Einkommen und Wohlbefinden signifikant für Neurotizismuswerte außerhalb des Intervalls [-5.27, -0.47]. Der obere Wert kann sinnvoll interpretiert werden, da es tatsächlich Personen gibt, die höhere Neurotizismuswerte als -0.47 haben. Der untere Werte ist dagegen nicht zu interpretieren, da dieser Wert in den Daten nicht vorkommt.
Abbildung 16.2 Grafische Darstellung des Johnson-Neyman-Intervalls für die Interaktion zwischen zwei metrischen Variablen
16.4
Nicht-lineare Regression
Zusätzlich erhalten wir automatisch das in Abbildung 16.2 dargestellte Diagramm. Auf der x-Achse sind hier die Werte der Moderatorvariablen (hier: neuro.c) dargestellt. Auf der y-Achse sind die bedingten Regressionskoeffizienten dargestellt für den Zusammenhang zwischen der fokalen Variablen (hier: geld.c) und der abhängigen Variablen (hier: wohlbefinden). Die gestrichelte vertikale Linie markiert den Wert der Moderatorvariablen, ab dem der Zusammenhang zwischen der fokalen Variablen und der abhängigen Variablen signifikant wird.
16.4 Nicht-lineare Regression Die lineare Regression kann, wie der Name schon sagt, nur lineare Zusammenhänge zwischen Variablen angemessen modellieren. Durch ein paar Kniffe können wir aber die Regression dazu bringen, auch nicht-lineare Zusammenhänge abzubilden, z. B. indem man Polynome höherer Ordnung in die Gleichung aufnimmt. Im einfachsten Fall nimmt man einen zusätzlichen quadratischen Term in die Gleichung auf: Y = b0 + b1 ⋅ X + b2 ⋅ X² + E
(Formel 16.2)
Die einzelnen Polynome werden als eigene Prädiktoren behandelt. Wichtig: Polynome niederigerer Ordnung müssen immer im Modell enthalten sein. Um die Interpretation zu erleichtern und einen Teil der Multikollinearität zu entschärfen, ist es meistens sinnvoll, die Prädiktoren vorher zu zentrieren. Wir betrachten in diesem Abschnitt den Zusammenhang zwischen Einkommen (geld.c, bereits zentrierte unabhängige Variable) und Wohlbefinden (wohlbefinden, abhängige Variable). Die Variable geld.c haben wir in Abschnitt 16.3.1 erstellt.
16.4.1 Grafische Darstellung Die grafische Darstellung von nicht-linearen Zusammenhängen ist in ggplot2 etwas komfortabler als mit den klassischen Grafik-Funktionen. Daher setzen wir hier die ggplot-Funktion ein. Eine einfache Art, die Form des Zusammenhangs grafisch zu untersuchen, ist die Loess-Kurve. Dabei handelt es sich um eine nicht-parametrische Anpassungskurve, die den Zusammenhang der Variablen darstellt, ohne dabei eine bestimmte Form des Zusammenhangs (z. B. linear) anzunehmen. Wir erstellen also zunächst ein Streudiagramm mit Loess-Kurve (s. Abschn. 10.3.5):
275
276
16 Spezielle Regressionsmodelle > ggplot(haustier, aes(x = geld, y = wohlbefinden)) + geom_point() + stat_smooth(method = "loess")
Die Loess-Kurve in dem in Abbildung 16.3 links dargestellten Diagramm ist eindeutig nicht-linear. Möglicherweise lässt sich diese Form des Zusammenhangs mit einem quadratischen oder einem kubischen Modell darstellen. Wir können das grafisch erkunden, indem wir eine quadratische und eine kubische Anpassungskurve ins Streudiagramm einfügen. Dazu verwenden wir die stat_smooth-Funktion mit der lmMethode und ergänzen die Formel um die quadratischen bzw. kubischen Polynome: >
ggplot(haustier, aes(x = geld, y = wohlbefinden)) + geom_point() + stat_smooth(method = "lm", formula = y ~ x + I(x^2), linetype = 2)+ stat_smooth(method = "lm", formula = y ~ x + I(x^2) + I(x^3))
Abbildung 16.3 Streudiagramme zum Zusammenhang zwischen Einkommen (Variable geld) und Wohlbefinden (Variable wohlbefinden) mit einer Loess-Anpassungskurve (links) und mit quadratischen und kubischen Anpassungskurven (gestrichelt bzw. durchgezogene Kurve) rechts
Die quadratischen und kubischen Terme x^2 bzw. x^3 werden jeweils in die I-Funktion eingesetzt. Dadurch werden diese Terme als separate Prädiktoren behandelt. Die quadratische Kurve wird mit linetype = 2, also gestrichelt dargestellt. Die
16.4
Nicht-lineare Regression
kubische Kurve wird als durchgezogene Linie dargestellt. Das damit erstellte Diagramm ist in Abbildung 16.3 rechts dargestellt. Die beiden Kurven unterscheiden sich rein optisch nicht wesentlich. Welches Regressionsmodell am besten passt, prüfen wir aber am besten mit der Regressionsanalyse, nicht rein grafisch.
16.4.2 Durchführung der nicht-linearen Regression Auch für die nicht-lineare Regression verwenden wir die lm-Funktion. Um den quadratischen Zusammenhang zu modellieren, wird die die zentrierte unabhängige Variable zweimal aufgenommen: einmal normal (geld.c) und einmal quadriert (geld.c^2). Für einen kubischen Zusammenhang nimmt man zusätzlich noch geld.c^3 auf. Die Polynome werden in die Funktion I() eingegeben. Dadurch erreichen wir, dass diese Terme als separate Prädiktoren behandelt werden. > quadr kub summary(quadr) Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 5.725e+00 2.488e-01 23.015 < 2e-16 *** geld.c 1.055e-03 2.265e-04 4.657 1.22e-05 *** I(geld.c^2) -1.592e-07 2.465e-07 -0.646 0.52 > summary(kub) Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 5.732e+00 2.500e-01 22.931 < 2e-16 *** geld.c 1.269e-03 4.164e-04 3.048 0.00311 ** I(geld.c^2) -1.555e-07 2.476e-07 -0.628 0.53177 I(geld.c^3) -1.414e-10 2.301e-10 -0.614 0.54062
277
278
16 Spezielle Regressionsmodelle
In beiden Modellen ist der lineare Term signifikant von Null verschieden, die quadratischen und kubischen Terme jedoch nicht. Woran liegt das – die Loess-Kurve war doch eindeutig nicht-linear? Ein Blick auf die Rohwerte hilft hier weiter. Wir sehen, dass die Stichprobe insgesamt eher klein war, besonders in den extremen Bereichen, in denen die Loess-Kurve vom linearen Zusammenhang abwich. Möglicherweise war die Stichprobe zu klein, um nicht-lineare Zusammenhänge mit ausreichender Teststärke aufdecken zu können. Oder es handelt sich um rein zufällige Abweichungen von der Linearität. Dieses Datenbeispiel zeigt, wie wichtig es ist, auch die Rohwerte zu visualisieren und wenn möglich immer grafische und statistische Ergebnisse gemeinsam zu betrachten.
16.5 Logistische Regression Beim Allgemeinen Linearen Modell (ALM) muss die abhängige Variable metrisch sein. Verallgemeinerte lineare Modelle sind eine Erweiterung des ALM auf nichtmetrische abhängige Variablen. In R werden verallgemeinerte lineare Modelle mit der glm-Funktion (GLM = generalized linear model) geschätzt. Die meisten Funktionen, die wir auf lm-Modelle anwenden konnten (z. B. summary, confint, predict), funktionieren auch für glm-Modelle. In diesem Abschnitt betrachten wir als einführendes Beispiel die logistische Regression, bei der wir es mit einer dichotomen abhängigen Variablen zu tun haben, also einer Variable mit zwei Ausprägungen. Das Datenbeispiel bezieht sich auf den Datensatz samstag.RData (s. Anhang A: Datensätze).
16.5.1 Durchführung der logistischen Regression Im folgenden Beispiel möchten wir Prädiktoren der Samstagabend-Gestaltung untersuchen. Die abhängige Variable ausgehen erfasst, ob jemand ausgegangen ist (codiert mit 1) oder nicht (codiert mit 0). In der logistischen Regression werden die beiden Ausprägungen der abhängigen Variable grundsätzlich mit 0 und 1 codiert. In der logistischen Regression sagen wir die Wahrscheinlichkeit vorher, auf dieser Variablen den Wert 1 zu erhalten: P(Y = 1). In unserem Beispiel ist die abhängige Variable als numerischer Vektor mit den Ausprägungen 0 und 1 angelegt. Wenn wir stattdessen einen Faktor als abhängige Variable verwenden, wird dieser automatisch umcodiert, und zwar so, dass die Ausprägung, die mit der levels-Funktion als erste aufgeführt wird, die 0 erhält und die Ausprägung, die mit der levels-Funktion als zweite aufgeführt wird, die 1.
16.5
Logistische Regression
Als Prädiktoren betrachten wir Extraversion (extra) und ob jemand am Vorabend bereits ausgegangen ist (gestern mit 0 = nicht ausgegangen und 1 = ausgegangen). Der Befehl für dieses logistische Regressionsmodell ist folgendermaßen aufgebaut: > log.reg summary(log.reg) Call: glm(formula = ausgehen.f ~ extra + gestern, family = binomial, data = samstag) Deviance Residuals: Min 1Q Median -2.4819 -0.8069 0.3407
3Q 0.4853
Max 1.7713
Coefficients: Estimate Std. Error z value Pr(>|z|) (Intercept) 1.5299 0.5384 2.842 0.00448 ** extra 0.3087 0.1350 2.287 0.02221 * gestern -3.0370 0.4748 -6.396 1.59e-10 *** --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 (Dispersion parameter for binomial family taken to be 1) Null deviance: 204.82 Residual deviance: 137.71 AIC: 143.71
on 161 on 159
degrees of freedom degrees of freedom
Number of Fisher Scoring iterations: 5
279
280
16 Spezielle Regressionsmodelle
Nach der Modellgleichung (Call) und den Residuenstatistiken (Deviance Residuals) erhalten wir eine Tabelle mit den Regressionskoeffizienten (Coefficients) sowie deren Standardfehler (Std. Error), z-Werte (z value) und p-Werte (Pr(>|z|)). Beide Regressionskoeffizienten sind signifikant von Null verschieden. Der Regressionskoeffizient von extra ist positiv, der Regressionskoeffizient von gestern ist negativ. Die Wahrscheinlichkeit, am Samstagabend auszugehen, ist also höher für Personen mit höheren Extraversionswerten und geringer für Personen, die am vorherigen Abend schon ausgegangen waren. Wichtig: Die Werte der Regressionskoeffizienten geben nicht an, um wie viel sich die Wahrscheinlichkeit verändert, sondern beziehen sich auf den sog. Logit. Der Logit ist der natürliche Logarithmus des Wettquotienten (zur Herleitung und Interpretation dieser Werte siehe Eid et al., 2017). Die Ausgabe enthält außerdem Angaben zu den Devianzen. Die Devianz ist ein Maß für die Modellgüte. Je kleiner die Devianz ist, desto besser passt das Modell auf die Daten, d. h., desto besser ist die Modellgüte. Die Null deviance ist die Devianz des sog. Nullmodells, also eines Modells, das keine Prädiktoren enthält. Die Residual deviance ist die Devianz für unser Modell. Die Devianz sollte deutlich kleiner sein als die Devianz des Nullmodells. AIC steht für Akaikes Information Criterion und ist ebenfalls ein Indikator für die Modellgüte. Je kleiner der AIC, desto besser ist das Modell. Die Devianz ist vor allem dann interessant, wenn man mehrere miteinander verschachtelte Modelle miteinander vergleichen möchte (s. Abschn. 16.5.3). Der Ausdruck Number of Fisher Scoring iterations: 5 zeigt an, wie viele Iterationen benötigt wurden, um die Modellparameter zu schätzen. Eine hohe Anzahl von Iterationen (> 25) deutet daraufhin, dass das Modell nicht gut auf die Daten passt.
16.5.2 Berechnung der Odds Ratios Mit der summary-Funktion erhalten wir Regressionskoeffizienten, die den Zusammenhang zwischen den Prädiktoren und dem sog. Logit der abhängigen Variablen ausdrücken. Der entscheidende Vorteil der Logit-Darstellung ist, dass dieser mit den Prädiktoren in einem linearen Zusammenhang steht. Allerdings sind Logits auch sehr schwer zu interpretieren (s. Eid et al., 2017). Eine Möglichkeit, die Interpretation etwas zu vereinfachen (wobei sich darüber streiten lässt, ob dies tatsächlich eine Erleichterung darstellt), besteht darin, die Regressionskoeffizienten an der Eulerischen Zahl e zu exponieren. Damit wird die abhängige Variable nicht mehr als Logit, sondern als Wettquotient (engl. odds) dargestellt. Wettquotienten geben das Verhältnis einer Wahrscheinlichkeit zu ihrer Gegenwahrscheinlichkeit an; hier also die Wahrscheinlichkeit, am Samstagabend auszugehen geteilt durch die Wahrscheinlichkeit, am Samstagabend zuhause zu bleiben. Der Begriff kommt aus dem Sport; hier werden
16.5
Logistische Regression
Wahrscheinlichkeiten für bestimmte Ergebnisse häufig in Wettquoten oder Chancen angegeben (z. B. Chance auf einen Sieg von 2:1). Um diese Transformation für unser Datenbeispiel durchzuführen, lassen wir uns zunächst noch einmal die Regressionskoeffizienten ausgeben. Dies geschieht mit der coef-Funktion: > coef(log.reg) (Intercept) extra 1.5299487 0.3087427
gestern -3.0370445
Diese Regressionskoeffizienten setzen wir nun in die exp-Funktion ein: > exp(coef(log.reg)) (Intercept) extra 4.61793986 1.36171202
gestern 0.04797647
Der Achsenabschnitt entspricht nun dem vorhergesagten Wettquotienten, wenn alle Prädiktoren den Wert 0 annehmen. Die Werte für die beiden Prädiktoren geben an, um welchen Faktor sich der vorhergesagte Wettquotient verändert, wenn der jeweilige Prädiktor um eine Einheit erhöht wird und gleichzeitig der andere Prädiktor konstant gehalten wird. Man bezeichnet diesen Wert auch als Wettquotientenverhältnis oder, etwas kürzer, als Odds Ratio (OR). Der Odds Ratio für den dichotomen Prädiktor gestern ist 0.05. Um herauszufinden, wie hoch die Chance aufs Ausgehen ist für Personen, die am Vorabend zuhause geblieben sind (gestern = 1), müssen wir also den Wert des Wettquotienten für gestern = 0 (hier: Achsenabschnitt 4.62) mit diesem Wert multiplizieren. Da 0.05 kleiner als 1 ist, wird die Chance aufs Ausgehen kleiner und sinkt sogar unter 1 (4.62 ∙ 0.05 = 0.23), d. h., für Personen, die am Vorabend schon ausgegangen sind, ist es wahrscheinlicher, dass sie am Samstagabend zuhause bleiben, als dass sie ausgehen.
16.5.3 Modellvergleiche mit dem Likelihood-Ratio-Test Um Regressionskoeffizienten der logistischen Regression inferenzstatistisch zu prüfen, stehen verschiedene Signifikanztests zur Verfügung: z-Test, Wald-Test und Likelihood-Ratio-Test (vgl. Eid et al., 2017). Standardmäßig werden in R die Regressionskoeffizienten mit dem z-Test getestet (s. Abschn. 16.5.1). Der Wald-Test basiert auf den quadrierten z-Werten und kommt immer zum selben Ergebnis. Der Likelihood-Ratio-Test hat dagegen eine etwas andere Logik und kommt auch zu etwas
281
282
16 Spezielle Regressionsmodelle
anderen Ergebnissen. Er hat tendenziell eine höhere Teststärke als der z-Test und wird daher bevorzugt. Der Likelihood-Ratio-Test vergleicht die Devianzen zweier geschachtelter Modelle miteinander. Er ist somit vergleichbar mit dem F-Test für die Differenz in R², den wir bei der hierarchischen Regression kennengelernt haben (s. Abschnitt 15.3). Die Differenz der Devianzen ist χ²-verteilt. Die Freiheitsgrade für den LikelihoodRatio-Test entsprechen der Differenz der Freiheitsgrade der einzelnen Modelle. In R können wir den Likelihood-Ratio-Test auf zwei Wegen durchführen. Am schnellsten geht es mit der Anova-Funktion (mit großem A!) aus dem car-Paket (Fox & Weisberg, 2019). Diese Funktion gibt uns für jeden Prädiktor das Ergebnis des Likelihood-Ratio-Tests an. Das ist so, als hätten wir für jeden Prädiktor ein Modell ohne diesen Prädiktor (aber mit allen anderen Prädiktoren) und ein Modell mit diesem Prädiktor jeweils miteinander verglichen. > Anova(log.reg) Analysis of Deviance Table (Type II tests) Response: ausgehen LR Chisq Df Pr(>Chisq) extra 5.674 1 0.01721 * gestern 58.040 1 2.568e-14 *** --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Wir können auch die geschachtelten Modelle per Hand anlegen und dann miteinander vergleichen. Für den Modellvergleich verwenden wir die anova-Funktion (mit kleinem a!), die wir schon bei der hierarchischen Regression für Modellvergleiche eingesetzt haben (s. Abschn. 15.3). Wir führen nun den Likelihood-Ratio-Test für den Prädiktor gestern durch. Wir legen zunächst zwei logistische Regressionsmodelle an, eines ohne diesen Prädiktor und eines mit diesem Prädiktor: > log.reg.1 log.reg.2 anova(log.reg.1, log.reg.2, test = "Chisq") Analysis of Deviance Table Model 1: ausgehen ~ extra Model 2: ausgehen ~ extra + gestern Resid. Df Resid. Dev Df Deviance Pr(>Chi) 1 160 195.75 2 159 137.71 1 58.04 2.568e-14 ***
Die Ausgabe beginnt mit den beiden Modellgleichungen. In der anschließenden Tabelle erscheinen die Freiheitsgrade (Resid. df) und die Residualdevianzen (Resid. Dev) der beiden Modelle. Die Spalte deviance enthält die Differenz der beiden Devianzen, also den χ²-Wert. Freiheitsgrade und p-Wert für den Likelihood-Ratio-Test finden wir in den Spalten Df und Pr(>Chi). Wir erhalten hier dieselben Werte, die wir oben mit der Anova-Funktion für den Prädiktor gestern erhalten haben. Das schrittweise Durchführen des Likelihood-Ratio-Tests ist deutlich umständlicher als das Verwenden der Anova-Funktion, daher würde man für den Test eines einzelnen Prädiktors die Anova-Funktion bevorzugen. Ein Vorteil des schrittweisen Durchführens ist jedoch, dass wir hier auch mehrere Prädiktoren auf einmal testen können, so wie wir es bei der hierarchischen Regression gemacht haben.
16.6 Die wichtigsten Funktionen im Überblick Funktion
Beschreibung
contrasts()
Gibt die aktuelle Codierung eines Faktors aus.
relevel()
Legt eine bestimmte Faktorstufe eines Faktors als Referenzkategorie fest.
emmeans()*
Berechnet adjustierte Mittelwerte und führt paarweise Mittelwertsvergleiche mit Tukey-Adjustierung durch. Funktion aus dem emmeans-Paket.
lm(y ~ x1 * x2)
Moderierte Regression mit einer abhängigen Variablen y und zwei Prädiktoren x1 und x2. Es werden sowohl die Haupteffekte für x1 und x2 als auch der Interaktionseffekt berechnet.
Anova()*
Testet kategoriale oder metrische Prädiktoren auf Signifikanz mithilfe von Modellvergleichen (Typ-IITests oder Typ-III-Tests). Funktion aus dem carPaket.
283
284
16 Spezielle Regressionsmodelle
emtrends()*
Bestimmt bedingte Regressionskoeffizienten für ausgewählte Werte auf einer kategorialen oder metrischen Moderatorvariablen. Funktion aus dem emmeans-Paket.
interact_plot()*
Darstellung von bedingten Regressionsgeraden. Funktion aus dem interactions-Paket.
johnson_neyman()*
Berechnung und grafische Darstellung des JohnsonNeyman-Intervalls für die moderierte Regression. Funktion aus dem interactions-Paket.
lm(y ~ x + I(x^2))
Regression zur Modellierung des quadratischen Zusammenhangs zwischen x und y.
glm(y ~ x, family = binomial)
Logistische Regression mit der abhängigen Variablen y und dem Prädiktor x.
anova(model1, model2, test = "Chi")
Likelihood-Ratio-Test für den Vergleich von zwei logistischen Regressionsmodellen.
* Funktionen aus zusätzlichen Paketen
16.7 Übungen Diese Übungen beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze). (1) Überprüfen Sie regressionsanalytisch, ob sich Personen mit und ohne Kinder (kinder) in ihrer Prokrastination (prok) unterscheiden. Die Prokrastination ist Ihre abhängige Variable. (2) Berechnen Sie den Interaktionseffekt von Gewissenhaftigkeit (gewiss) und Neurotizismus (neuro) auf die Prokrastination (prok). Vergessen Sie nicht, die unabhängigen Variablen zu zentrieren. Stellen Sie die bedingten Regressionsgeraden grafisch dar. (3) Führen Sie eine Kovarianzanalyse durch mit der abhängigen Variablen Prokrastination (prok) und den Prädiktoren kinder und gewiss. Berechnen Sie die adjustierten Mittelwerte für Personen mit und ohne Kinder. (4) Überprüfen Sie, ob es einen quadratischen Zusammenhang zwischen der Prokrastination (prok; Prädiktor) und der Lebenszufriedenheit (lz.1; abhängige Variable) gibt. (5) Versuchen Sie mit einer logistischen Regression vorherzusagen, welche Personen einen Nebenjob (job; abhängige Variable) haben. Prüfen Sie die folgenden Variablen als Prädiktoren: kinder, gewiss, lz.1.
Powered by TCPDF (www.tcpdf.org)
17.1
17
Der chi²-Test
Nonparametrische Verfahren
Bei den bisher vorgestellten inferenzstatistischen Tests handelte es sich meist um sog. parametrische Verfahren, die bestimmte Eigenschaften der abhängigen Variablen voraussetzen, z. B. Intervallskalenniveau oder Normalverteilung. Wenn die Voraussetzungen für diese Tests nicht erfüllt sind, kann man auf nonparametrische Verfahren zurückgreifen. Diese Verfahren haben weniger strenge Voraussetzungen bezüglich der Verteilungseigenschaften der abhängigen Variablen, ihre Aussagekraft und statistische Teststärke ist allerdings eingeschränkter. Wir besprechen hier nur den χ²-Test (Abschn. 17.1), den Wilcoxon-Test (Abschn. 17.2) sowie den Kruskal-Wallis-Test (Abschn. 17.3). Die Beispiele in diesem Kapitel beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze).
17.1 Der chi²-Test Der χ²-Test ist einer der wichtigsten nonparametrischen Tests. Allgemein dient dieser Test dazu, beobachtete Werte mit erwarteten Werten zu vergleichen. Der χ²-Wert ist umso größer, je stärker die beobachteten Werte von den erwarteten Werten abweichen. Wir besprechen hier zwei einfache Beispiele für den Test, den χ²-Anpassungstest sowie den zweidimensionalen χ²-Test. Der χ²-Test begegnet uns aber auch in vielen anderen Bereichen, z. B. als Indikator für den Modellfit bei Strukturgleichungsmodellen. Es lohnt sich daher, die Grundidee dieses Tests zu verstehen.
17.1.1
Der chi²-Anpassungstest
Mit dem χ²-Anpassungstest wird überprüft, ob die beobachtete Häufigkeitsverteilung einer Variablen von einer vorgegebenen Häufigkeitsverteilung abweicht. Wir untersuchen im folgenden Beispiel, ob die Häufigkeitsverteilung des Geschlechts (geschl) in unserer Stichprobe der Häufigkeitsverteilung in der Population entspricht. Wir erstellen zunächst eine Häufigkeitstabelle für das Geschlecht und speichern diese in einem neuen Objekt ab: > tab.1 tab.1 weiblich männlich 115 55 > prop.table(tab.1) weiblich männlich 0.6764706 0.3235294
Wie wir sehen, liegt der Frauenanteil in unserer Stichprobe bei ca. 67 %. Wir führen nun den χ²-Anpassungstest durch, um die Nullhypothese zu prüfen, dass der Frauenbzw. Männeranteil bei jeweils 50 % liegt. Dazu wenden wir die chisq.test-Funktion auf die Häufigkeitstabelle an (d. h., nicht auf die Rohdaten!): > chisq.test(tab.1) Chi-squared test for given probabilities data: tab.1 X-squared = 21.176, df = 1, p-value = 4.189e-06
Das Ergebnis des Tests ist signifikant mit χ²(1) = 21.18, p < .001. Das heißt, dass die Häufigkeitsverteilung in unserer Stichprobe bedeutsam von der Häufigkeitsverteilung in der Population abweicht. Die chisq.test-Funktion prüft standardmäßig, ob eine Gleichverteilung der Gruppen vorliegt. Wenn man andere Proportionen testen möchte, ergänzt man das Argument p. Mit p = c(.7,.3) prüfen wir bspw., ob die Verteilung in der Stichprobe signifikant von einer Verteilung mit 70 % Frauen und 30 % Männern abweicht.
17.1.2 Der zweidimensionale chi²-Test Der χ²-Test kann auch verwendet werden, um den Zusammenhang zwischen zwei nominalskalierten Variablen inferenzstatistisch zu prüfen. Für jede Kombination der Ausprägungen der beiden Variablen wird die beobachtete Häufigkeit mit der erwarteten Häufigkeit verglichen, also mit der Häufigkeit, die man erwarten würde, wenn es keinen Zusammenhang zwischen den Variablen gäbe. Je größer die Abweichungen zwischen den beobachteten und den erwarteten Häufigkeiten sind, desto größer wird der χ²-Wert und desto stärker ist der Zusammenhang zwischen den Variablen.
17.1
Der chi²-Test
Wir untersuchen nun, ob es einen Zusammenhang zwischen dem Statistikkurs (gruppe) und dem Geschlecht (geschl) gibt. Wir erstellen zunächst eine Kontingenztabelle mit den absoluten Häufigkeiten und speichern diese Tabelle als neues Objekt: > tab.2 addmargins(tab.2) Kurs 1 Kurs 2 Kurs 3 Kurs 4 Sum weiblich 33 29 22 31 115 männlich 13 18 12 12 55 Sum 46 47 34 43 170
Wir sehen, dass insgesamt deutlich mehr Frauen als Männer an der Befragung teilgenommen haben. Daher ist es nicht überraschend, dass in jedem Kurs die Zahl der Männer geringer als die Zahl der Frauen ist. Um herauszufinden, ob es einen systematischen Zusammenhang zwischen dem Geschlecht und der Kurswahl gibt, führen wir den χ²-Test durch. Dazu verwenden wir wieder die chisq.test-Funktion, die wir im vorherigen Abschnitt kennengelernt haben: > chisq.test(tab.2) Pearson's Chi-squared test data: tab.2 X-squared = 1.6337, df = 3, p-value = 0.6518
Der Test ist nicht signifikant, χ²(3) = 1.63, p = .652. Es besteht also kein Zusammenhang zwischen dem Geschlecht und der Kurswahl. Erwartete Werte und Residuen Es ist manchmal nützlich, die erwarteten Werte und die Residuen (d. h., die Abweichungen zwischen den beobachteten und erwarteten Werten) anzuschauen. Die erwarteten Werte erhält man, indem man den Ausdruck $expected hinter der chisq.test-Funktion ergänzt. Die standardisierten Residuen erhält man über die Ergänzung $residuals:
287
288
17 Nonparametrische Verfahren > chisq.test(tab.2)$expected > chisq.test(tab.2)$residuals
Was wir nicht direkt anfordern können, sind die unstandardisierten Residuen. Diese müssen wir Hand berechnen als Abweichung der erwarteten Werte von den beobachteten Werten: > chisq.test(tab.2)$observed - chisq.test(tab.2)$expected
Korrektur von Yates Wenn man den χ²-Test bei einer 2 × 2 Tabelle anwendet, wird standardmäßig die Korrektur von Yates angewandt. Dies demonstrieren wir im folgenden Beispiel für die dichotomen Variablen geschl und berlin: > chisq.test(table(erstis$geschl, erstis$berlin)) Pearson's Chi-squared test with Yates' continuity correction data: table(erstis$geschl, erstis$berlin) X-squared = 0.49486, df = 1, p-value = 0.4818
Um den klassischen χ²-Test nach Pearson anzufordern, muss man die chisq.testFunktion um das Argument correct = FALSE ergänzen. Dies gilt aber nur für 2 × 2 Tabellen. Sobald eine der Variablen mehr als zwei Ausprägungen hat, wird automatisch der χ²-Test nach Pearson durchgeführt. Tipp
Wenn die erwartete Häufigkeit in mehr als 20 % der Zellen unter 5 liegt, sollte man den χ²-Test nicht anwenden. Als Alternative steht der exakte Test nach Fisher zur Verfügung. Diesen Test kann man mit der Funktion fisher.test anfordern.
17.2 Der Wilcoxon-Test Der Wilcoxon-Test ist eine nonparametrische Alternative zu den t-Tests, die wir in Kapitel 12 besprochen haben. Dieser Test wird mit der wilcox.test-Funktion angefordert. Diese Funktion funktioniert genauso wie die t.test-Funktion, d. h., die meisten Argumente der t.test-Funktion können hier genauso eingesetzt werden.
17.2
Der Wilcoxon-Test
17.2.1 Eine Stichprobe Der hier vorgestellte Wilcoxon-Test ist eine Alternative zum t-Test für eine Stichprobe. Mit diesem Test wird die zentrale Tendenz der Stichprobe mit der (bekannten) zentralen Tendenz in der Population verglichen. Im folgenden Beispiel betrachten wir das Item stim1 (»zufrieden«). Dieses Item wurde auf einer fünfstufigen Antwortskala mit den Ausprägungen 1 (überhaupt nicht) bis 5 (sehr) beantwortet. Wir glauben, dass die zentrale Tendenz dieses Items ungefähr bei 3 liegen müsste, da dies die mittlere Antwortkategorie ist. Zunächst lassen wir uns mit der describe-Funktion aus dem psych-Paket (Revelle, 2019; s. Abschn. 8.2.2) die deskriptiven Statistiken für das Item ausgeben (hier verkürzt dargestellt). Sowohl der Median als auch der Mittelwert liegen über dem Wert der mittleren Antwortkategorie: > describe(erstis$stim1) vars n mean sd median trimmed mad min max range X1 1 188 3.54 0.87 4 3.59 0 1 5 4
Als nächstes führen wir den Wilcoxon-Test durch. Die Argumente der wilcox.test-Funktion sind identisch mit denen der t.test-Funktion: Als erstes wird die Variable aufgeführt, anschließend der Vergleichswert. In unserem Fall ist der Vergleichswert µ = 3.0: > wilcox.test(erstis$stim1, mu = 3.0) Wilcoxon signed rank test with continuity correction data: erstis$stim1 V = 7456, p-value = 1.645e-12 alternative hypothesis: true location is not equal to 3
Wir erhalten eine Ausgabe mit der empirischen Prüfgröße V und dem p-Wert. Der p-Wert ist deutlich kleiner als .05, daher verwerfen wir die Nullhypothese und nehmen die Alternativhypothese an: Die zentrale Tendenz in unserer Stichprobe weicht signifikant von 3.0 ab.
289
290
17 Nonparametrische Verfahren
17.2.2 Zwei unabhängige Stichproben Wir möchten untersuchen, ob sich Männer und Frauen in ihrer zentralen Tendenz auf der Variablen stim1 unterscheiden. Zunächst lassen wir uns mit der describeBy-Funktion aus dem psych-Paket (Revelle, 2019; s. Abschn. 8.3) die deskriptiven Statistiken für die Variable stim1 getrennt für Frauen und Männer ausgeben (hier verkürzt dargestellt). Der Median ist bei Frauen und Männern gleich. Der Mittelwert der Männer ist etwas höher als der Mittelwert der Frauen: > describeBy(erstis$stim1, erstis$geschl, mat = TRUE) item group1 vars n mean sd median X11 1 weiblich 1 112 3.508929 0.9201991 4 X12 2 männlich 1 55 3.563636 0.7394602 4
Der Befehl für den Wilcoxon-Test für zwei unabhängige Stichproben sieht dem entsprechenden Befehl für den t-Test sehr ähnlich. Auch hier wird eine Modellgleichung eingegeben, bei der die abhängige Variable (d. h., die Variable, für die Unterschiede in der zentralen Tendenz untersucht werden sollen, hier also stim1) vor der Tilde aufgeführt wird und die unabhängige Variable (d. h., die Variable, die die Gruppenzugehörigkeit definiert, hier also geschl) hinter der Tilde aufgeführt wird. Den Data Frame geben wir im Argument data an. > wilcox.test(stim1 ~ geschl, data = erstis) Wilcoxon rank sum test with continuity correction data: stim1 by geschl W = 3123.5, p-value = 0.8722 alternative hypothesis: true location shift is not equal to 0
Wir erhalten eine Ausgabe mit der empirischen Prüfgröße W und dem p-Wert. Der p-Wert ist .8722 und damit größer als .05, daher behalten wir die Nullhypothese bei: Männer und Frauen unterscheiden sich nicht signifikant in ihrer zentralen Tendenz auf der Variablen stim1.
17.2.3 Zwei abhängige Stichproben Wenn die Voraussetzungen für den t-Test für abhängige Stichproben nicht erfüllt sind, kann man ebenfalls auf eine Variante des Wilcoxon-Tests zurückgreifen. Wir möchten untersuchen, ob die zentrale Tendenz der Variablen stim1 (zufrieden) und
17.2
Der Wilcoxon-Test
stim8 (gut) etwa gleich ist. Wir lassen uns zunächst wieder die deskriptiven Statisti-
ken für die beiden Items ausgeben (hier verkürzt dargestellt). Dabei berücksichtigen wir nur Personen, die auf beiden Variablen gültige Werte haben. Der Median liegt bei beiden Variablen bei 4. Der Mittelwert der Variable stim8 ist größer als der Mittelwert der Variable stim1, aber der Unterschied ist nur gering: > describe(na.omit(data.frame(erstis$stim1, erstis$stim8))) vars n mean sd median trimmed mad min max erstis.stim1 1 188 3.54 0.87 4 3.59 0 1 5 erstis.stim8 2 188 3.64 0.78 4 3.68 0 1 5
Der Befehl für den Wilcoxon-Test für zwei abhängige Stichproben sieht dem entsprechenden Befehl für den t-Test wieder sehr ähnlich. Er enthält drei Argumente. Die ersten beiden Argumente sind die Variablen, für die die zentrale Tendenz verglichen werden soll, hier also stim1 und stim8. Das dritte Argument paired = TRUE legt fest, dass es sich um gepaarte Werte bzw. um abhängige Stichproben handelt. > wilcox.test(erstis$stim1, erstis$stim8, paired = TRUE) Wilcoxon signed rank test with continuity correction data: erstis$stim1 and erstis$stim8 V = 839, p-value = 0.03828 alternative hypothesis: true location shift is not equal to 0
Wir erhalten eine Ausgabe mit der empirischen Prüfgröße V und dem p-Wert. Der p-Wert ist .038, daher verwerfen wir die Nullhypothese und nehmen die Alternativhypothese an: Die Variablen stim1 und stim8 unterscheiden sich signifikant in ihrer zentralen Tendenz. Tipp
Die wilcox.test-Funktion lässt sich analog zur t.test-Funktion erweitern. Beispielsweise kann man auch gerichtete Alternativhypothesen prüfen, indem man das Argument alternative ergänzt. Weitere Informationen dazu gibt es unter help(wilcox.test).
291
292
17 Nonparametrische Verfahren
17.3 Der Kruskal-Wallis-Test Der Kruskal-Wallis-Test ist eine nonparametrische Alternative zur einfaktoriellen Varianzanalyse ohne Messwiederholung. Wir möchten nun untersuchen, ob sich die vier Kurse (definiert durch die Variable gruppe) hinsichtlich der Variable stim1 unterscheiden. Zunächst lassen wir uns mit der describeBy-Funktion aus dem psychPaket (Revelle, 2019) die deskriptiven Statistiken für die Gruppen ausgeben (hier verkürzt dargestellt): > describeBy(erstis$stim1, erstis$gruppe, mat = TRUE) item group1 vars n mean sd median X11 1 Kurs 1 1 46 3.673913 0.7617042 4 X12 2 Kurs 2 1 55 3.563636 0.7879565 4 X13 3 Kurs 3 1 40 3.475000 0.8766925 4 X14 4 Kurs 4 1 47 3.425532 1.0579858 4
Alle vier Gruppen haben denselben Median, und auch die Mittelwerte unterscheiden sich kaum. Als nächstes prüfen wir diese Unterschiede inferenzstatistisch mit dem Kruskal-Wallis-Test. Diesen Test rufen wir mit der kruskal.test-Funktion auf: > kruskal.test(stim1 ~ gruppe, data = erstis) Kruskal-Wallis rank sum test data: stim1 by gruppe Kruskal-Wallis chi-squared = 1.5076, df = 3, p-value = 0.6805
Der Kruskal-Wallis-Test gibt eine χ²-verteilte Prüfgröße aus. Die Freiheitsgrade sind die Anzahl der Faktorstufen bzw. die Anzahl der Gruppen minus Eins. Wir erhalten hier ein nicht-signifikantes Ergebnis mit χ²(3) = 1.51, p = .681. Das heißt, wir behalten die Nullhypothese bei: Die vier Kurse unterschieden sich nicht in ihrer Stimmung. Wichtig: Die Alternativhypothese des Kruskal-Wallis-Tests ist identisch mit der Alternativhypothese der einfaktoriellen Varianzanalyse. Ist der Test signifikant, so unterscheidet sich mindestens ein Paar signifikant. Keineswegs kann man daraus jedoch schließen, dass sich alle Gruppen signifikant voneinander unterscheiden.
17.5
Übungen
17.4 Die wichtigsten Funktionen im Überblick Funktion
Beschreibung
chisq.test()
Wendet den χ²-Test auf eine eindimensionale oder zweidimensionale Tabelle an.
wilcox.test(y, mu = a)
Wilcoxon-Test für eine Stichprobe. y ist die abhängige Variable, a ist der Vergleichswert.
wilcox.test(y ~ x)
Wilcoxon-Test für zwei unabhängige Stichproben. y ist die abhängige Variable, x ist die dichotome unabhängige Variable.
wilcox.test(y1, y2, paired = TRUE)
Wilcoxon-Test für zwei abhängige Stichproben. y1 und y2 sind die miteinander zu vergleichenden Variablen.
kruskal.test(y ~ x)
Kruskal-Wallis-Test. y ist die abhängige Variable, x ist die kategoriale unabhängige Variable.
* Funktionen aus zusätzlichen Paketen
17.5 Übungen Diese Übungen beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze). (1) Untersuchen Sie, ob sich Frauen und Männer (geschl) signifikant darin unterscheiden, ob sie die Studienberatung (uni1) in Anspruch genommen haben. (2) Die Items zur Lebenszufriedenheit (lz13 bis lz17) wurden auf einem siebenstufigen Antwortformat beantwortet. Überprüfen Sie, ob beim Item lz13 im Mittel die mittlere Antwortkategorie mit der Ausprägung 4 angekreuzt wurde. (3) Unterscheiden sich Personen mit Kindern und Personen ohne Kinder (kinder) in Bezug auf das Item lz17? (4) Unterscheiden sich die Antworten auf das Item lz13 von den Antworten auf das Item lz17? Beantworten Sie diese Frage mithilfe eines Wilcoxon-Tests für abhängige Stichproben. (5) Prüfen Sie, ob der Wohnort vor zwölf Monaten (wohnort.alt) einen Effekt auf die Antworten auf das Item lz14 hat.
Powered by TCPDF (www.tcpdf.org)
293
294
18 Verfahren für die Testkonstruktion
18
Verfahren für die Testkonstruktion
Kein psychologischer Test ist von Anfang an perfekt, sondern meist das Ergebnis eines langen Revisionsprozesses. In diesem Prozess wird der vorläufige Test mehrmals von Personen bearbeitet. Die so erhobenen Daten verwendet man, um den Test zu überarbeiten. In diesem Kapitel besprechen wir zwei statistische Verfahren, die bei der Testkonstruktion häufig zum Einsatz kommen. Mit der exploratorischen Faktorenanalyse untersuchen wir die faktorielle Struktur einer Skala, d. h., wir prüfen, ob sich die Items auf mehrere Subskalen verteilen lassen (Abschn. 18.1). Mit der Itemanalyse untersuchen wir die Verteilung der einzelnen Items sowie deren psychometrischen Beitrag zur Skala (Abschn. 18.2). In diesem Abschnitt gehen wir auch darauf ein, wie man die interne Konsistenz einer Skala bestimmen kann. Die Beispiele in diesem Kapitel beziehen sich auf den Datensatz bigfive.items.RData (s. Anhang A: Datensätze). Tipp
Wir besprechen in diesem Kapitel überwiegend Verfahren, die im Rahmen der Klassischen Testtheorie entwickelt wurden. Verfahren der probabilistischen Testtheorie sind in R ebenfalls verfügbar (s. Anhang B: Pakete).
18.1 Exploratorische Faktorenanalyse Vor der Durchführung einer exploratorischen Faktorenanalyse sollten wir zunächst die Zusammenhänge zwischen den Items deskriptiv analysieren und die Anzahl der zu extrahierenden Faktoren bestimmen. Anschließend führen wir die eigentliche Faktorenanalyse durch. In unserem Beispiel untersuchen wir eine Skala zur Messung der Big-Five-Persönlichkeitseigenschaften.
18.1.1 Deskriptive Analysen und Bartlett-Test Eine Faktorenanalyse kann nur dann ein sinnvolles Ergebnis liefern, wenn die Items zumindest teilweise miteinander korreliert sind. Um diese Voraussetzung zu prüfen, sollten wir zunächst deskriptiv untersuchen, wie die Items zusammenhängen. Am besten machen wir das mit einer Streudiagramm-Matrix, in der für jede Kombination
18.1
Exploratorische Faktorenanalyse
von Items ein eigenes Streudiagramm erzeugt wird. In so einer Streudiagramm-Matrix kann man sich nicht nur einen ersten Eindruck von der Stärke des Zusammenhangs zwischen den Variablen verschaffen, man kann auch prüfen, ob es Hinweise auf nicht-lineare Zusammenhänge gibt oder ob es Ausreißer gibt. Eine geeignete Funktion für die Erstellung von Streudiagramm-Matrizen ist die pairs.panelsFunktion aus dem psych-Paket (Revelle, 2019; s. Abschn. 10.3.6). Wenn die Verteilung der Datenpunkte weniger von Interesse hat, kann man die Stärke der Korrelationskoeffizienten einer Korrelationsmatrix in einem sog. Korrelogramm grafisch darstellen. Im psych-Paket steht dafür die cor.plot-Funktion zur Verfügung. Wir wenden sie hier auf den vollständigen Data Frame an: > cor.plot(bigfive.items)
Das damit erzeugte Diagramm ist in Abbildung 18.1 dargestellt. Weitere Varianten bieten die Pakete corrgram (das auf den klassischen Grafik-Funktionen aufbaut; Wright, 2018) und ggcorrplot (das auf ggplot2 aufbaut; Kassambara, 2019). Zusätzlich zur rein deskriptiven Betrachtung der Korrelationen können wir mit dem Bartlett-Test prüfen, ob die Korrelationsmatrix faktorisierbar ist, ob also genügend substantielle Korrelationen zwischen den Items vorliegen, dass diese mit Faktoren erklärt werden könnten. Im psych-Paket ist der Bartlett-Test in der Funktion cortest.bartlett enthalten: > cortest.bartlett(bigfive.items) R was not square, finding R from data $chisq [1] 3516.047 $p.value [1] 0 $df [1] 190
Der Barlett-Test prüft die Nullhypothese, dass alle Korrelationen in einer Korrelationsmatrix gleich Null sind. Hier würde ein signifikantes Ergebnis mit p < .05 darauf hindeuten, dass eine Faktorenanalyse durchgeführt werden kann.
295
296
18 Verfahren für die Testkonstruktion
Correlation plot 1
bf01 bf02 bf03 bf04
0.8
bf05
0.6
bf06 0.4
bf07 bf08
0.2
bf09 bf10
0
bf11 bf12 bf13 bf14 bf15 bf16 bf17 bf18 bf19 bf20 bf01
bf03
bf05
bf07
bf09
bf11
bf13
bf15
bf17
bf19
Abbildung 18.1 Korrelogramm für die Big-Five-Items, erstellt mit der cor.plot-Funktion aus dem psych-Paket. Je dunkler die Felder, desto stärker ist der Zusammenhang zwischen zwei Variablen. In RStudio werden positive Korrelationen in blau und negative Korrelationen in rot dargestellt.
18.1.2 Bestimmung der Anzahl der Faktoren Es gibt eine Reihe von Verfahren, mit denen man die optimale Zahl der Faktoren bestimmen kann. Traditionelle Ansätze wie das Kaiser-Kriterium (d. h., alle Faktoren mit einem Eigenwert > 1 werden extrahiert) oder der Scree-Test (d. h., Interpretation des Eigenwertverlaufs) haben sich nicht bewährt (Goretzko et al., 2019; Fabrigar et al., 1999). Wir besprechen hier einige bessere Verfahren, die alle im psych-Paket (Revelle, 2019) implementiert sind.
18.1
Exploratorische Faktorenanalyse
Parallelanalyse Bei der Parallelanalyse werden die beobachteten Eigenwerte mit den Eigenwerten verglichen, die wir bei einer Faktorenanalyse mit Zufallsdaten erwarten würden. Wir möchten, dass unsere Faktoren höhere Eigenwerte aufweisen, als man unter der Zufallsbedingung erwarten würde. Wir extrahieren daher nur die Faktoren, deren Eigenwerte größer sind als die zufälligen Eigenwerte. Zur Durchführung der Parallelanalyse wenden wir die fa.parallel-Funktion aus dem psych-Paket auf den Data Frame an. > fa.parallel(bigfive.items) Parallel analysis suggests that the number of factors = and the number of components = 5
5
In dieser Funktion werden die Zufallsdaten auf zwei verschiedene Arten erzeugt: durch Simulation sowie durch Resampling. Außerdem werden die Eigenwerte sowohl mit einer Hauptachsenanalyse als auch mit einer Hauptkomponentenanalyse geschätzt. In der Ausgabe der Funktion wird das Ergebnis zusammengefasst. In unserem Datenbeispiel kommt die Parallelanalayse auf fünf Faktoren und auf fünf Komponenten. Wir müssen uns aber nicht auf diesen Antwortsatz verlassen, sondern können den Eigenwertverlauf auch selbst überprüfen. Dazu betrachten wir das Diagramm, das ebenfalls mit dieser Funktion erzeugt wird (s. Abb. 18.2). In diesem Diagramm sind die beobachteten Eigenwertverläufe für die Hauptachsenanalyse (FA Actual Data) und die Hauptkomponentenanalyse (PC Actual Data) in durchgezogenen Linien dargestellt. Für beide Verfahren werden zudem die Eigenwertverläufe der Zufallsdaten in gepunkteten Linien dargestellt. Wir suchen nun jeweils die Stelle, an der die durchgezogene Linie unter die gepunktete Linie tritt. Bei beiden Verfahren ist dies zwischen den Faktoren 5 und 6 der Fall. Beurteilung der Modellgüte und weitere Kriterien Ein weiteres Verfahren zur Bestimmung der Anzahl der Faktoren besteht darin, die Modellgüte verschiedener Faktorenlösungen zu vergleichen. Für die Beurteilung der Modellgüte stehen verschiedene Kennwerte zur Verfügung, z. B. χ²-Test, der Root Mean Square Error of Approximation (RMSEA) oder das Bayesian Information Criterion (BIC). Die VSS-Funktion aus dem psych-Paket gibt diese und andere Gütekriterien für verschiedene Faktorenlösungen aus. Wir gehen hier aus Platzgründen nicht alle Kennwerte einzeln durch, daher empfehle ich dazu die sehr ausführliche Hilfe-Datei zu dieser Funktion.
297
298
18 Verfahren für die Testkonstruktion
Abbildung 18.2 Parallelanalyse für die Big-Five-Items
Für unser Datenbeispiel erhalten wir auf das folgende Ergebnis: > VSS(bigfive.items) Very Simple Structure Call: vss(x = x, n = n, rotate = rotate, diagonal = diagonal, fm = fm, n.obs = n.obs, plot = plot, title = title, use = use, cor = cor) VSS complexity 1 achieves a maximimum of 0.73 6 factors VSS complexity 2 achieves a maximimum of 0.83 5 factors
with with
The Velicer MAP achieves a minimum of 0.03 with 5 factors BIC achieves a minimum of -378.25 with 6 factors Sample Size adjusted BIC achieves a minimum of -119.26 with 7 factors Statistics by number of factors vss1 vss2 map dof chisq prob sqresid fit 1 0.37 0.00 0.044 170 2626 0.0e+00 24.3 0.37 2 0.48 0.53 0.045 151 1921 3.8e-304 18.3 0.53 3 0.56 0.64 0.044 133 1330 1.9e-196 13.1 0.66 4 0.66 0.76 0.039 116 831 1.9e-108 8.5 0.78
18.1 5 6 7 8
0.73 0.73 0.69 0.71
1 2 3 4 5 6 7 8
RMSEA 0.173 0.156 0.137 0.113 0.060 0.039 0.026 0.027
0.83 0.82 0.83 0.83
0.026 100 0.027 85 0.034 71 0.042 58
273 147 94 78
6.4e-18 3.9e-05 3.7e-02 3.9e-02
Exploratorische Faktorenanalyse 5.4 4.6 4.3 3.8
0.86 0.88 0.89 0.90
BIC SABIC complex eChisq SRMR eCRMS eBIC 1577 2116 1.0 4703 0.161 0.170 3653 989 1468 1.2 3154 0.131 0.148 2222 509 931 1.4 1884 0.102 0.121 1063 115 483 1.3 851 0.068 0.087 135 -345 -27 1.2 149 0.029 0.039 -468 -378 -108 1.3 56 0.017 0.026 -469 -345 -119 1.4 35 0.014 0.023 -403 -280 -96 1.5 27 0.012 0.022 -331
Tipp
Um zu untersuchen, wie sich die Faktorenstruktur durch die Hinzunahme weiterer Faktoren verändert, kann man die Bass-Ackwards-Methode anwenden (Goldberg, 2006). Damit erhält man ein Diagramm, in dem die Aufteilung der Faktoren über verschiedene Faktorenlösungen hinweg dargestellt wird. Diese Methode ist im psych-Paket in der bassAckward-Funktion verfügbar.
18.1.3 Durchführung der Faktorenanalyse Nachdem wir die Anzahl der zu extrahierenden Faktoren festgelegt haben, führen wir die eigentliche Faktorenanalyse durch. Aber auch hier müssen wir noch einige Entscheidungen treffen: Wahl der Extraktionsmethode. Zur Verfügung stehen u. a. die Maximum-Likelihood-Faktorenanalyse und die Hauptachsenanalyse (zur Unterscheidung und Bewertung dieser Verfahren s. Eid et al., 2017). Wahl der Rotationsmethode. Bei der Rotationsmethode unterscheidet man zwischen orthogonaler Rotation (die Faktoren dürfen nicht korrelieren) und obliquer Rotation (die Faktoren dürfen korrelieren). Das gängigste orthogonale Rotationsverfahren ist die Varimax-Rotation. Eine häufig eingesetzte oblique Rotationsmethode ist die Promax-Methode. Im folgenden Beispiel führen wir eine Maximum-Likelihood-Faktorenanalyse mit Promax-Rotation für die 20 Big-Five-Items durch, die im Objekt bigfive.items zusammengefasst sind. Wir verwenden dazu die fa-Funktion aus dem psych-Paket (Revelle, 2019). Das Ergebnis wird in einem Objekt mit dem Namen fa.ml gespeichert.
299
300
18 Verfahren für die Testkonstruktion
> fa.ml print(fa.ml, digits = 2, cut = .3, sort = TRUE)
In diesem Befehl legen wir fest, dass alle Werte auf zwei Nachkommastellen gerundet werden sollen (digits-Argument), dass nur Faktorladungen größer als 0.30 angezeigt werden sollen (cut-Argument) und dass die Tabelle mit den Faktorladungen (die sog. Mustermatrix, englisch pattern matrix) innerhalb der Faktoren nach Höhe der Faktorladungen sortiert sein soll (sort-Argument). Die erste Tabelle in der Ausgabe enthält die Faktorladungen der einzelnen Variablen auf den Faktoren (ML1 bis ML5). Ideal ist, wenn die Variablen möglichst hoch
18.1
Exploratorische Faktorenanalyse
auf einem und möglichst niedrig auf allen anderen Faktoren laden, sodass keine bedeutsamen Nebenladungen vorhanden sind. Ein solches Muster nennt man Einfachstruktur. In unserem Beispiel liegt eine solche Einfachstruktur vor. Standardized loadings (pattern matrix) based matrix item ML2 ML1 ML5 ML3 ML4 h2 bf07 7 0.91 0.79 bf03 3 0.86 0.75 bf20 20 0.73 0.53 bf11 11 0.52 0.34 bf09 9 0.95 0.83 bf05 5 0.90 0.77 bf18 18 0.50 0.33 bf14 14 0.47 0.27 bf08 8 0.72 0.52 bf15 15 0.70 0.44 bf17 17 0.67 0.50 bf02 2 0.61 0.47 bf13 13 0.84 0.66 bf16 16 0.72 0.50 bf01 1 0.62 0.41 bf06 6 0.55 0.40 bf04 4 0.77 0.63 bf10 10 0.75 0.58 bf12 12 0.52 0.34 bf19 19 0.52 0.29
upon correlation u2 0.21 0.25 0.47 0.66 0.17 0.23 0.67 0.73 0.48 0.56 0.50 0.53 0.34 0.50 0.59 0.60 0.37 0.42 0.66 0.71
com 1.0 1.0 1.0 1.3 1.1 1.1 1.2 1.1 1.1 1.1 1.1 1.2 1.1 1.1 1.0 1.4 1.2 1.1 1.6 1.1
Darüber hinaus sind in dieser Tabelle für jedes Item die Kommunalität (h2), der Uniqueness-Wert (u2) sowie die Komplexität (com) angegeben. Die Kommunalität h² drückt aus, wie viel Prozent der Varianz dieses Items durch alle fünf Faktoren erklärt wird. Die Uniqueness eines Items ist mit 1 – h² definiert. Die Uniqueness ist daher der Anteil der Varianz des Items, der nicht durch die Faktoren erklärt wird. Je höher der Uniqueness-Wert, desto weniger hat das Item mit den anderen Items gemeinsam. Der Komplexitätswert gibt an, wie viele latente Faktoren notwendig sind, um die Varianz dieses Items zu erklären. Idealerweise haben alle Items einen KomplexitätsWert nahe 1, denn dies entspricht einer Einfachstruktur (d. h., die Items haben hohe Ladungen auf genau einem einzigen Faktor und niedrige Ladungen auf allen anderen Faktoren). Der Komplexitätswert hilft zudem dabei, potenziell problematische Items zu identifizieren.
301
302
18 Verfahren für die Testkonstruktion
Die nächste Tabelle enthält die quadrierten und aufsummierten Ladungen der einzelnen Faktoren (SS loadings) sowie Angaben, wie viel Prozent der Gesamtvarianz durch die einzelnen Faktoren erklärt wird. Die Zeile Proportion Var gibt den Anteil der Varianz dieses Faktors an der Gesamtvarianz wieder. In der Zeile Cumulative Var werden diese Werte addiert. Hier kann man erkennen, dass die fünf Faktoren zusammen 52 % der Gesamtvarianz aufklären. Dieser 52 % der Gesamtvarianz sind die Basis für die folgenden zwei Zeilen. In der Zeile Proportion Explained steht, wie viel jeder Faktor zur erklärten Varianz beiträgt. In der Zeile Cumulative Proportion werden diese Werte wiederum aufaddiert.
SS loadings Proportion Var Cumulative Var Proportion Explained Cumulative Proportion
ML2 2.40 0.12 0.12 0.23 0.23
ML1 2.15 0.11 0.23 0.21 0.44
ML5 2.05 0.10 0.33 0.20 0.64
ML3 2.02 0.10 0.43 0.19 0.83
ML4 1.75 0.09 0.52 0.17 1.00
Da wir eine Promax-Rotation durchgeführt haben, können die Faktoren korreliert sein. Die folgende Tabelle enthält die Korrelationen der Faktoren. With factor correlations of ML2 ML1 ML5 ML3 ML4 ML2 1.00 0.24 0.27 0.09 0.03 ML1 0.24 1.00 0.15 0.27 -0.08 ML5 0.27 0.15 1.00 0.31 -0.03 ML3 0.09 0.27 0.31 1.00 0.00 ML4 0.03 -0.08 -0.03 0.00 1.00
Anschließend werden eine Reihe von Kennwerten ausgegeben, mit denen die Modellgüte beurteilt werden kann, bspw. der RMSEA und der χ²-Test für das Modell (zur Interpretation s. ?fa.stats). With factor correlations of ML2 ML1 ML5 ML3 ML4 ML2 1.00 0.24 0.27 0.09 0.03 ML1 0.24 1.00 0.15 0.27 -0.08 ML5 0.27 0.15 1.00 0.31 -0.03 ML3 0.09 0.27 0.31 1.00 0.00 ML4 0.03 -0.08 Mean item complexity = 1.1 Test of the hypothesis that 5 factors are sufficient. The degrees of freedom for the null model are 190 and the
18.1
Exploratorische Faktorenanalyse
objective function was 7.46 with Chi Square of 3516.05 The degrees of freedom for the model are 100 and the objective function was 0.54 The root mean square of the residuals (RMSR) is 0.03 The df corrected root mean square of the residuals is 0.04 The harmonic number of observations is 480 with the empirical chi square 167.03 with prob < 3e-05 The total number of observations was 480 with Likelihood Chi Square = 252.59 with prob < 3.5e-15 Tucker Lewis Index of factoring reliability = 0.912 RMSEA index = 0.056 and the 90 % confidence intervals are 0.048 0.065 BIC = -364.79 Fit based upon off diagonal values = 0.98
Am Ende der Ausgabe erhalten wir eine Tabelle zu den Faktorwerten. In den Zeilen wird für jeden Faktor die multiple Korrelation zwischen den Faktorwerten einerseits und den Item-Rohwerten andererseits berichtet. In der zweiten Zeile stehen die jeweiligen Determinationskoeffizienten, die sich aus dem Quadrat der multiplen Korrelationen in der ersten Zeile berechnen. Die Determinationskoeffizienten drücken den Anteil der Varianz in den Faktorwerten aus, der durch die Item-Rohwerte erklärt werden. Die dritte Zeile gibt die minimale Korrelation zwischen alternativen Faktorwerten wieder. Im schlimmsten Fall können zwei auf unterschiedliche Weisen berechnete Faktorwerte gar nicht oder negativ korreliert sein. In unserem Beispiel erhalten wir für alle Faktoren hohe Werte, daher können die Faktorwerte – so wir sie denn berechnen – gut interpretiert werden. Measures of factor score adequacy Correlation of (regression) scores with factors Multiple R square of scores with factors Minimum correlation of possible factor scores
Correlation of (regression) scores with factors Multiple R square of scores with factors Minimum correlation of possible factor scores
ML2 ML1 ML5 0.95 0.95 0.90 0.89 0.90 0.80 0.79 0.80 0.61 ML3 ML4 0.91 0.89 0.82 0.79 0.64 0.58
303
304
18 Verfahren für die Testkonstruktion
18.1.4 Alternativen zur exploratorischen Faktorenanalyse Die hier dargestellte Form der exploratorischen Faktorenanalyse ist nur eine von vielen Methoden, mit denen man die Struktur einer psychologischen Skala untersuchen kann, und nicht immer die angemessenste. Wir gehen hier kurz auf Varianten und Alternativen zur exploratorischen Faktorenanalyse ein. Komplexe Faktorstrukturen Bei der Testkonstruktion wird meistens eine Einfachstruktur angestrebt, bei der die einzelnen Items jeweils auf einem Faktor hoch laden und auf allen anderen Faktoren niedrig. Diese einfache Faktorenstruktur ist jedoch nicht immer passend. Bei der hierarchischen exploratorischen Faktorenanalyse wird angenommen, dass es Faktoren höherer Ordnung gibt, die die Korrelationen der Faktoren untereinander erklären. Bei der Bifaktor-Faktorenanalyse wird angenommen, dass es einen Generalfaktor gibt, auf den alle Faktoren laden sowie weitere Faktoren, die die Beziehungen der Items erklären, die nicht auf den Generalfaktor zurückzuführen sind. Sowohl die hierarchische exploratorische Faktorenanalyse als auch die exploratorische BifaktorAnalyse können mit der omega-Funktion aus dem psych-Paket (Revelle, 2019) durchgeführt werden. Konfirmatorische Faktorenanalyse Wenn man bereits eine genaue Vorstellung von der Faktorenstruktur einer Skala hat, sollte man statt der exploratorischen eine konfirmatorische Faktorenanalyse durchführen. Dieses Verfahren wird in Abschnitt 19.3 behandelt. Hauptkomponentenanalyse Die Hauptkomponentenanalyse wird manchmal zu den faktorenanalytischen Verfahren gezählt, allerdings unterscheidet sie sich von der explorativen Faktorenanalyse in einem wichtigen Punkt: In der Hauptkomponentenanalyse wird versucht, die gesamte Varianz mit den Komponenten zu erklären, während die Verfahren der exploratorischen Faktorenanalyse die beobachteten Korrelationen zwischen den Variablen auf latente Faktoren zurückführen – dies impliziert, dass nicht die gesamte Varianz erklärt wird. In R kann die Hauptkomponentenanalyse u. a. mit der principalFunktion aus dem psych-Paket (Revelle, 2019) durchgeführt werden.
18.2 Itemanalyse und interne Konsistenz Das Ziel eines psychologischen Tests ist immer, Unterschiede zwischen Personen hinsichtlich bestimmter Konstrukte aufzudecken. Um sicherzustellen, dass man die
18.2
Itemanalyse und interne Konsistenz
Unterschiede zwischen den Personen möglichst gut im Test abbilden kann, muss man bei der Auswahl der Items ansetzen. Die Güte eines Items kann anhand verschiedener Kriterien beurteilt werden: Beitrag zur internen Konsistenz. Das Item sollte die interne Konsistenz der Skala verbessern. Schwierigkeit. Das Item sollte weder zu leicht (nur positive Antworten) noch zu schwer (nur negative Antworten) sein, sondern eine mittlere Schwierigkeit haben. Allerdings ist es häufig auch wünschenswert, Items mit verschiedenen Schwierigkeiten in einer Skala zu behalten, sodass das Konstrukt in seiner Breite gemessen werden kann. Trennschärfe. Das Item sollte die Skala möglichst gut repräsentieren. Verteilungsform. Die Häufigkeitsverteilung der Antworten sollte möglichst symmetrisch sein. Diese Kriterien werden im Rahmen einer Itemanalyse geprüft. Bei mehrdimensionalen Skalen sollte man die Itemanalyse immer getrennt für jede Subskala durchführen. Wir führen nun eine Itemanalyse für die Items durch, die die Big-Five-Subskala Gewissenhaftigkeit messen sollen. Bevor wir loslegen, speichern wir zunächst die dazugehörigen Items in einem neuen Objekt mit dem Namen gewiss ab. Dazu verwenden wir die select-Funktion aus dem dplyr-Paket (Wickham et al., 2020; s. Abschn. 7.3.1). > gewiss alpha(gewiss)
Die Ausgabe beginnt mit Maßen der internen Konsistenz. Die erste Spalte (raw_alpha) enthält das klassische Cronbach’s α. Die Berechnung dieses Maßes der internen
Konsistenz beruht auf den beobachteten Kovarianzen der Items. Für das standardisierte α (std.alpha) werden dagegen die Korrelationen herangezogen. Bei G6 (smc) handelt es sich um Guttman’s Lambda, ein alternativer Schätzer der Reliabilität einer Skala. Die Spalte average_r enthält die durchschnittliche Interkorrelation der Items. Ein weiteres Maß für die Qualität einer Skala ist das Signal-NoiseRatio (S/N). Unter ase ist der Standardfehler für Cronbach’s α aufgeführt. Dieser Standardfehler wird auch verwendet, um das Konfidenzintervall für α zu berechnen (folgende Zeile). Die folgenden Spalten geben den Skalenmittelwert (mean) sowie die
305
306
18 Verfahren für die Testkonstruktion
Standardabweichung (sd) wieder. Die Spalte median_r enthält den Median der Interkorrelationen der Items. Die Hilfe-Datei zur alpha-Funktion enthält detaillierte Informationen zur Berechnung und Interpretation dieser verschiedenen Maße. Reliability analysis Call: alpha(x = gewiss) raw_alpha std.alpha G6(smc) average_r S/N ase mean sd 0.84 0.84 0.81 0.56 5.2 0.012 3.5 0.83 median_r 0.55 lower alpha upper 0.82 0.84 0.86
95% confidence boundaries
Der Beitrag zur internen Konsistenz der einzelnen Items kann der folgenden Tabelle entnommen werden. In der Spalte raw_alpha erfährt man die interne Konsistenz der Skala, wenn diese das betreffende Item nicht enthält. Je kleiner dieser Wert im Vergleich zur internen Konsistenz für die Gesamtskala, desto größer ist der Beitrag dieses Items zur internen Konsistenz. In den folgenden Spalten werden auch für die anderen oben eingeführten Reliabilitäts-Maßen die Werte angegeben, die man ohne das jeweilige Item erhalten würde. Reliability if an item is dropped: raw_alpha std.alpha G6(smc) average_r bf03 0.76 0.75 0.69 0.51 bf07 0.75 0.75 0.68 0.50 bf11 0.86 0.86 0.82 0.67 bf20 0.80 0.80 0.76 0.57
bf03 bf07 bf11 bf20
S/N alpha se 3.1 0.019 3.1 0.019 6.2 0.011 3.9 0.016
var.r 0.0168 0.0091 0.0064 0.0295
med.r 0.45 0.49 0.65 0.49
Die nächste Tabelle beginnt mit der Anzahl gültiger Werte für jedes Item (n). Es folgen vier Korrelationen. Die Spalten raw.r und std.r enthalten die Korrelationen der Items mit der Gesamtskala, wobei raw.r aus den Rohwerten und std.r aus der Korrelationsmatrix berechnet wurde. Auch die Korrelationen r.cor und r.drop geben die Korrelationen der Items mit der Gesamtskala wieder, hier wurden allerdings
18.2
Itemanalyse und interne Konsistenz
verschiedene Korrekturen durchgeführt. Bei r.cor wurde die Itemreliabilität sowie die Tatsache, dass das Item Teil der Gesamtskala ist, berücksichtigt. Bei r.drop wurde das Item selbst nicht in die Gesamtskala aufgenommen; dies ist also die Korrelation des Items mit der Gesamtskala ohne dieses Item (Trennschärfe). Item statistics n raw.r std.r r.cor r.drop mean sd bf03 480 0.88 0.87 0.84 0.76 3.4 1.0 bf07 480 0.88 0.87 0.85 0.77 3.3 1.1 bf11 480 0.70 0.72 0.55 0.51 4.0 0.9 bf20 480 0.82 0.82 0.72 0.67 3.2 1.0
Die Tabelle enthält außerdem die Mittelwerte und Standardabweichungen der einzelnen Items. Die Mittelwerte können als Indikator der Schwierigkeit der Items herangezogen werden. Je höher der Mittelwert eines Items ist, desto »leichter« ist es, diesem Item zuzustimmen. Die letzte Tabelle in dieser Ausgabe enthält die relativen Häufigkeiten der einzelnen Antwortkategorien für jedes Item. Diese Tabelle kann verwendet werden, um die Verteilungsform der Items zu bestimmen. Die Interpretation ist etwas einfacher, wenn man die relativen Häufigkeiten in einem Säulendiagramm darstellt (s. Abschn. 10.1). Damit kann man schnell erkennen, ob extreme Abweichungen von der angestrebten Symmetrie vorliegen. Auch die Inspektion der deskriptiven Statistiken (z. B. Schiefe und Kurtosis) für das Item kann hilfreich sein, z. B. mit der describe-Funktion aus dem psych-Paket (s. Abschn. 8.2.2). Non missing response frequency for each item 1 2 3 4 5 miss bf03 0.03 0.16 0.35 0.32 0.14 0 bf07 0.05 0.19 0.33 0.30 0.12 0 bf11 0.01 0.05 0.19 0.40 0.35 0 bf20 0.04 0.21 0.32 0.32 0.10 0
Tipp
Die interne Konsistenz einer Skala wird zunehmend auch über den sog. ω-Koeffizienten geschätzt. Dieser Koeffizient ist u. a. in der omega-Funktion aus dem psych-Paket (Revelle, 2019) enthalten.
307
308
18 Verfahren für die Testkonstruktion
18.3 Die wichtigsten Funktionen im Überblick Funktion
Beschreibung
fa.parallel()*
Führt eine Parallelanalyse durch. Das Ergebnis wird grafisch dargestellt. Funktion aus dem psych-Paket.
VSS()*
Gibt verschiedene Kennwerte zur Bestimmung der Anzahl der Faktoren in einer exploratorischen Faktorenanalyse aus. Funktion aus dem psych-Paket.
fa()*
Führt eine Faktorenanalyse durch. Funktion aus dem psych-Paket.
alpha()*
Bestimmt verschiedene Kennwerte der internen Konsistenz und führt eine Itemanalyse durch. Funktion aus dem psych-Paket.
* Funktionen aus zusätzlichen Paketen
18.4 Übungen Diese Übungen beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze). (1) Führen Sie eine Itemanalyse für die Lebenszufriedenheits-Items (lz13 bis lz17) durch. Auf welches der fünf Items könnte man am ehesten verzichten? (2) Untersuchen Sie die faktorielle Struktur der Stimmungs-Items (stim1 bis stim12). Fassen Sie zunächst diese Items in einem neuen Data Frame zusammen, der keine fehlenden Werte enthält. Bestimmen Sie anschließend die Anzahl der zu extrahierenden Faktoren mit einer Parallelanalyse und führen Sie dann eine exploratorische Faktorenanalyse mit Maximum-Likelihood-Schätzung und obliquer Rotation durch.
Powered by TCPDF (www.tcpdf.org)
19.1
19
Multiple Regression mit lavaan
Lineare Strukturgleichungsmodelle
Der Begriff Strukturgleichungsmodell umfasst eine ganze Familie von Modellen, mit denen die Beziehungen zwischen mehreren unabhängigen und abhängigen Variablen gleichzeitig analysiert werden können. Im Gegensatz zur Regressionsanalyse können mehrere abhängige Variablen gleichzeitig berücksichtigt werden. Zudem können Variablen gleichzeitig als abhängige und unabhängige Variablen dienen, z. B. als vermittelnde Variablen in einem Mediationsmodell. Darüber hinaus können die Variablen entweder direkt beobachtet sein (manifeste Variablen) oder indirekt über mehrere Indikatoren (z. B. einzelne Items) gemessen werden (latente Variablen). Alle Modelle werden mit dem Paket lavaan (Rossell, 2012) geschätzt. Um dieses Paket kennenzulernen, schauen wir uns zunächst an, wie ein normales Regressionsmodell mit lavaan geschätzt wird (Abschn. 19.1). Anschließend besprechen wir drei Strukturgleichungsmodelle: ein Pfadmodell mit einer Mediatorvariablen (Abschn. 19.2), ein konfirmatorisches Faktorenmodell (Abschn. 19.3) sowie ein lineares Strukturgleichungsmodell mit mehreren latenten Variablen (Abschn. 19.4). Die Beispiele in diesem Kapitel beziehen sich auf den Datensatz erstis.RData (s. Anhang A: Datensätze).
19.1 Multiple Regression mit lavaan In lavaan werden Modelle immer in drei Schritten geschätzt: (1) Modellspezifikation, (2) Modellschätzung, (3) Ausgabe anfordern. Wir analysieren jetzt ein Regressionsmodell mit der Lebenszufriedenheit (lz.1) als abhängige Variable und Extraversion (extra) und Neurotizismus (neuro) als unabhängige Variablen. Als erstes spezifizieren wir das Modell, d. h., wir legen die Modellgleichung fest. Die Modellgleichung wird in der gleichen Formelschreibweise wie bei der Regressionsanalyse angegeben (s. Kap. 15), d. h., die abhängige Variable steht links von der Tilde (~) und die unabhängigen Variablen stehen rechts von der Tilde und werden mit einem Pluszeichen verknüpft. Diese Modellgleichung wird in einfache Anführungszeichen gesetzt und in einem neuen Objekt gespeichert: > reg.txt reg.fit summary(reg.fit) lavaan 0.6-5 ended normally after 22 iterations Estimator Optimization method Number of free parameters
ML NLMINB 3 Used 187
Number of observations
Total 191
Model Test User Model: Test statistic Degrees of freedom
0.000 0
Parameter Estimates: Information Information saturated (h1) model Standard errors
Expected Structured Standard
Regressions: lz.1 ~ neuro extra
Estimate
Std.Err
z-value
P(>|z|)
-1.920 1.796
0.523 0.605
-3.670 2.967
0.000 0.003
Estimate 28.419
Std.Err 2.939
z-value 9.670
P(>|z|) 0.000
Variances: .lz.1
19.2
Pfadmodell mit Mediatorvariable
Die einzelnen Teile dieser Ausgabe werden wir im Detail in den folgenden Abschnitten besprechen. Für uns ist hier vor allem die Tabelle mit der Überschrift Regressions interessant. Hier erhalten wir die unstandardisierten Regressionskoeffizienten für die beiden unabhängigen Variablen sowie deren Standardfehler, z-Werte und p-Werte. Tipp
Standardisierte Regressionskoeffizienten erhält man, indem man in der summaryFunktion das Argument standardized = TRUE ergänzt. Mit dem Argument rsquare = TRUE kann man außerdem den Determinationskoeffizienten R² anfordern.
19.2 Pfadmodell mit Mediatorvariable Wenn ein Strukturgleichungsmodell nur manifeste Variablen enthält, spricht man auch von einem Pfadmodell. Pfadmodelle sind erweiterte Regressionsmodelle, die mehrere abhängige Variablen sowie Mediatorvariablen enthalten können. Wir analysieren jetzt ein recht einfaches Pfadmodell mit einer unabhängigen Variablen, einer abhängigen Variablen sowie einer Mediatorvariablen (s. Abb. 19.1). In diesem Beispiel untersuchen wir, ob der Zusammenhang zwischen Gewissenhaftigkeit (gewiss, unabhängige Variable) und Lebenszufriedenheit (lz.1, abhängige Variable) durch aufschiebendes Verhalten bzw. Prokrastination (prok, Mediatorvariable) vermittelt wird.
Prokrastination a
Gewissenhaftigkeit
b
c’
Lebenszufriedenheit
Abbildung 19.1 Pfaddiagramm eines einfachen Mediationsmodells
311
312
19 Lineare Strukturgleichungsmodelle
Wie man im Pfaddiagramm sehen kann, enthält dieses Modell zwei abhängige Variablen, d. h., es gibt zwei Variablen, auf die Pfeile zeigen: Prokrastination und Lebenszufriedenheit. Für jede dieser abhängigen Variablen muss in der Modellspezifikation eine eigene Gleichung angelegt werden: > med1.txt med1.fit summary(med1.fit)
Wir erhalten zunächst einige Informationen zur Modellschätzung. Unser Modell enthält fünf freie Parameter, deren Werte mit der Maximum Likelihood-Methode geschätzt wurden (Estimator: ML). Dafür wurden 26 Iterationen benötigt. Wir erfahren außerdem, dass unsere Daten 191 Fälle (observations) enthielten, von denen aber nur 173 für die Schätzung berücksichtigt wurden, weil nur diese Fälle gültige Werte auf allen drei Variablen hatten. Unter Model Test User Model erhalten wir das Ergebnis des χ2-Anpassungstests. Bei überidentifizierten Modellen ist dieser Test ein Indikator der Modellgüte. Unser Modell ist jedoch genau identifiziert, daher kann dieser Test hier noch nicht durchgeführt werden. lavaan 0.6-5 ended normally after 26 iterations Estimator Optimization method Number of free parameters
Number of observations
ML NLMINB 5 Used 173
Total 191
Model Test User Model: Test statistic Degrees of freedom
0.000 0
19.2
Pfadmodell mit Mediatorvariable
Im nächsten Teil der Ausgabe geht es um die geschätzten Parameter. Unter Parameter Estimates erhalten wir einige technische Informationen dazu, wie diese Parameterschätzungen genau ermittelt wurden (für Details s. Hilfe-Datei zu dieser Funktion). Die Tabelle Regressions enthält die Pfadkoeffizienten (Estimate) sowie deren Standardfehler (Std.Err), statistische Prüfgrößen (z-value) und p-Werte (P(>|z|)). Die Tabelle Variances enthält die Residualvarianzen der beiden abhängigen Variablen mit Standardfehlern, statistischen Prüfgrößen und p-Werten. Parameter Estimates: Information Information saturated (h1) model Standard errors
Expected Structured Standard
Regressions: prok ~ gewiss lz.1 ~ prok gewiss
Estimate
Std.Err
z-value
P(>|z|)
-0.366
0.046
-7.922
0.000
-3.385 0.228
0.813 0.577
-4.164 0.396
0.000 0.692
Estimate 0.229 26.206
Std.Err 0.025 2.818
z-value 9.301 9.301
P(>|z|) 0.000 0.000
Variances: .prok .lz.1
Die Tabelle Regressions enthält drei Pfadkoeffizienten: den Koeffizienten für den Effekt der unabhängigen Variablen auf die Mediatorvariable (a), den Koeffizienten für den Effekt der Mediatorvariablen auf die abhängige Variable (b) sowie den Koeffizienten für den Effekt der unabhängigen Variablen auf die abhängige Variable, kontrolliert für den Mediator (c‘). Der Effekt c‘ wird auch als direkter Effekt bezeichnet. Er gibt an, wie stark die unabhängige Variable mit der abhängigen Variablen zusammenhängt nach Kontrolle der Mediatorvariablen. Wenn der Zusammenhang vollständig durch die Mediatorvariable vermittelt wird, sollte der direkte Effekt nicht signifikant von Null verschieden sein. Dies ist hier der Fall: Gewissenhaftigkeit hängt nicht signifikant mit Lebenszufriedenheit zusammen, kontrolliert für Prokrastination.
313
314
19 Lineare Strukturgleichungsmodelle
Damit wissen wir jedoch noch nichts über die Mediation selbst. Eine Mediation liegt nur vor, wenn der indirekte Effekt signifikant ist. Der indirekte Effekt ist in dieser Ausgabe jedoch nicht enthalten. Um den indirekten Effekt zu schätzen und auf Signifikanz zu testen, modifizieren wir die Modellgleichung. > med2.txt med2.fit |z|)
(a)
-0.366
0.042
-8.635
0.000
(b) (c)
-3.385 0.228
0.792 0.546
-4.273 0.418
0.000 0.676
Estimate 0.229 26.206
Std.Err 0.025 2.852
z-value 9.098 9.189
P(>|z|) 0.000 0.000
Std.Err 0.314 0.510
z-value 3.946 2.880
P(>|z|) 0.000 0.004
Variances: .prok .lz.1 Defined Parameters: indirekt total
Estimate 1.240 1.468
Die Tabellen Regressions und Variances sind weitgehend unverändert. Allerdings werden bei den Pfadkoeffizienten jetzt auch die Labels (a), (b) und (c) aufgeführt, die wir für die verschiedenen Effekte vergeben haben. Die Tabelle Defined Parameters ist neu. Hier erscheinen unsere neu definierten Modellparameter. Der totale Effekt hat den Wert 1.468 und ist signifikant von Null verschieden, d. h., je höher die Gewissenhaftigkeit, desto höher die Lebenszufriedenheit. Der totale Effekt setzt sich aus dem indirekten und dem direkten Effekt zusammen. Der indirekte Effekt hat den Wert 1.240 und ist signifikant von Null verschieden. Dies deutet darauf
315
316
19 Lineare Strukturgleichungsmodelle
hin, dass Prokrastination tatsächlich den Zusammenhang zwischen Gewissenhaftigkeit und Lebenszufriedenheit vermittelt, und zwar so, dass höhere Gewissenhaftigkeit mit einer erhöhten Tendenz zur Prokrastination einhergeht (a-Pfad) und höhere Prokrastination wiederum die Lebenzufriedenheit verringert (b-Pfad). Wie bereits erwähnt sollte man jedoch den indirekten Effekt idealerweise mit Konfidenzintervallen testen. Diese Konfidenzintervalle fordern wir mit dem folgenden Befehl an: > parameterEstimates (med2.fit, ci = TRUE, boot.ci.type = "bca.simple")
Mit der Funktion parameterEstimates erhält man die Modellparameter in Tabellenform, was besonders praktisch ist, wenn man diese Tabelle exportieren möchte (s. Kap. 21). Mit dem Argument ci = TRUE werden Konfidenzintervalle angefordert. Die Art der Konfidenzintervalle wird im Argument boot.ci.type festgelegt. Hier fordern wir 95%-bias-adjustierte Bootstrap-Perzentil-Konfidenzintervalle (abgekürzt mit bca.simple) an. Weitere Bootstrap-Optionen werden in der Hilfe-Datei zu der Funktion erläutert. Wir erhalten die folgende Ausgabe: lhs op rhs label est se z pvalue 1 prok ~ gewiss a -0.366 0.042 -8.635 0.000 2 lz.1 ~ prok b -3.385 0.792 -4.273 0.000 3 lz.1 ~ gewiss c 0.228 0.546 0.418 0.676 4 prok ~~ prok 0.229 0.025 9.098 0.000 5 lz.1 ~~ lz.1 26.206 2.852 9.189 0.000 6 gewiss ~~ gewiss 0.620 0.000 NA NA 7 indirekt := a*b indirekt 1.240 0.314 3.946 0.000 8 total := c+(a*b) total 1.468 0.510 2.880 0.004
1 2 3 4 5 6 7 8
ci.lower ci.upper -0.452 -0.283 -4.897 -1.796 -0.853 1.285 0.188 0.288 21.372 33.284 0.620 0.620 0.659 1.897 0.557 2.532
19.3
Konfirmatorische Faktorenanalyse
Die unteren bzw. oberen Grenzen der Konfidenzintervalle sind in den letzten beiden Spalten aufgeführt. Das Konfidenzintervall unseres indirekten Effekts (Zeile 7) enthält den Wert Null nicht, d. h., wir können schließen, dass der indirekte Effekt signifikant von Null verschieden ist und wir somit eine Mediation vorliegen haben.
19.3 Konfirmatorische Faktorenanalyse In der konfirmatorischen Faktorenanalyse werden die Beziehungen zwischen den Indikatoren und den latenten Variablen untersucht. Im Rahmen eines Strukturgleichungsmodells nennt man ein solches Modell auch Messmodell, da hier beschrieben wird, wie die latenten Variablen gemessen werden. Im Gegensatz zur exploratorischen Faktorenanalyse (s. Abschn. 18.1) werden in der konfirmatorischen Faktorenanalyse sowohl die Anzahl der Faktoren bzw. latenten Variablen als auch die Beziehungen der Items zu diesen Faktoren festgelegt, d. h., wir bestimmen, welche Items auf welchen Faktoren laden dürfen. Alle anderen Faktorladungen werden automatisch auf Null gesetzt. Mithilfe von Indikatoren der Modellgüte überprüfen wir dann, ob das von uns vorgegebene Modell angemessen auf die beobachteten Daten passt. Einfaktorielles Modell Wir betrachten nun die fünf Items der Satisfaction With Life Scale (Diener et al., 1985). Wir möchten untersuchen, ob ein einfaktorielles Modell gut auf die Daten passt. Dazu spezifizieren wir zunächst die folgende Modellgleichung: > cfa.1.txt cfa.1.fit summary(cfa.1.fit, fit = TRUE)
Die Ausgabe beginnt mit Informationen zu den benötigten Iterationen und der verwendeten Stichprobengröße. Darunter steht das Ergebnis des χ²-Anpassungstests (Model Test User Model). Bei überidentifizierten Modellen drückt dieser Test aus, wie gut unser Modell auf die beobachteten Daten passt. Die Nullhypothese des Tests ist, dass die beobachtete Varianz-Kovarianz-Matrix gleich der modellimplizierten Varianz-Kovarianz-Matrix ist. In unserem Beispiel ist der Test signifikant. Dies deutet daher darauf hin, dass das Modell nicht gut auf die Daten passt. lavaan 0.6-5 ended normally after 21 iterations Estimator Optimization method Number of free parameters
Number of observations
ML NLMINB 10 Used 188
Total 191
Model Test User Model: Test statistic Degrees of freedom P-value (Chi-square)
11.263 5 0.046
Es folgt der χ²-Test für das Baseline-Modell (Model Test Baseline Model). Im Baseline-Modell werden alle Ladungskoeffizienten auf 1 und alle Varianzen der latenten Variablen auf 0 fixiert. Zudem werden sämtliche Korrelationen zwischen latenten Variablen auf 0 fixiert (hier nicht relevant). Das Baseline-Modell ist also ein extrem restriktives Modell und wird immer schlechter passen als unser tatsächliches Modell. Dieser Test kann nützlich sein, um einzuschätzen, wie viel besser unser Modell ist als das restriktivste Modell. Model Test Baseline Model: Test statistic Degrees of freedom P-value
427.245 10 0.000
19.3
Konfirmatorische Faktorenanalyse
In den folgenden Zeilen werden eine Reihe von Modellgütemaßen aufgeführt (zur Berechnung und Interpretation s. Eid et al., 2017). User Model versus Baseline Model: Comparative Fit Index (CFI) Tucker-Lewis Index (TLI)
0.985 0.970
Loglikelihood and Information Criteria: Loglikelihood user model (H0) Loglikelihood unrestricted model (H1) Akaike (AIC) Bayesian (BIC) Sample-size adjusted Bayesian (BIC)
-1440.752 -1435.121 2901.505 2933.869 2902.194
Root Mean Square Error of Approximation: RMSEA 90 Percent confidence interval - lower 90 Percent confidence interval - upper P-value RMSEA |z|)
1.000 0.854 0.851 0.851 0.866
0.073 0.068 0.085 0.098
11.703 12.453 10.071 8.860
0.000 0.000 0.000 0.000
Estimate 0.475 0.716 0.553 1.149 1.688 1.371
Std.Err 0.082 0.092 0.076 0.134 0.190 0.195
z-value 5.807 7.813 7.243 8.553 8.897 7.020
P(>|z|) 0.000 0.000 0.000 0.000 0.000 0.000
Variances: .lz13 .lz14 .lz15 .lz16 .lz17 f
Tipp
Die Ladung des ersten Items lz13 wird in lavaan automatisch auf 1 gesetzt, um das Modell zu identifizieren und die latente Variable zu skalieren. Wir können aber auch in der Modellgleichung angeben, dass die Ladung des ersten Items frei geschätzt (hier: NA*lz13) und stattdessen die Varianz der latenten Variablen auf 1 fixiert werden soll (durch eine zusätzliche Zeile in der Modellgleichung, hier: lz ~ 1*lz).
Modellvergleiche Die konfirmatorische Faktorenanalyse wird häufig eingesetzt, um verschiedene Faktorenmodelle empirisch miteinander zu vergleichen. Grundsätzlich kann man immer dann, wenn zwei Modelle ineinander geschachtelt sind, diese Modelle mit einem Likelihood-Ratio-Test miteinander vergleichen. Modelle sind dann ineinander geschachtelt, wenn ein Modell aus dem anderen abgeleitet werden kann, indem Parameter weggelassen oder hinzugefügt werden. Wir vergleichen nun ein zweifaktorielles Modell mit einem einfaktoriellen Modell. Das einfaktorielle Modell lässt sich aus dem zweifaktoriellen Modell herleiten, indem man die Korrelation der beiden Faktoren auf 1 setzt. Somit handelt es sich hier um geschachtelte Modelle und wir können einen Modellvergleich durchführen. In unserem zweifaktoriellen Modell laden die Items lz13 bis lz15 auf dem ersten Faktor und die Items lz16 und lz17 auf dem zweiten Faktor:
19.3
Konfirmatorische Faktorenanalyse
> cfa.2.txt cfa.2.fit anova(cfa.1.fit, cfa.2.fit) Chi-Squared Difference Test
cfa.2.fit cfa.1.fit
Df AIC BIC Chisq Chisq diff Df diff 4 2894.1 2929.7 1.8341 5 2901.5 2933.9 11.2633 9.4292 1 Pr(>Chisq)
cfa.2.fit cfa.1.fit 0.002136 ** --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
In der Spalte Df stehen die Freiheitsgrade der beiden Modelle. Beim zweifaktoriellen Modell cfa.2.fit wurde ein Parameter mehr geschätzt als beim einfaktoriellen Modell (die Korrelation zwischen den beiden Faktoren), daher hat dieses Modell einen Freiheitsgrad weniger als das einfaktorielle Modell. Es folgen Akaikes Information Criterion (AIC) und Bayesian Information Criterion (BIC). Je kleiner diese Werte sind, desto besser passt das Modell auf die Daten. AIC und BIC sind inbesondere für den Vergleich von nicht-geschachtelten Modellen geeignet. In der Spalte Chisq finden wir den jeweiligen χ²-Wert der beiden Modelle. Der χ²-Wert des zweifaktoriellen Modells ist kleiner als der des einfaktoriellen Modells. Das ist immer so, denn das zweifaktorielle Modell ist weniger restriktiv und passt daher immer besser auf die Daten als das einfaktorielle Modell.
321
322
19 Lineare Strukturgleichungsmodelle
Ist dieser Unterschied statistisch bedeutsam? Die Antwort auf diese Frage liefert der Likelihood-Ratio-Test in den folgenden Spalten. Hier wird die Differenz der beiden χ²-Werte (Chisq diff) als Prüfgröße verwendet, die ebenfalls χ²-verteilt ist. Die Freiheitsgrade dieser χ²-Verteilung entsprechen der Differenz der Freiheitsgrade der beiden Modelle (Df diff). Schließlich erhalten wir den p-Wert für diesen Test. In diesem Beispiel ist der p-Wert für diesen Test (Pr(>Chisq)) kleiner als .05, d. h., das weniger restriktive zweifaktorielle Modell passt signifikant besser auf die Daten als das restriktivere einfaktorielle Modell.
19.4 Kombination von Mess- und Strukturmodell Strukturgleichungsmodelle im engeren Sinne sind Modelle, in denen die Beziehungen zwischen mehreren latenten Variablen dargestellt werden. Für jede latente Variable wird ein eigenes Messmodell formuliert, in dem festgelegt wird, durch welche Indikatoren diese Variable gemessen wird. Die Beziehungen der latenten Variablen untereinander werden im Strukturmodell beschrieben. Wir behandeln hier ein sehr einfaches Modell mit zwei latenten Variablen. Die latente Variable Studienzufriedenheit (zuf) wird durch die Zufriedenheit mit den Studieninhalten (zuf.inh.1), mit den Studienbedingungen (zuf.bed.1) sowie mit der Belastung durch das Studium (zuf.bel.1) gemessen. Die latente Variable Lebenszufriedenheit (lz) wird durch die Items lz13, lz14 und lz15 gemessen (s. oben). Die beiden Messmodelle sind daher: zuf =~ zuf.inh.1 + zuf.bed.1 + zuf.bel.1 lz =~ lz13 + lz14 + lz15
Zwischen den beiden latenten Variablen besteht eine gerichtete Beziehung: Die Studienzufriedenheit (unabhängige Variable) beeinflusst die Lebenszufriedenheit (abhängige Variable). (Wichtig: Obwohl wir eine gerichtete Beziehung im Modell annehmen, können wir aus den Ergebnissen keine kausalen Schlüsse ziehen, da es sich nach wie vor um korrelative Daten handelt.) Das Strukturmodell ist somit: lz ~ zuf
Diese Modellgleichungen werden nun wieder in einem neuen Objekt gespeichert. > sem.txt sem.fit summary(sem.fit, fit = TRUE)
Den Aufbau der Ausgabe haben wir oben schon detailliert besprochen und stellen die Ausgabe für dieses Modell daher verkürzt dar. In der folgenden Tabelle finden wir unter Latent Variables die Ladungskoeffizienten, die die Stärke der Beziehungen zwischen den latenten Variablen und den jeweiligen Indikatoren in den Messmodellen beschreiben. Unter Regressions wird der Pfadkoeffizient des Strukturmodells aufgeführt, der die Beziehung der beiden latenten Variablen beschreibt. In der Tabelle Variances werden die Varianzen der verschiedenen Variablen aufgeführt. Für die Indikatoren und die latente abhängige Variable lz handelt es sich dabei um Residualvarianzen. Das erkennt man u. a. daran, dass diese Variablennamen mit einem Punkt beginnen (z. B. .lz). Für die unabhängige latente Variable zuf wird dagegen die beobachtete Varianz ausgegeben. Latent Variables: zuf =~ zuf.inh.1 zuf.bed.1 zuf.bel.1 lz =~ lz13 lz14 lz15
Estimate
Std.Err
z-value
P(>|z|)
1.000 1.019 1.086
0.248 0.243
4.108 4.469
0.000 0.000
1.000 0.865 0.985
0.083 0.084
10.370 11.683
0.000 0.000
Estimate
Std.Err
z-value
P(>|z|)
2.002
0.459
4.364
0.000
Estimate 0.253 0.411 0.272 0.512 0.714 0.401
Std.Err 0.038 0.055 0.043 0.094 0.098 0.085
z-value 6.564 7.495 6.324 5.452 7.261 4.730
P(>|z|) 0.000 0.000 0.000 0.000 0.000 0.000
Regressions: lz ~ zuf Variances: .zuf.inh.1 .zuf.bed.1 .zuf.bel.1 .lz13 .lz14 .lz15
323
324
19 Lineare Strukturgleichungsmodelle
zuf .lz
0.127 0.739
0.041 0.164
3.090 4.516
0.002 0.000
19.5 Erstellen eines Pfaddiagramms Bei komplexeren Strukturgleichungsmodellen kann man schnell den Überblick verlieren. Daher werden Strukturgleichungsmodelle gerne grafisch dargestellt. Mit den Paketen semPlot (Epskamp, 2019) und lavaanPlot (Lishinski, 2018) kann man in lavaan geschätzte Modelle schnell und einfach grafisch darstellen lassen. Wir schauen uns hier die Funktion semPaths aus dem semPlot-Paket an und erstellen damit ein Pfaddiagramm für das Modell aus dem vorherigen Abschnitt: > semPaths(sem.fit)
Das damit erstellte Pfaddiagramm ist in Abbildung 19.2 links dargestellt. Die semPaths-Funktion bietet eine Reihe von zusätzlichen Argumenten, mit denen man die Darstellung anpassen kann. Mit dem folgenden Befehl werden die unstandardisierten Modellparameter (Ladungs- und Pfadkoeffizienten sowie Residualvarianzen) eingefügt. Außerdem wurde hier das Layout etwas angepasst (s. Abb. 19.2 rechts): > semPaths(sem.fit, whatLabels = "est", layout = "spring", layoutSplit = TRUE, rotation = 2)
Abbildung 19.2 Mit semPaths erstellte Pfaddiagramme
19.7
Die wichtigsten Funktionen im Überblick
19.6 Weitere Funktionen und ergänzende Pakete Das Paket lavaan ist sehr vielseitig und enthält viele weitere nützliche Funktionen. Beispielsweise ist es möglich, Parameter auf bestimmte Werte zu fixieren oder mehrere Parameter gleichzusetzen. Auch komplexere nicht-lineare Restriktionen können relativ einfach spezifiziert werden. Zudem eignet sich lavaan auch für die Analyse von Multigruppen-Modellen und Daten mit Mehrebenenstruktur und verfügt mit growth sogar über eine eigene Funktion für die Analyse von latenten Wachstumskurvenmodellen. Zur Vertiefung empfehle ich das Tutorial auf der lavaan-Homepage (http://lavaan.ugent.be/). Darüber hinaus stehen eine ganze Reihe von Paketen zur Verfügung, die lavaan ergänzen und erweitern, z. B. blavaan (Merkle & Rosseel, 2018) für Bayesianische Strukturgleichungsmodelle oder semTools (Jorgensen et al., 2019) für Funktionen zur Prüfung von Messinvarianz und Poweranalysen.
19.7 Die wichtigsten Funktionen im Überblick Funktion
Beschreibung
modell.txt modell.1 summary(modell.1)
Die Ausgabe beginnt mit Informationen zur verwendeten Schätzfunktion (hier: restricted maximum likelihood bzw. REML), der Modellgleichung sowie den Daten. Wir erhalten außerdem den Wert der Likelihood-Funktion. Linear mixed model fit by REML ['lmerMod']
20.1
Das Nullmodell
Formula: lezu ~ 1 + (1 | nation) Data: kultur REML criterion at convergence: 21236.2
Die Tabelle Scaled residuals enthält eine Fünf-Punkte-Zusammenfassung der standardisierten Residuen (vgl. Ausgabe der Regressionsanalyse in Abschn. 15.1). Diese Werte geben uns einen Eindruck davon, wie stark die Residuen streuen und ob die Verteilung symmetrisch ist. Scaled residuals: Min 1Q Median -3.8534 -0.6683 0.0975
3Q 0.7328
Max 3.3994
In der Tabelle Random Effects finden wir Daten zu den Zufallseffekten. Ein zentraler Unterschied zwischen einem herkömmlichen Regressionsmodell und einem Mehrebenenmodell ist der, dass das Mehrebenenmodell mehrere Residuen enthält. Die Varianzen (Variance) bzw. Standardabweichungen (Std.Dev, definiert als Wurzel der Varianz) dieser Residuen sind in dieser Tabelle aufgeführt. Wir erfahren außerdem, wie viele Ebene-1- und Ebene-2-Einheiten analysiert wurden. Random effects: Groups Name Variance Std.Dev. nation (Intercept) 0.2862 0.535 Residual 1.2287 1.108 Number of obs: 6929, groups: nation, 40
Die letzte Tabelle enthält die festen Effekte. Im Nullmodell ist dies nur der Achsenabschnitt, der hier genau der mittleren Lebenszufriedenheit über alle Personen und über alle Nationen hinweg entspricht. Für diesen Parameter erhalten wir auch den Standardfehler (Std. Error) sowie den t-Wert (t value), jedoch keine Freiheitsgrade und keinen p-Wert. Warum das so ist und wie man p-Werte ermitteln kann, besprechen wir in Abschnitt 20.2.1. Fixed effects: Estimate Std. Error t value (Intercept) 4.397 0.086 51.12
329
330
20 Mehrebenenanalyse
Die Intraklassenkorrelation Die Intraklassenkorrelation (ICC) drückt aus, wie ähnlich sich Ebene-1-Einheiten derselben Ebene-2-Einheit im Vergleich zu Ebene-1-Einheiten aus anderen Ebene-2Einheiten sind. Für unser Datenbeispiel gibt die ICC also an, wie ähnlich sind Personen aus derselben Nation sind gegenüber Personen aus anderen Nationen. Formal wird sie berechnet als der Anteil der Varianz auf Ebene 2 an der Gesamtvarianz, wobei die Varianzen wiederum aufgrund des Nullmodells geschätzt werden. Je höher die Intraklassenkorrelation, desto stärker unterscheiden sich die Ebene-2-Einheiten voneinander und umso ähnlicher sind sich die Ebene-1-Einheiten innerhalb einer Ebene-2-Einheit. Wir bestimmen die Intraklassenkorrelation mit dem folgenden Befehl: > performance::icc(modell.1) # Intraclass Correlation Coefficient Adjusted ICC: 0.189 Conditional ICC: 0.189
Wir erhalten hier zwei Werte: die adjustierte Intraklassenkorrelation und die bedingte Intraklassenkorrelation. Diese Werte sind bei unserem Nullmodell identisch. Enthalten die Modelle aber mehr Effekte oder mehr Ebenen, können sich diese Werte unterscheiden. Details dazu findet man in der Hilfe-Datei zu dieser Funktion. Der Wert 0.189 bedeutet für unser Datenbeispiel, dass 18.9 % der Unterschiede in der Lebenszufriedenheit auf Unterschiede zwischen Nationen zurückgeführt werden können.
20.2 Das Random-Intercept-Modell Wir möchten nun herausfinden, wie stark die Lebenszufriedenheit von der Häufigkeit des Erlebens von positiven Gefühlen abhängt. Dazu fügen wir die Variable pa (positiver Affekt) als Prädiktor in die Modellgleichung ein. Der Achsenabschnitt muss nun nicht mehr gesondert aufgeführt werden. Die Ausgabe wird wieder mit der summary-Funktion angefordert. > modell.2 summary(modell.2)
Wir besprechen hier nur einige ausgewählte Teile der Ausgabe. Die Tabelle Random Effects enthält wiederum die Varianzen und Standardabweichungen der Residuen
20.2
Das Random-Intercept-Modell
auf Ebene 2 (nation (Intercept)) und auf Ebene 1 (Residual). Beide Werte unterscheiden sich von den Werten im Nullmodell. Das sollte so sein, denn die Interpretation dieser Werte hat sich geändert. Zum Beispiel entsprachen die Residuen auf Ebene 1 im Nullmodell den Abweichungen der individuellen Werte vom jeweiligen Gruppen-Mittelwert. Im Random-Intercept-Modell dagegen entsprechen sie den Abweichungen der individuellen Werte vom jeweiligen vorhergesagten Wert bzw. von der gruppenspezifischen Regressionsgerade. Gleichermaßen entsprachen die Residuen auf Ebene 2 im Nullmodell den Abweichungen der Gruppenmittelwerte vom Gesamtmittelwert. Hier geben sie dagegen wieder, wie stark sich die Achsenabschnitte der gruppenspezifischen Regressionsgeraden vom mittleren Achsenabschnitt unterscheiden. Random effects: Groups Name Variance Std.Dev. nation (Intercept) 0.191 0.437 Residual 1.007 1.003
Diesen mittleren Achsenabschnitt finden wir in der Tabelle Fixed Effects. In dieser Tabelle sehen wir die Koeffizienten und die dazugehörigen Standardfehler und t-Werte für den Achsenabschnitt (Intercept) und den Prädiktor pa. Die Interpretation dieser Koeffizienten ist ähnlich wie bei der normalen Regressionsanalyse. Der Achsenabschnitt bezeichnet den vorhergesagten Wert auf der abhängigen Variablen, wenn alle Prädiktoren (hier nur positiver Affekt) den Wert Null annehmen. Der Koeffizient des Prädiktors pa bezeichnet den Wert, um den sich die vorhergesagten Werte auf der abhängigen Variablen verändern, wenn dieser Prädiktor um eine Einheit erhöht wird. Fixed effects: Estimate Std. Error t value (Intercept) 2.487476 0.085662 29.04 pa 0.350660 0.008939 39.23
Bei dieser Ausgabe gibt es nun zwei Probleme. Erstens werden zwar t-Werte, jedoch keine p-Werte ausgegeben. In Abschnitt 20.2.1 besprechen wir ein paar Lösungen für dieses Problem. Zweitens ist der Achsenabschnitt nicht sinnvoll zu interpretieren, da die Variable pa einen Wertebereich von 1 bis 9 hat und somit den Wert 0 gar nicht enthält. Um den Achsenabschnitt interpretierbar zu machen, kann (und sollte) man diesen Prädiktor zentrieren. In Abschnitt 20.2.2 werden zwei Zentrierungsmethoden vorgestellt, die für die Mehrebenenanalyse zur Verfügung stehen.
331
332
20 Mehrebenenanalyse
20.2.1 Signifikanztests für die festen Effekte In der Ausgabe der lmer-Funktion fehlen nicht nur die p-Werte, sondern auch die Freiheitsgrade. Und die sind genau das Problem: Es gibt in der Literatur keine Einigkeit, wie die Freiheitsgrade bei Mehrebenenmodellen genau berechnet werden sollen. In R stehen uns eine Reihe verschiedener Methoden zur Verfügung, um die festen Effekte auf Signifikanz zu testen. Modellvergleich mit Devianzentest Bei diesem Ansatz werden wie bei der hierarchischen Regression (s. Abschn. 15.3) zwei Modelle miteinander verglichen: Das einfachere Modell enthält alle Prädiktoren außer den Prädiktor, den wir auf Signifikanz testen wollen. Das komplexere Modell enthält dieselben Prädiktoren wie das einfache Modell und zusätzlich den uns interessierenden Prädiktor. In unserem Beispiel entspricht das Nullmodell modell.1 dem einfacheren Modell und das Random-Intercept-Modell modell.2 dem komplexeren Modell. Wir vergleichen diese Modelle mit der anova-Funktion (s. Abschn. 15.3): > anova(modell.1, modell.2) refitting model(s) with ML (instead of REML) Data: kultur Models: modell.1: lezu ~ 1 + (1 | nation) modell.2: lezu ~ pa + (1 | nation)
modell.1 modell.2
Df AIC BIC logLik deviance 3 21239 21260 -10616.6 21233 4 19852 19879 -9921.9 19844
Chisq Chi Df Pr(>Chisq) modell.1 modell.2 1389.3 1 < 2.2e-16 ***
Die Tabelle enthält zwei Zeilen, eine für jedes Modell. In den Spalten werden für jedes Modell zunächst die Freiheitsgrade (Df), die Informationskriterien AIC(Akaikes Information Criterion) und BIC (Bayesian Information Criterion) sowie der Wert der Log-Likelihood-Funktion (logLik) berichtet. Multipliziert man die Log-Likelihood mit -2, erhält man die Devianz (deviance). Je kleiner die Devianz, desto besser passt das Modell auf die Daten. Die Differenz der beiden Devianzen ist die Prüfgröße für einen χ²-Test (Chisq). Die Freiheitsgrade dieses Tests (Chi Df) entsprechen genau der Differenz der Freiheitsgrade der beiden Modelle. In der letzten Spalte
20.2
Das Random-Intercept-Modell
erhalten wir den p-Wert (Pr(>Chisq)). Hier ist der p-Wert kleiner als .05, d. h., das komplexere Modell passt signifikant besser als das einfachere Modell. Wir können folgern, dass positiver Affekt signifikant mit der Lebenszufriedenheit zusammenhängt. Tipp
Wenn man mehrere Prädiktoren auf Signifikanz testen möchte, muss man für jeden Prädiktor einen eigenen Modellvergleich durchführen. Die Funktion Anova aus dem car-Paket (Fox & Weisberg, 2019) nimmt uns diese Arbeit ab. Mit dieser Funktion erhalten wir für jeden festen Effekt einen χ²-Test. Falls das Modell Interaktionen enthält, müssen wir auch hier wieder die Unterscheidung zwischen TypII- und Typ-III-Quadratsummen beachten (s. Abschn. 13.2.1). Approximative Freiheitsgrade In diesem Ansatz werden sog. approximative Freiheitsgrade für die festen Effekte bestimmt. Diese Freiheitsgrade kann man dann nehmen, um die festen Effekte (d. h., die Regressionskoeffizienten) ähnlich wie bei der Regressionsanalyse mit t-Tests auf Signifikanz zu prüfen. Im Paket lmerTest (Kuznetsova et al., 2017) stehen approximative Freiheitsgrade nach Satterthwaite (Standardeinstellung) sowie Kenward-Roger-approximative Freiheitsgrade zur Verfügung. Um die Freiheitsgrade und pWerte für die festen Effekte anzufordern, laden wir das Paket und schätzen dann noch einmal das Modell mit demselben Befehl wie oben. Hier wird nun aber nicht die lmer-Funktion aus dem lme4-Paket verwendet, sondern die gleichnamige Funktion aus dem lmerTest-Paket: > library(lmerTest) > modell.2 |t|) (Intercept) 2.487e+00 8.566e-02 8.395e+01 29.04 % mutate(pa.zen.gm = pa - mean(pa, na.rm = TRUE))
Wir haben hier drei Befehle mit der Pipe (%>%) verknüpft. Wir nehmen hier den Data Frame kultur und gruppieren diesen mit der Funktion group_by nach der Variablen nation. Damit erreichen wir, dass alle nachfolgenden Befehle immer getrennt für jede Nation durchgeführt werden. Die eigentliche Zentrierung folgt dann im mutateBefehl. Hier legen wir eine neue Variable mit dem Namen pa.zen.gm an. Die Formel für die Berechnung dieser Variablen steht hinter dem Gleichheitszeichen: Von jedem beobachteten Wert auf der Variablen pa wird der Mittelwert dieser Variablen abgezogen. Da wir vorher mit group_by festgelegt haben, dass dieser Befehl für jede Gruppe getrennt durchgeführt werden soll, werden hier automatisch die Gruppenmittelwerte, und nicht etwa der Gesamtmittelwert bestimmt. Das Argument na.rm = TRUE müssen wir hier ergänzen, damit die Gruppenmittelwerte auch dann
20.3
Das Random-Slopes-Modell
berechnet werden, wenn einzelne Personen auf der Variablen pa fehlende Werte haben (s. Abschn. 8.2.3).
20.3 Das Random-Slopes-Modell Im Random-Intercept-Modell wird angenommen, dass die Steigung der gruppenspezifischen Regressionsgeraden in allen Gruppen gleich ist. Diese Annahme ist jedoch häufig zu streng. Man kann daher auch zulassen, dass sich die Steigungen zwischen den Gruppen unterscheiden dürfen. So ein Modell nennt man Random-Slopes-Modell oder auch Random-Coefficient-Modell. Im folgenden Modell lassen wir Random Slopes für die Variable pa.zen.gm zu. Bei dieser Variablen handelt es sich um die am Gruppenmittelwert zentrierte Variable pa (s. Abschn. 20.2.2). Da wir das lmerTest-Paket (Kuznetsova et al., 2017) geladen haben, wird hier automatisch die lmer-Funktion aus diesem Paket verwendet. > modell.3 modell.2a anova(modell.2a, modell.3) refitting model(s) with ML (instead of REML) Data: kultur Models: modell.2a: lezu ~ pa.zen.gm + (1 | nation) modell.3: lezu ~ pa.zen.gm + (pa.zen.gm | nation)
modell.2a modell.3
Df AIC BIC logLik deviance 4 19868 19895 -9929.8 19860 6 19827 19868 -9907.4 19815 Chisq Chi Df Pr(>Chisq)
modell.2a modell.3
44.8
2
1.87e-10 ***
20.3
Das Random-Slopes-Modell
Der Test ist signifikant, d. h., das Random-Slopes-Modell passt signifikant besser auf die Daten als das Random-Intercept-Modell und die gruppenspezifischen Steigungskoeffizienten unterscheiden sich signifikant voneinander. Grafische Darstellung der festen Effekte Bei einem Random-Slopes-Modell interessiert einen häufig, in welchem Bereich die gruppenspezifischen Steigungskoeffizienten streuen. Sind alle nahe beieinander oder weit voneinander entfernt, sind alle positiv oder gibt es gar einige Nationen, in denen der Zusammenhang negativ ist? Diese Fragen kann man beantworten, indem man die gruppenspezifischen Achsenabschnitte und Steigungskoeffizienten grafisch darstellt. Eine schöne Art der Darstellung ist der Dotplot, der mit der Funktion dotplot aus dem lattice-Paket (Sarkar, 2008) erstellt wird. Dieses Paket muss vor dem Ausführen des folgenden Befehls installiert und geladen werden. > dotplot(ranef(modell.3, condVar = TRUE))
Mit der Funktion ranef erhalten wir eine Tabelle der gruppenspezifischen Achsenabschnitte und Steigungskoeffizienten. Wendet man die dotplot-Funktion darauf an, wird das in Abbildung 20.1 dargestellte Diagramm erstellt. Hier sind die Achsenabschnitte (links) und Steigungskoeffizienten (rechts) getrennt für jede Gruppe abgebildet. Die Fehlerbalken werden durch das optionale Argument condVar = TRUE erzeugt.
Abbildung 20.1 Dotplot der gruppenspezifischen Achsenabschnitte (links) und Steigungskoeffizienten (rechts)
337
338
20 Mehrebenenanalyse
20.4 Modelle mit Ebene-2-Prädiktoren Ebene-2-Prädiktoren sind Prädiktoren, die nur zwischen den Gruppen, jedoch nicht innerhalb der Gruppen variieren. In unserem Datenbeispiel ist die Variable gdp so eine Variable: Sie gibt die Höhe des Bruttoinlandsprodukts der jeweiligen Nationen an. Wir haben somit für jede Nation genau einen Wert, und für alle Personen innerhalb einer Nation ist dies derselbe Wert. Zentrierung von Ebene-2-Prädiktoren Auch Ebene-2-Prädiktoren werden in der Regel zentriert. Hier steht nur die Zentrierung am Gesamtmittelwert zur Verfügung, die wir mit der scale-Funktion durchführen können. Wichtig: Wenn wir diese Funktion verwenden, wird der Gesamtmittelwert über alle Personen berechnet, d. h., der Wert Null entspricht dem Mittelwert aller Personen in unserer Stichprobe. > kultur$gdp.zen modell.4 |t|) (Intercept) 4.38793 0.07382 38.18487 59.441 < 2e-16 *** pa.zen.gm 0.34681 0.01606 38.36236 21.593 < 2e-16 *** gdp.zen 1.59847 0.43858 38.55870 3.645 0.000787 ***
20.4
Modelle mit Ebene-2-Prädiktoren
Modell mit Prädiktoren auf Ebene 2 mit Cross-Level-Interaktion Zusätzlich können wir nun noch die Cross-Level-Interaktion zwischen dem Ebene1-Prädiktor pa.zen.gm und dem Ebene-2-Prädiktor gdp.zen aufnehmen. Diese Interaktion drückt aus, wie stark der Zusammenhang zwischen positivem Affekt und Lebenszufriedenheit in Abhängigkeit vom Bruttoinlandsprodukt eines Landes variiert. Um die Cross-Level-Interaktion aufzunehmen, verknüpfen wir die beiden Variablen mit dem Symbol * (vgl. moderierte Regression in Abschn. 16.2): > modell.5 |t|) 38.30627 59.471 < 2e-16 39.24011 23.312 < 2e-16 38.50852 3.898 0.000376 43.92005 2.939 0.005238
Der Koeffizient für die Interaktion ist positiv und signifikant von Null verschieden, d. h., je höher das Bruttoinlandsprodukt einer Nation, desto positiver (stärker) ist der Zusammenhang zwischen positivem Affekt und Lebenszufriedenheit. Bedingte Regressionsgleichungen und Interaktionsdiagramm Um uns die Interpretation der Cross-Level-Interaktion zu erleichtern, greifen wir auf dieselben Funktionen zurück, die wir schon bei der moderierten Regression verwendet haben (s. Abschn. 16.3.3). Mit der Funktion emtrends aus dem emmeans-Paket (Lenth, 2019) können wir die bedingten Steigungskoeffizienten der fokalen Variablen (meistens der Ebene-1-Prädiktor) für ausgewählte Werte auf der Moderatorvariablen (meistens der Ebene-2-Prädiktor) bestimmen. Die fokale Variable wird im var-Argument angegeben, die Moderatorvariable im specs-Argument. Im folgenden Beispiel berechnen wir die bedingten Steigungskoeffizienten für den Ebene-1-Prädiktor pa.ze.gm für die Werte -0.16 und 0.16 auf dem Ebene-2-Prädiktor gdp.zen. Diese Werte entsprechen genau dem Mittelwert plus/minus eine Standardabweichung. Wir geben sie im at-Argument an (für Details s. Abschn. 16.3.3). > emtrends(modell.5, var = "pa.zen.gm", specs = "gdp.zen", at = list(gdp.zen = c(-.16, .16)))
339
340
20 Mehrebenenanalyse Note: D.f. calculations have been disabled because the number of observations exceeds 3000. … gdp.zen pa.zen.gm.trend SE df asymp.LCL asymp.UCL -0.16 0.303 0.0210 Inf 0.262 0.344 0.16 0.388 0.0204 Inf 0.348 0.428 Degrees-of-freedom method: asymptotic Confidence level used: 0.95
Wir erhalten zunächst eine längere Warnmeldung, die wir hier aus Platzgründen nicht vollständig darstellen. Bei großen Stichproben werden die approximativen Freiheitsgrade nicht bestimmt, da dies sehr lange dauern würde. Stattdessen wird hier anstelle einer t-Verteilung eine z-Verteilung angenommen. In der Tabelle erhalten wir für jeden der beiden von uns vorgegebenen Werte auf der Moderatorvariablen gdp.zen jeweils die bedingten Regressionskoeffizienten (Spalte pa.zen.gm.trend), deren Standardfehler (SE), ggf. approximative Freiheitsgrade (df) sowie die untere und obere Grenze der Konfidenzintervalle (asymp.LCL und asymp.ULC).
Abbildung 20.2 Darstellung der Cross-Level-Interaktion mit der interact_plot-Funktion aus dem interactions-Paket
20.5
Die wichtigsten Funktionen im Überblick
Für die grafische Darstellung der bedingten Regressionskoeffizienten mit Konfidenzbändern können wir wieder die interact_plot-Funktion aus dem interactionsPaket (Long, 2019a) verwenden (für Details s. Abschn. 16.3.3). Das mit dem folgenden Befehl erstellte Diagramm ist in Abbildung 20.2 dargestellt. > interact_plot(modell.5, pred = pa.zen.gm, modx = gdp.zen, interval = TRUE , modx.values = "plus-minus")
20.5 Die wichtigsten Funktionen im Überblick Funktion
Beschreibung
lmer(av ~ uv + (1 | gruppe), data = daten)*
Spezifikation eines Mehrebenenmodells (hier ein Random-Intercept-Modell mit einer unabhängigen Variablen) im Paket lme4.
performance::icc()*
Berechnet die Intraklassenkorrelation.
anova()
Devianzentest für den Vergleich von zwei Mehrebenenmodellen.
Anova()*
Führt den Devianzentest automatisch für jeden festen Effekt im Modell aus und gibt die entsprechenden p-Werte aus. Funktion aus dem car-Paket.
lmerTest::lmer()*
Mit der lmer-Funktion aus dem Paket lmerTest werden approximative Freiheitsgrade und p-Werte für Mehrebenenmodelle berechnet.
dotplot(ranef(modell))*
Erstellt einen Dotplot der gruppenspezifischen Achsenabschnitte und Steigungskoeffizienten. Funktion aus dem lattice-Paket.
emtrends()*
Bestimmt bedingte Regressionskoeffizienten für ausgewählte Werte auf einer kategorialen oder metrischen Moderatorvariablen. Funktion aus dem emmeans-Paket.
interact_plot()*
Darstellung von bedingten Regressionsgeraden. Funktion aus dem interactions-Paket.
* Funktionen aus zusätzlichen Paketen
341
342
20 Mehrebenenanalyse
20.6 Übungen Diese Übungen beziehen sich auf den Datensatz kultur.RData (s. Anhang A: Datensätze). Der Name der Gruppenvariable ist nation. Die folgenden Modelle bauen aufeinander auf. (1) Schätzen Sie ein Nullmodell für die abhängige Variable Aufmerksamkeit auf fremde Gefühle (auf_f). Berechnen Sie auch die Intraklassenkorrelation. (2) Zentrieren Sie nun die Variable Aufmerksamkeit auf eigene Gefühle (auf_e) am Gruppenmittelwert und nehmen Sie dann diese zentrierte Variable als Prädiktor auf. Schätzen Sie jeweils ein Random-Intercept- und ein Random-Slopes-Modell und führen Sie einen Modellvergleich durch, um zu prüfen, ob die Steigungskoeffizienten signifikant zwischen den Nationen variieren. (3) Prüfen Sie, ob das Ausmaß an Individualismus vs. Kollektivismus (ic; hohe Werte = hoher Individualismus) in einem Land Unterschiede in der Aufmerksamkeit auf fremde Gefühle erklärt. (4) Prüfen Sie, ob das Ausmaß an Individualismus vs. Kollektivismus (ic) in einem Land Unterschiede in dem Zusammenhang zwischen der Aufmerksamkeit auf eigene Gefühle und der Aufmerksamkeit auf fremde Gefühle erklärt.
Powered by TCPDF (www.tcpdf.org)
21.1
21
Poweranalysen mit dem pwr-Paket
Poweranalysen und Stichprobenumfangsplanung
Vor der Durchführung einer empirischen Studie sollte die Stichprobengröße werden mittels einer Poweranalyse geplant werden. Dabei wird die Stichprobengröße ermittelt, die man benötigt, um eine bestimmte Effektgröße mit einer bestimmten Wahrscheinlichkeit aufzudecken. Diese Wahrscheinlichkeit wird als Teststärke oder Power bezeichnet. Für einfache statistische Verfahren wie t-Tests oder Varianzanalysen kann der optimale Stichprobenumfang über Formeln direkt berechnet werden (s. Abschn. 21.1). Bei komplexeren statistischen Verfahren hängt der optimale Stichprobenumfang jedoch von derart vielen unbekannten Parametern ab, dass eine Poweranalyse mittels einer Formel häufig nicht mehr praktikabel oder sogar unmöglich ist. In diesen Fällen können Poweranalysen mittels Simulationen durchgeführt werden (s. Abschn. 21.2).
21.1 Poweranalysen mit dem pwr-Paket Das Paket pwr (Champely, 2020) enthält Funktionen, mit denen man den optimalen Stichprobenumfang für viele gängige Tests berechnen kann. Tabelle 21.1 gibt einen Überblick über die Funktionen für verschiedene Tests. Diese Funktionen sind alle nach demselben Prinzip aufgebaut. Tabelle 21.1 Funktionen für Poweranalysen aus dem Paket pwr
Statistisches Verfahren
Funktion
t-Tests
pwr.t.test()
Korrelation
pwr.r.test()
Regression
pwr.f2.test()
Einfaktorielle Varianzanalyse
pwr.anova.test()
χ²-Test
pwr.chisq.test()
Wir schauen uns hier beispielhaft die Funktion für den t-Test für unabhängige Stichproben an. Dazu verwenden wir die pwr.t.test-Funktion, mit der man Poweranalysen für alle t-Tests durchführen kann. Dass es sich um einen t-Test für unabhängige
343
344
21 Poweranalysen und Stichprobenumfangsplanung
Stichproben handelt, legen wir im Argument type = "two.sample" fest. Im folgenden Beispiel bestimmen wir den optimalen Stichprobenumfang für einen t-Test für unabhängige Stichproben mit einem Effekt von Cohens d = 0.5 (d = 0.5) bei einem Signifikanzniveau von 5 % (sig.level = 0.05) und einer Teststärke von 80 % (power = 0.8). Der Test soll zweiseitig durchgeführt werden (alternative = "two.sided"): > pwr.t.test(d = 0.5, sig.level = 0.05, power = 0.8, type = "two.sample", alternative = "two.sided") Two-sample t test power calculation n d sig.level power alternative
= = = = =
63.76561 0.5 0.05 0.8 two.sided
NOTE: n is number in *each* group
Die Analyse zeigt, dass ein Stichprobenumfang von (aufgerundet) N = 64 pro Gruppe optimal wäre. Insgesamt müssten wir also 128 Versuchspersonen untersuchen. Tipp
Weitere Pakete, die ebenfalls Poweranalysen anhand bestimmter Formeln durchführen, sind pwr2ppl (Aberson, 2019) und MBESS (Kelley, 2019). Das pwr2pplPaket enthält Funktionen für spezifische statistische Verfahren (z. B. 2 × 2 Varianzanalyse). Das MBESS-Paket verwendet den Accuracy in Parameter Estimation (AIPE)-Ansatz (z. B. Kelley & Rausch, 2006). Dabei wird nicht eine bestimmte Teststärke, sondern eine spezifische Breite des Konfidenzintervalls vorher festgelegt.
21.2 Simulationsbasierte Poweranalysen Bei simulationsbasierten Poweranalysen werden die geplanten Analysen wiederholt mit simulierten Daten durchgeführt und bestimmte Eigenschaften der Daten (z. B. Stichprobengrößen, Effektgrößen, Varianzen, Kovarianzen) systematisch variiert. Die Ergebnisse werden meist in Form von sog. Powerkurven oder anderen grafischen und tabellarischen Darstellungsformen ausgegeben, an denen man ablesen kann, unter welchen Bedingungen eine bestimmte Teststärke erreicht werden kann. Tabelle
21.3
Übungen
21.2 gibt einen Überblick über verschiedene Pakete und Anwendungen, die Poweranalysen mittels Simulationen ermöglichen. Tabelle 21.2 Übersicht über Pakete für simulationsbasierte Poweranalysen
Paket
Beschreibung
Quelle
Superpower
Umfangreiche Poweranalysen für faktorielle Designs
Caldwell & Lakens (2019)
simr
Poweranalysen für Mehrebenenmodellen, die mit dem lme4-Paket geschätzt werden
Green & MacLeod (2016)
pamm
Poweranalysen für die Zufallseffekte (Random Slopes) in Mehrebenenmodellen
Martin et al. (2011) Magnusson (2018)
powerlmm
Poweranalysen für Mehrebenenmodelle für Längsschnittdaten mit zwei oder drei Ebenen, besonders geeignet für randomisiert kontrollierte Designs
pwrSEM
Shiny App für Poweranalysen für lineare Strukturgleichungsmodelle
Wang & Rhemtulla (2020)
21.3 Übungen Für diese Übungen brauchen Sie keine Daten. (1) Bestimmen Sie den optimalen Stichprobenumfang für die folgenden Tests mit α = 0.05 und Power = 0.80. a. t-Test für abhängige Stichproben, d = 1.0, ungerichtete Hypothese b. Test des Korrelationskoeffizienten r = 0.45, ungerichtete Hypothese c. Multiple Regression mit R² = 0.03 und 10 Prädiktoren d. Einfaktorielle Varianzanalyse mit f = 0.05 und 6 Gruppen (2) Schauen Sie sich eines der in Tabelle 21.2 aufgelisteten Pakete genauer an, sodass Sie eine einfache Poweranalyse damit durchführen können.
Powered by TCPDF (www.tcpdf.org)
345
346
22 Ausgaben exportieren
22
Ausgaben exportieren
In RStudio erscheinen Ausgaben unformatiert in der Konsole. Man könnte diese Ausgaben kopieren und in eine andere Datei (z. B. in eine Word-Datei) einfügen, aber sie sind dann immer noch unformatiert. Geschickter ist es daher, Ausgaben zu exportieren und dann in anderen Programmen zu öffnen und zu bearbeiten. In diesem Kapitel besprechen wir, wie man Daten (Abschn. 22.1), Tabellen (Abschn. 22.2) und Diagramme (Abschn. 22.3) exportiert. Anschließend wird R Markdown vorgestellt (Abschn. 22.4). Diese Anwendung ist geeignet, um R-Befehle, Ausgaben, Diagramme und Kommentare in einem einzigen Dokument zusammenzufügen. Die hier verwendeten Beispiele beziehen sich auf den Datensatz erstis.RData.
22.1 Daten exportieren In R werden Data Frames im Dateiformat .RData gespeichert. Dieses Format kann von anderen Statistik-Programmen nicht gelesen werden. Um die Daten auch in anderen Programmen öffnen zu können, muss man sie in andere Dateiformate exportieren. Dabei gibt es zwei grundsätzliche Möglichkeiten: Entweder exportiert man die Daten in eine Textdatei, die von allen Statistik-Programmen importiert werden kann, oder man exportiert sie direkt in das spezielle Dateiformat der Zielsoftware. Export in Textdateien Es gibt eine Reihe verschiedener Textdatei-Formate. Eines der am häufigsten verwendeten Formate ist das csv-Format, bei dem die einzelnen Werte durch Semikolons oder Kommata getrennt werden. Für den Export in csv-Dateien stehen die Funktionen write.csv und write.csv2 zur Verfügung, die in Abschnitt 22.2 genauer besprochen werden. Manche Programme benötigen andere Formate wie z. B. tabulatorgetrennte Daten. Mit der write.table-Funktion kann man andere Arten von Textdateien erstellen (z. B. tabulatorgetrennte Dateien). Export in spezielle Dateiformate Das foreign-Paket (R Core Team, 2019a) verfügt über einige Funktionen, mit denen Data Frames direkt in spezielle Dateiformate exportiert werden können. Mit der Funktion write.dta wird eine von Stata lesbare Datei erstellt. Um Daten nach SPSS zu exportieren, werden mit der write.foreign-Funktion zwei Dateien erstellt: die
22.2
Tabellen exportieren
Datendatei im Textformat sowie eine Syntaxdatei, mit der die Daten dann in SPSS eingelesen werden können. Numerische vs. Textvariablen Wenn man in R Wertelabels für Faktoren definiert hat (s. Abschn. 7.2), werden die Wertelabels beim Export der Daten übernommen. Ein Beispiel: Wir haben für den Faktor Geschlecht die Wertelabels weiblich und männlich definiert. In den exportierten Daten wird diese Variable nun ebenfalls mit den Ausprägungen weiblich und männlich aufgeführt. Da nicht alle Statistik-Programme mit diesen Werten etwas anfangen können, ist es manchmal sinnvoll, vor dem Export der Daten alle Faktoren in numerische Vektoren zu konvertieren (s. Abschn. 7.2.3). Ein weiterer wichtiger Hinweis: Exportiert man Daten mit Textvariablen, so werden die einzelnen Werte der Textvariablen (und auch die Variablennamen) in Anführungszeichen gesetzt. Dies ist kein Problem, wenn die Daten anschließend in Excel geöffnet werden – hier werden die Anführungszeichen einfach ignoriert. Andere Software-Pakete sind jedoch nicht so nachsichtig. In diesem Fall kann man die Anführungszeichen mit dem Argument quote = FALSE unterdrücken.
22.2 Tabellen exportieren Die in R erstellten Tabellen sind zwar nützlich, aber unschön. Um die Tabellen in ein publikationsreifes Format zu bringen, empfiehlt es sich, sie in ein anderes Programm zu exportieren und dort zu verschönern. Am besten sind dafür Tabellenkalkulationsprogramme wie Excel geeignet. Es gibt zwar Pakete, die den Export von Excel-Dateien erlauben (z. B. xlsx; Dragulescu & Arendt, 2020), allerdings gibt es damit immer wieder Kompatibilitätsprobleme. Wir besprechen hier daher, wie man Tabellen als csv-Dateien speichert, die sich dann problemlos in Excel und anderen Tabellenkalkulationsprogrammen öffnen lassen. Für die Beispiele erstellen wir zunächst eine einfache Kontingenztabelle, die wir anschließend exportieren: > tabelle write.csv2(tabelle, file = "Meine Tabelle.csv")
Tipp
Einige Pakete bieten Funktionen an, mit denen man Tabellen direkt im Layout der American Psychological Association (APA) exportieren kann, z. B. die Pakete apaTables (Stanley, 2018) oder papaja (Aust & Barth, 2020).
22.3 Diagramme exportieren In RStudio erstellte Diagramme lassen sich in verschiedenen Dateiformaten speichern. Dazu geht wählt man im Plot-Fenster unten rechts die Option EXPORT und wählt das gewünschte Dateiformat aus, z. B. png oder pdf. Für die Weiterverwendung in Office-Programmen (z. B. Word oder Powerpoint) ist das Format Windows Metafile besonders geeignet. Geschickter ist es aber, Diagramme mithilfe einer Funktion zu exportieren, denn dann wird der Export beim Durchlaufen des Skripts durchgeführt und muss nicht jedes Mal per Hand ausgeführt werden. Das Exportieren eines Diagramms erfolgt immer in drei Schritten, die immer in exakt dieser Reihenfolge ausgeführt werden müssen und im Skript in dieser Reihenfolge erscheinen sollten. Starten des Exports. Durch Ausführen des Export-Befehls wird eine Umleitung eingerichtet, d. h., alle nun erzeugten Diagramme werden direkt in eine externe Datei umgeleitet. Dazu stehen verschiedene Export-Funktionen zur Auswahl, deren Namen jeweils dem gewünschten Dateiformat entsprechen (z. B. pdf für pdf-Dateien, png für png-Dateien, tiff für tiff-Dateien und win.metafile für Windows Metafile). Innerhalb der Funktion wird der gewünschte Dateiname einschließlich der Dateiendung (z. B. "Mein Diagramm.pdf") angegeben. Diagramm-Befehl. Wir führen nun wie gewohnt den oder die Befehle zur Erstellung des Diagramms aus. Da wir aber eine Umleitung eingerichtet haben, wird
22.4
Kommentierte Ausgaben mit R Markdown erstellen
das Diagramm nicht in RStudio angezeigt, sondern direkt in die Datei umgeleitet. Beenden des Exports. Am Ende muss der Befehl dev.off() ausgeführt werden. Dadurch wird die Umleitung beendet. Solange wir diesen Befehl nicht ausgeführt haben, wird die externe Datei von RStudio verwendet und kann nicht von uns geöffnet werden. In diesem Beispiel wird ein Boxplot erstellt und als pdf-Datei gespeichert: > pdf("Boxplot.pdf") > boxplot(erstis$lz.1) > dev.off()
Die meisten Dateiformate können nur ein einziges Diagramm darstellen, daher muss der dev.off-Befehl ausgeführt werden, sobald ein Diagramm erstellt wurde. Dies ist anders für pdf-Dateien. Hier kann man beliebig viele Diagramme in die pdf-Datei umleiten, bevor man die Datei mit dem dev.off-Befehl schließt. Für jedes Diagramm wird in der pdf-Datei eine neue Seite angelegt. Tipp
Mit ggplot2 erstellte Diagramme lassen sich auch mit der ggsave-Funktion exportieren. Diese Funktion exportiert immer das zuletzt erstellte Diagramm.
22.4 Kommentierte Ausgaben mit R Markdown erstellen Bei der Datenanalyse macht es meistens Sinn, seine Gedanken zu den Ergebnissen schriftlich festzuhalten, und zwar am besten direkt in der Datei, in der die Ergebnisse selbst gespeichert sind. Das ist in der R-Basisversion nicht ganz einfach. Hier hat man vor allem zwei Möglichkeiten: entweder die Notizen als mit # gekennzeichnete Kommentare in das Skript hineinschreiben oder die Ausgaben aus der Konsole herauskopieren und in ein kommentiertes Word-Dokument einfügen. Der erste Weg hat den Nachteil, dass man die Befehle immer wieder ausführen muss, um aus seinen Kommentaren schlau zu werden. Zudem erzeugt man dann häufig sehr viele Kommentare, die schnell unübersichtlich werden. Und einen Preis für das schönste Layout werden die Skript-Dateien auch nicht mehr gewinnen. Der zweite Weg hat den Nachteil, dass er mit sehr viel Arbeit verbunden ist, da man alle Ausgaben einzeln kopieren und einfügen muss. Sollte sich etwas an den Ausgaben ändern, muss man diese Arbeit erneut machen.
349
350
22 Ausgaben exportieren
Wem diese Probleme bekannt vorkommen, der wird sich sehr über R Markdown freuen. R Markdown erlaubt es einem, Befehle, Ausgaben, Diagramme und Kommentare in einem einzigen Dokument zusammenzufügen. Dieses Dokument kann in verschiedenen Formaten ausgegeben werden, z. B. als HTML-, pdf- oder Word-Datei, und ist somit ideal, um Kooperationspartnern eine schnelle Zusammenfassung der Ergebnisse samt Diagrammen und Interpretation zukommen zu lassen. Manche Wissenschaftlerinnen und Wissenschaftler schreiben sogar ihre Fachartikel und ganze Dissertationen in R Markdown. Die Erstellung eines R Markdown-Dokuments erfolgt in drei Schritten: (1) Erstellen der R Markdown-Datei, (2) Eingabe von Text und Einbetten von R-Befehlen, (3) umwandeln (»rendern«) in die Ausgabe-Datei. R Markdown-Datei erstellen In RStudio erstellen wir eine R Markdown-Datei über die Menüoption FILE → NEW FILE → R MARKDOWN . R Markdown-Dateien erhalten die Dateiendung .rmd. Text eingeben Nun kann man drauflos schreiben. Ohne weitere Informationen eingegebener Text wird später in der Standardschriftart dargestellt. Überschriften beginnen mit dem Symbol #, wobei die Anzahl der Symbole die Überschriftenebene kennzeichnet (z. B. kennzeichnet ### eine Überschrift der 3. Ebene). Um einzelne Wörter hervorzuheben, kann man sie auf die folgende Art *kursiv* oder **fett** drucken. Die Markdown Quick Reference enthält Informationen zu weiteren Formatierungen. Diese Datei findet man in RStudio unter dem Fragezeichen-Symbol oder online unter http://rmarkdown.rstudio.com/. R-Befehle einbetten R-Befehle werden folgendermaßen eingebettet: ```{r} desk here("Daten", "erstis.RData")
RStudio-Projekte und relative Pfade funktionieren auch dann einwandfrei, wenn man die Ordner an eine andere Stelle auf dem eigenen Rechner verschiebt oder auf einem anderen Computer öffnet.
23.3 Aufbau eines R-Skripts Die wichtigsten Dateien überhaupt sind – neben Ihren Rohdaten – die Skript-Dateien. Mit sauber angelegten Skript-Dateien können Sie Ihre Analysen jederzeit reproduzieren. Damit die Skript-Dateien nicht zu unübersichtlich werden, sollten Sie für jeden Schritt in der Datenaufbereitung und Datenauswertung ein eigenes Skript anlegen. Jedes Skript sollte dabei eigenständig funktionieren, d. h., jedes Skript sollte alle Befehle enthalten, mit denen man die erforderlichen Daten und Pakete lädt. Laden Sie alle erforderlichen Daten und Pakete direkt am Anfang des Skripts. Um zu testen, ob ein Skript eigenständig funktioniert, öffnen Sie RStudio noch einmal neu (z. B. mit der Tastenkombination STRG + SHIFT + F10 auf Windows bzw. CMD + SHIFT + F10 auf Mac) und lassen Sie alle Befehle von oben nach unten durchlaufen. Um eine Skript-Datei zu strukturieren, können Sie Überschriften verwenden. In RStudio werden Kommentare automatisch als Überschriften interpretiert, wenn Sie mit vier Rauten (####) oder vier Bindestrichen (----) enden. Mit der Tastenkombination STRG + SHIFT + O (Windows) bzw. CMD + SHIFT + O (Mac) können Sie im Skript-Fenster eine Navigationsleiste öffnen, in der Sie einzelne Überschriften anklicken und dann direkt an die entsprechende Stelle springen können.
Powered by TCPDF (www.tcpdf.org)
24.1
24
Typische Tippfehler
Troubleshooting
Fehler gehören zum Leben dazu, und besonders zum Arbeiten mit R. Gerade beim Einstieg kann es aber frustrierend sein, wenn Befehle fast nie auf Anhieb funktionieren. Das ist aber ganz normal und passiert selbst R-Profis regelmäßig. Der Unterschied ist natürlich, dass R-Profis die Fehlerquelle wesentlich schneller entdecken und beheben. In diesem Kapitel besprechen wir typische Tippfehler (Abschn. 24.1) und häufige Fehlermeldungen (Abschn. 24.2) und wie man allgemein bei der Fehlersuche vorgehen kann (Abschn. 24.3). Außerdem gehen wir darauf ein, wie man RSkripte mit seltsamen Sonderzeichen lesbar machen kann (Abschn. 24.4).
24.1 Typische Tippfehler Bei Einsteigern lassen sich fast alle Fehlermeldungen auf Tippfehler zurückführen. Hier sind die häufigsten: Namen von Funktionen, Objekten oder Variablen wurden falsch eingegeben. Groß- und Kleinschreibung wurde nicht beachtet. Anführungszeichen oder Klammern wurden nicht oder zu häufig geschlossen. Das passiert besonders gerne bei langen, verschachtelten Befehlen. Man sollte daher zu verschachtelte Befehle vermeiden. Objektnamen wurden in Anführungszeichen gesetzt. Symbole wie Anführungszeichen oder Bindestriche wurden falsch formatiert eingegeben. Das passiert besonders gerne, wenn wir R-Befehle aus fremden Dokumenten kopieren, z. B. aus einer pdf-Datei. Dann kann es passieren, dass einfache Symbole automatisch umformatiert werden (z. B. " " in „ “). Anführungszeichen wurden vergessen. Alle Texteingaben, die sich nicht auf Funktionen, Pakete oder Objekte beziehen, müssen in Anführungszeichen gesetzt werden. Das Komma zwischen den Argumenten wurde vergessen, besonders bei langen Befehlen, die über mehrere Zeilen gehen.
355
356
24 Troubleshooting
24.2 Häufige Fehlermeldungen Fehlermeldungen in R sind berüchtigt. Die meisten Fehlermeldungen verwenden eine sehr technische Sprache, die es gerade Einsteigern erschwert, den Fehler überhaupt zu verstehen. Hier sind ein paar Formulierungen, die in vielen Fehlermeldungen verwendet werden, sowie ein paar erste Lösungsansätze: Could not find function. Prüfen Sie, ob Sie das Paket geladen haben, das die Funktion enthält und ob Sie den Namen der Funktion korrekt geschrieben haben. Cannot open. Diese Fehlermeldung erscheint häufig, wenn man versucht, auf externe Dateien zuzugreifen. Prüfen Sie, ob die Datei wirklich im aktuellen Arbeitsverzeichnis enthalten ist, z. B. mit den Funktionen getwd() und dir(). Haben Sie den Dateinamen richtig geschrieben? Haben Sie an die Dateiendung gedacht? Error in eval. Wenn Sie das lesen, versuchen Sie eine Funktion auf ein Objekt anzuwenden, das es gar nicht gibt. Prüfen Sie, ob Sie das Objekt wirklich geladen und den Namen korrekt geschrieben haben. Subscript out of bounds. Diese Fehlermeldung erhalten Sie dann, wenn Sie die Index-Funktion inkorrekt verwendet haben. Prüfen Sie, ob die innerhalb der eckigen Klammern angegeben Zeilen oder Spalten überhaupt im Objekt existieren. Vielleicht haben Sie Zeilen und Spalten verwechselt? Error: unexpected …. Diese Fehlermeldung wird immer dann ausgegeben, wenn ein Symbol oder ein Objekttyp verwendet wird, der an dieser Stelle im Befehl eigentlich nichts zu suchen hat.
24.3 Vorgehen bei der Fehlersuche Gerade bei längeren Befehlen ist oft unklar, wo genau der Fehler aufgetreten ist. Die folgenden Tipps können das Vorgehen bei der Fehlersuche strukturieren. Wenn Sie mehrere Befehle ineinander verschachtelt haben, führen Sie zunächst den innersten Befehl aus und arbeiten Sie sich dann Stück für Stück weiter nach außen. So können Sie besser erkennen, an welcher Stelle der Fehler auftritt. Bei Befehlen mit vielen Argumenten können Sie einzelne Argumente probehalber weglassen, um zu testen, ob das jeweilige Argument für die Fehlermeldung verantwortlich ist. Formatieren Sie dafür den Befehl so, dass jedes Argument in einer eigenen Zeile steht. Setzen Sie das #-Zeichen vor das Argument, das Sie weglassen möchten. Damit wird die Zeile mit dem fraglichen Argument als Kommentar gewertet und nicht ausgeführt. Um das Argument wieder zuzulassen, löschen Sie einfach das #-Zeichen.
24.4
Probleme mit der Darstellung von R-Skripten
In vielen Fehlermeldungen wird der ausgeführte R-Befehl abgedruckt, und zwar genau bis zu der Stelle, an der das Problem aufgetreten ist. Lesen Sie sich also die Fehlermeldung genau durch und prüfen Sie dann die Stelle in Ihrem R-Befehl, an der R aufgegeben hat.
24.4 Probleme mit der Darstellung von R-Skripten Wenn Sie R-Skripte öffnen, die an einem anderen Computer erstellt wurden, kann es manchmal vorkommen, dass Sonderzeichen wie ä oder ü seltsam dargestellt werden. Das liegt daran, dass auf dem anderen Computer eine andere Encodierung für Sonderzeichen verwendet wurde als auf Ihrem Computer. Dieses Problem können Sie lösen, indem Sie die Skript-Datei zunächst normal in RStudio öffnen und anschließend über die Menüoption FILE → REOPEN WITH ENCODING wählen und hier die korrekte Encodierung auswählen.
Powered by TCPDF (www.tcpdf.org)
357
358
Anhang A: Datensätze
Anhang A: Datensätze
Die in diesem Lehrbuch verwendeten Datensätze stehen auf der begleitenden Internetseite www.beltz.de/r-fuer-einsteiger zur Verfügung. Dort finden Sie auch detaillierte Beschreibungen und Codebooks der einzelnen Datensätze. Bigfive Diese Daten wurden 2001 im Rahmen eines DFG-Projekts erhoben (Eid et al., 2004). Sie enthalten die Antworten auf 20 Items zur Messung der Big-Five-Persönlichkeitsvariablen. Wir verwenden diese Daten in Kapitel 18 für die Durchführung von exploratorischen Faktorenanalysen und Itemanalysen. Erstis Diese Daten wurden im Wintersemester 2008/2009 sowie im Sommersemester 2009 von Psychologie-Studierenden im ersten Semester an der Freien Universität Berlin erhoben. Die meisten Datenbeispiele und Übungen in diesem Buch beziehen sich auf diese Daten. Haustier In diesen simulierten Daten werden drei Gruppen von Haustierbesitzern (Hunde, Katzen- und Pferdebesitzer) bezüglich Wohlbefinden, Einkommen und Neurotizismus verglichen. Wir analysieren diese Daten in Kapitel 13 mit einer einfaktoriellen Varianzanalyse sowie in Kapitel 16 mit speziellen Regressionsmodellen. Kultur Diese Daten stammen aus dem International College Survey 2001, an dem 10 018 Studierende aus 48 Ländern teilnahmen (z. B. Lischetzke et al., 2012). Für unsere Datenbeispiele wurde der Datensatz auf 40 Länder und einige wenige Variablen zum Wohlbefinden reduziert. Diese Daten haben eine Mehrebenenstruktur und werden in Kapitel 20 mit Mehrebenenmodellen analysiert. Minidaten Drei kleine, künstliche Datensätze zur Veranschaulichung der Datenaufbereitung in Kapitel 7.
Anhang A: Datensätze
Prüfung In diesen Daten wurde das Befinden von Studierenden am Abend vor, während und nach einer wichtigen Prüfung erfasst. Es handelt sich um Längsschnittdaten, die im Long-Format strukturiert sind. Wir analysieren diese Daten in Kapitel 14 mit Varianzanalysen mit Messwiederholung. Samstag Simulierte Daten zum Ausgehverhalten am Samstagabend. Diese Daten analysieren wir in Kapitel 16 mit einer logistischen Regression. Textdaten_komma und Textdaten_semikolon Kleine, übersichtliche Datensätze zur Veranschaulichung des Datenimports in Kapitel 6. Beide Dateien sind csv-Dateien mit denselben Daten, wurden aber mit unterschiedlichen Einstellungen (Datenfeldtrennzeichen, Dezimaltrennzeichen) gespeichert. Therapie Simulierte Daten einer fiktiven klinischen Studie, in der die Wirksamkeit einer Therapie gegen Höhenangst evaluiert wurde. Wir analysieren diese Daten in Kapitel 13 mit einer zweifaktoriellen Varianzanalyse. Vpn Übersichtlicher, künstlicher Datensatz zur Veranschaulichung der grundlegenden klassischen Grafik-Funktionen und der grundlegenden ggplot2-Funktionen in Kapitel 10.
Powered by TCPDF (www.tcpdf.org)
359
360
Anhang B: Pakete
Anhang B: Pakete
In diesem Buch verwendete Pakete Eine vollständige Liste der in diesem Buch verwendeten Funktionen und Pakete können Sie auf der begleitenden Internetseite www.beltz.de/r-fuer-einsteiger herunterladen. Pakete für komplexere Analysen Dieses Buch ist für Einsteiger konzipiert, daher können und sollen komplexere Verfahren nicht im Detail behandelt werden. Tabelle B.1 enthält einige Pakete, mit denen man komplexere Verfahren durchführen kann. Weitere Informationen zu den Paketen und den einzelnen Informationen findet man in den jeweiligen Hilfe-Dateien. Tabelle B.1 Pakete für komplexere statistische Verfahren
Powered by TCPDF (www.tcpdf.org)
Verfahren
Pakete
Beurteilerübereinstimmung
irr, psychometric, psych, s. Task View zum Thema »Psychometric Models and Methods«
Clusteranalyse
cluster, kmeans, pam, s. Task View zum Thema »Cluster Analysis & Finite Mixture Models«
Imputation fehlender Werte
mice, mix, pan, mice, s. Task View zum Thema »Missing Data«
Item Response Theory
eRm, ltm, mirt, s. Task View zum Thema »Psychometric Models and Methods«
Klassische Testtheorie
psych, CTT, psychometric, itemanalysis, s. Task View zum Thema »Psychometric Models and Methods«
Metaanalyse
metafor, meta, s. Task View zum Thema »MetaAnalysis«
Robuste Verfahren
robust, robustbase, quantreg, s. Task View zum Thema »Robust Statistical Methods«
Maschinelles Lernen
randomForest, lasso2, s. Task View zum Thema »Machine Learning & Statistical Learning«
Bayesianische Verfahren
BayesFactor, arm, blavaan, brms, s. Task View zum Thema »Bayesian Inference«
Hinweise zum Online-Material
Hinweise zum Online-Material
Auf der Internetseite www.beltz.de/r-fuer-einsteiger finden Sie eine Reihe von Zusatzmaterialien, die Sie bei der Arbeit mit R unterstützen sollen.
Datensätze für die Beispiele und Übungsaufgaben in diesem Buch Lösungen zu den Übungsaufgaben Links zu wichtigen Webseiten wie CRAN, R-Seek usw. Übersicht mit den wichtigsten Funktionen zum Ausdrucken Liste aller Pakete, die in diesem Buch verwendet werden
Powered by TCPDF (www.tcpdf.org)
361
362
Literatur
Literatur
Einige weiterführende Bücher Chang, W. (2013). R graphics cookbook. Sebastopol: O’Reilly. Field, A. P., Miles, J. N. V. & Field, Z. C. (2012). Discovering statistics using R. London: Sage publications. Sauer, S. (2019). Moderne Datenanalyse mit R. Wiesbaden: Springer. Wickham & Grolemund (2017). R for Data Science. Sebastopol: O’Reilly.
Zitierte Literatur Aberson. C. (2019). pwr2ppl: Power analyses for common designs (Power to the People). R package version 0.1.1, https://CRAN.R-project.org/package=pwr2ppl Adler, D., & Kelly, S. T. (2019). vioplot: violin plot. R package version 0.3.4, https://github.com/TomKellyGenetics/vioplot Arnold, J. (2019). ggthemes: Extra themes, scales and geoms for 'ggplot2'. R package version 4.2.0, https://CRAN.R-project.org/package=ggthemes Aust, F. & Barth, M. (2020). papaja: Prepare reproducible APA journal articles with R Markdown. R package version 0.1.0.9942, https://github.com/crsh/papaja Bates, D., Mächler, M., Bolker, B. & Walker S (2015). Fitting linear mixed-effects models using lme4. Journal of Statistical Software, 67(1), 1-48. https://doi.org/10.18637/jss.v067.i01 Bhalla, D. (2016). Companies using R. https://www.listendata.com/2016/12/companies-usingr.html Bürkner, P. (2017). brms: An R package for Bayesian multilevel models using stan. Journal of Statistical Software, 80(1), 1-28. https://doi.org/10.18637/jss.v080.i01 Bürkner, P. (2018). Advanced Bayesian multilevel modeling with the R package brms. The R Journal, 10(1), 395-411. https://doi.org/10.32614/RJ-2018-017 Caldwell, A., & Lakens, D. (2019). Power analysis with Superpower. Self published on GitHub, https://arcaldwell49.github.io/SuperpowerBook Champely, S. (2020). pwr: Basic functions for power analysis. R package version 1.3-0, https://CRAN.R-project.org/package=pwr Chang, W. (2013). R graphics cookbook. Sebastopol: O’Reilly. Clarke, E. & Sherrill-Mix, S. (2017). ggbeeswarm: categorical scatter (violin point) plots. R package version 0.6.0, https://CRAN.R-project.org/package=ggbeeswarm Cohen, J. (1988). Statistical power analysis for the social sciences. Mahwah, NJ: Erlbaum. Dataflair Team (2019). Why choose R for data science. https://data-flair.training/blogs/using-rfor-data-science/ Diener, E., Emmons, R. A., Larsen, R. J. & Griffin, S. (1985). The Satisfaction With Life Scale. Journal of Personality Assessment, 49(1), 71-75. https://doi.org/10.1207/s15327752jpa4901_13 Dragulescu, A. & Arendt, C. (2020). xlsx: Read, write, format Excel 2007 and Excel 97/2000/XP/2003 files. R package version 0.6.3, https://CRAN.R-project.org/package=xlsx Eid, M., Gollwitzer, M. & Schmitt, M. (2017). Statistik und Forschungsmethoden (5. Auflage). Weinheim: Beltz. Eid, M., Lischetzke, T., Nussbeck, F. & Geiser, G. (2004). Die Multitrait-Multimethod-Analyse: Entwicklung neuer Modelle und ihre Anwendung in der Differentiellen und Diagnostischen Psychologie. Unveröffentlichter Abschlussbericht zum DFG-Projekt Ei 379/5-2.
Literatur Enders, C. K. & Tofighi, D. (2007). Centering predictor variables in cross-sectional multilevel models: A new look at an old issue. Psychological Methods, 12(2), 121-138. https://doi.org/10.1037/1082-989X.12.2.121 Epskamp, S. (2019). semPlot: Path diagrams and visual analysis of various SEM packages' output. R package version 1.1.2, https://CRAN.R-project.org/package=semPlot Fabrigar, L. R., Wegener, D. T., MacCallum, R. C. & Strahan, E. J. (1999). Evaluating the use of exploratory factor analysis in psychological research. Psychological Methods, 4, 272-299. https://doi.org/10.1037/1082-989X.4.3.272 Field, A. P., Miles, J. N. V. & Field, Z. C. (2012). Discovering statistics using R. London: Sage publications. Fox, J., & Weisberg, S. (2019). An R companion to applied regression, Third edition. Sage, Thousand Oaks CA. https://socialsciences.mcmaster.ca/jfox/Books/Companion/ Funder, D. C. & Ozer, D. J. (2019). Evaluating effect size in psychological research: Sense and nonsense. Advances in Methods and Practices in Psychological Research. Advance online publication. https://doi.org/10.1177/2F2515245919847202 Gibbons, R. D., Hedeker, D. R., & Davis, J. M. (1993). Estimation of effect size from a series of experiments involving paired comparisons. Journal of Educational Statistics, 18, 271-279. https://doi.org/10.3102/10769986018003271 Goldberg, L. R. (2006). Doing it all bass-ackwards: The development of hierarchical factor structures from the top down. Journal of Research in Personality, 40(4), 347-358. https://doi.org/10.1016/j.jrp.2006.01.001 Goretzko, D., Pham, T.T.H. & Bühner, M. (2019). Exploratory factor analysis: Current use, methodological developments and recommendations for good practice. Current Psychology (2019). https://doi.org/10.1007/s12144-019-00300-2 Green, P., & MacLeod, C. J. (2016). simr: an R package for power analysis of generalised linear mixed models by simulation. Methods in Ecology and Evolution, 7(4), 493-498. https://doi.org/10.1111/2041-210X.12504, https://CRAN.R-project.org/package=simr Gross, J., & Ligges, U. (2015). nortest: Tests for normality. R package version 1.0-4, https://CRAN.R-project.org/package=nortest Hale, S., Bright, J., & Blank, G. (2017). oii: Crosstab and statistical tests for OII MSc stats course. R package version 1.0.2.1, https://CRAN.R-project.org/package=oii Iannone, R., Cheng, J., & Schloerke, B. (2020). gt: Easily create presentation-ready display tables. R package version 0.2.0.5, https://CRAN.R-project.org/package=gt Jorgensen, T. D., Pornprasertmanit, S., Schoemann, A. M., & Rosseel, Y. (2019). semTools: Useful tools for structural equation modeling. R package version 0.5-2, https://CRAN.R-project.org/package=semTools Kassambara, A. (2019). ggcorrplot: Visualization of a correlation matrix using 'ggplot2'. R package version 0.1.3, https://CRAN.R-project.org/package=ggcorrplot Kelley, K. & Rausch, J. R. (2006). Sample size planning for the standardized mean difference: Accuracy in Parameter Estimation via narrow confidence intervals. Psychological Methods, 11(4), 363-385. https://doi.org/10.1037/1082-989X.11.4.363 Kelley, K. (2019). MBESS: The MBESS R package. R package version 4.6.0, https://CRAN.R-project.org/package=MBESS Kim, S. (2015). ppcor: Partial and semi-partial (part) correlation. R package version 1.1, https://CRAN.R-project.org/package=ppcor Kleiman, E. (2017). EMAtools: Data management tools for real-time monitoring/ecological momentary assessment data. R package version 0.1.3, https://CRAN.R-project.org/package=EMAtools Knowles, J. E., & Frederick, C. (2019). merTools: Tools for analyzing mixed effect regression models. R package version 0.5.0, https://CRAN.R-project.org/package=merTools
363
364
Literatur Kuznetsova, A., Brockhoff, P. B., & Christensen, R. H. B. (2017). lmerTest Package: Tests in linear mixed effects models. Journal of Statistical Software, 82(13), 1-26. https://doi.org/10.18637/jss.v082.i13. Lawrence, M. A. (2016). ez: Easy analysis and visualization of factorial experiments. R package version 4.4-0, https://CRAN.R-project.org/package=ez Lenth, R. (2019). emmeans: Estimated marginal means, aka least-squares means. R package version 1.4.3.01, https://CRAN.R-project.org/package=emmeans Lischetzke, T., Eid, M. & Diener, E. (2012). Perceiving one's own and others' feelings around the world: The relations of attention to and clarity of feelings with subjective well-being across nations. Journal of Cross-Cultural Psychology, 43(8), 1249-1267. Lishinski, A. (2018). lavaanPlot: Path diagrams for lavaan models via diagrammeR. R package version 0.5.1, https://CRAN.R-project.org/package=lavaanPlot Long, J. A. (2019a). interactions: Comprehensive, user-friendly toolkit for probing interactions. R package version 1.1.0, https://cran.r-project.org/package=interactions Long, J. A. (2019b). jtools: Analysis and presentation of social scientific data. R package version 2.0.1, https://cran.r-project.org/package=jtools Lüdecke, D. (2020a). sjPlot: Data visualization for statistics in social science. https://doi.org/10.5281/zenodo.1308157, R package version 2.8.3, https://CRAN.R-project.org/package=sjPlot Lüdecke, D. (2020b). sjstats: Statistical functions for regression models (Version 0.18.0). https://doi.org/10.5281/zenodo.1284472, https://CRAN.R-project.org/package=sjstats Magnusson, K. (2018). powerlmm: Power analysis for longitudinal multilevel models. R package version 0.4.0, https://CRAN.R-project.org/package=powerlmm Makowski, D., Ben-Shachar, M., & Lüdecke, D. (2019). Compute and interpret indices of effect size. CRAN. R package, https://github.com/easystats/effectsize Martin, J., Nussey, D., Wilson, A., & Reale, D. (2011). Measuring individual differences in reaction norms in field and experimental studies: a power analysis of random regression models. Methods in Ecology and Evolution, 2(4), 362-374. http://onlinelibrary.wiley.com/doi/10.1111/j.2041-210X.2010.00084.x/abstract Merkle, E. C., & Rosseel, Y. (2018). blavaan: Bayesian structural equation models via parameter expansion. Journal of Statistical Software, 85(4), 1-30. https://doi.org/10.18637/jss.v085.i04. Meyer, D., Zeileis, A., & Hornik, K. (2020). vcd: Visualizing categorical data. R package version 1.4-7. https://CRAN.R-project.org/package=vcd Morris, S. B., & DeShon, R. P. (2002). Combining effect size estimates in meta-analysis with repeated measures and independent-groups designs. Psychological Methods, 7(1), 105. https://doi.org/10.1037/1082-989X.7.1.105 Müller, K. (2017). here: A simpler way to find your files. R package version 0.1, https://CRAN.Rproject.org/package=here Neuwirth, E. (2014). RColorBrewer: ColorBrewer palettes. R package version 1.1-2, https://CRAN.R-project.org/package=RColorBrewer Pedersen, T. (2019). patchwork: The composer of plots. R package version 1.0.0, https://CRAN.Rproject.org/package=patchwork Phillips, N. (2017). yarrr: A companion to the e-book "YaRrr!: The Pirate's Guide to R". R package version 0.1.5, https://CRAN.R-project.org/package=yarrr Pinheiro, J., Bates, D., DebRoy, S., Sarkar, D., & R Core Team (2019). nlme: Linear and nonlinear mixed effects models. R package version 3.1-142, https://CRAN.R-project.org/package=nlme Preacher, K. J. (2015). Advances in mediation analysis: A survey and synthesis of new developments. Annual Review of Psychology, 66, 825-852. https://doi.org/10.1146/annurev-psych010814-015258 R Core Team (2019a). foreign: Read data stored by 'Minitab', 'S', 'SAS', 'SPSS', 'Stata', 'Systat', 'Weka', 'dBase', .... R package version 0.8-72, https://CRAN.R-project.org/package=foreign
Literatur R Core Team (2019b). R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. https://www.R-project.org/. Revelle, W. (2019). psych: Procedures for psychological, psychometric, and personality research. Northwestern University, Evanston, Illinois. R package version 1.9.12, https://CRAN.R-project.org/package=psych Rosseel, Y. (2012). lavaan: An R package for structural equation modeling. Journal of Statistical Software, 48(2), 1-36. http://www.jstatsoft.org/v48/i02/ RStudio Team (2019). RStudio: Integrated Development for R. RStudio, Inc., Boston, MA URL http://www.rstudio.com/. Sarkar, D. (2008). Lattice: Multivariate data visualization with R. Springer, New York. ISBN 9780-387-75968-5, http://lmdvr.r-forge.r-project.org Sauer, S. (2019). Moderne Datenanalyse mit R. Wiesbaden: Springer. Schönbrodt, F., Gollwitzer, M., & Abele-Brehm, A. (2017). Der Umgang mit Forschungsdaten im Fach Psychologie: Konkretisierung der DFG-Leitlinien. Psychologische Rundschau, 68, 20-35. https://doi.org/10.1026/0033-3042/a000341 Singmann, H., Bolker, B., Westfall, J., Aust, F., & Ben-Shachar, M. (2020). afex: Analysis of factorial experiments. R package version 0.27-2, https://CRAN.R-project.org/package=afex Stanley, D. (2018). apaTables: Create American Psychological Association (APA) style tables. R package version 2.0.5, https://CRAN.R-project.org/package=apaTables Torchiano, M. (2020). effsize: Efficient effect size computation. doi: 10.5281/zenodo.1480624 (URL: https://doi.org/10.5281/zenodo.1480624), R package version 0.7.8, https://CRAN.Rproject.org/package=effsize Wang, Y. A., & Rhemtulla, M. (2020). Power analysis for parameter estimation in structural equation modeling: A discussion and tutorial. Advances in Methods and Practices in Psychological Science. Advance online publication. ShinyApp: https://yilinandrewang.shinyapps.io/pwrSEM/ Wickham & Grolemund (2017). R for Data Science. Sebastopol: O’Reilly. Wickham, H. (2011). The split-apply-combine strategy for data analysis. Journal of Statistical Software, 40(1), 1-29. Wickham, H. (2016). ggplot2: Elegant graphics for data analysis. Springer-Verlag New York. ISBN 978-3-319-24277-4, https://ggplot2.tidyverse.org Wickham, H., & Henry, L. (2019). tidyr: Tidy messy data. R package version 1.0.0, https://CRAN.R-project.org/package=tidyr Wickham, H., & Miller, E. (2019). haven: Import and export 'SPSS', 'Stata' and 'SAS' files. R package version 2.2.0, https://CRAN.R-project.org/package=haven Wickham, H., François, R., Henry, L., & Müller, K. (2020). dplyr: A grammar of data manipulation. R package version 0.8.5, https://CRAN.R-project.org/package=dplyr Wickham, H., Hester, J., & François, R. (2018). readr: Read rectangular text data. R package version 1.3.1, https://CRAN.R-project.org/package=readr Wright, K. (2018). corrgram: Plot a correlogram. R package version 1.13, https://CRAN.R-project.org/package=corrgram Xie, Y. (2020). knitr: A general-purpose package for dynamic report generation in R. R package version 1.28, https://yihui.org/knitr/ Zhu, H. (2019). kableExtra: Construct complex table with 'kable' and pipe syntax. R package version 1.1.0, https://CRAN.R-project.org/package=kableExtra
365
366
Literatur
Zitierte Webseiten http://cran.r-project.org http://cran.r-project.org/web/packages http://cran.r-project.org/web/views/Robust.html http://lavaan.ugent.be http://methods-berlin.com/de/r-lernplattform/ http://rmarkdown.rstudio.com http://www.beltz.de/r-fuer-einsteiger http://www.personality-project.org/R/R.guide.html http://www.r-project.org http://www.rseek.org http://www.rstudio.com/ide http://www.statmethods.net http://xquartz.macosforge.org https://community.rstudio.com https://cran.r-project.org/bin/macosx/ https://osf.io/ https://rstudio.com/resources/cheatsheets https://stackoverflow.com https://style.tidyverse.org https://support.rstudio.com https://www.facebook.com/groups/346735129027556 https://www.rdocumentation.org https://www.tidyverse.org
Powered by TCPDF (www.tcpdf.org)
Sachwortverzeichnis
Sachwortverzeichnis
# 43 η² Siehe eta² χ²-Test Siehe chi²-Test χ²-Verteilung Siehe chi²-Verteilung ω-Koeffizient Siehe omegaKoeffizient $ 54 ? 33, 35, 41 ?? 33, 35 [ ] 55 [[ ]] 56 ~ 171 20 Abfrage, logische 37, 83 abline() 149, 176 abs() 36 Absoluter Wert 36 Addieren 36 addmargins() 127, 128, 135 Adjustierte Mittelwerte 262 aes() 150, 181 afex_plot() 180, 209, 217, 219, 227, 235, 237 afex-Paket 174, 205, 209, 213, 217, 222, 227, 230, 235 AIC Siehe Akaikes Information Criterion AIC() 248 Akaikes Information Criterion 248, 280, 321, 332 Allgemeines lineares Modell 256 alpha() 305, 308 ANCOVA Siehe Kovarianzanalyse
Anführungszeichen 47 annotate() 157 ANOVA s. Varianzanalyse 204 anova() 247, 254, 282, 284, 321, 325, 341 Anova() 265, 267, 282, 283, 333, 341 anova_stats() 215 aov_car() 205, 213, 219, 222, 230, 237 apaTables-Paket 348 Approximative Freiheitsgrade 333 Arbeitsverzeichnis 58, 353 Argument 38 arrange() 96, 110 arrows() 149, 174 as.data.frame() 52 as.numeric() 79, 109, 264 as_tibble() 52, 53 ASCII-Format, festes 68 association.measures() 135 Ausreißer 251, 252 axis() 149 barplot() 159, 180 Bartlett-Test 294 Bass Ackwards-Methode 299 bassAckward() 299 Bayesian Information Criterion 297, 321, 332 Bayesianische Verfahren 360 Mehrebenenanalyse 328 Strukturgleichungsmodelle 325 Bedingte Regressionsgleichungen 269, 339
367
368
Sachwortverzeichnis
Betrag 36 Beurteilerübereinstimmung 360 BIC Siehe Bayesian Information Criterion bind_rows() 98, 110 Binomial-Verteilung 183 biserial() 135 blavaan-Paket 325 Bootstrapping 315 Boxplot 138, 171 boxplot() 171, 180 brms-Paket 328 c() 39, 53, 61 car-Paket 195, 252, 254, 265, 267, 333 cbind() 53, 61, 116 cfa() 317, 321, 325 CFI 319 Cheatsheets 34, 40 chi²-Test Anpassungstest 285 Devianzentest 332, 336 Exploratorische Faktorenanalyse 302 Konfirmatorische Faktorenanalyse 318 Likelihood-Ratio-Test 320 Logistische Regressionsanalyse 282 Mehrebenenanalyse 332, 336 Poweranalyse 343 zweidimensional 286 chi²-Verteilung 183 chisq.test() 286, 287, 293 class() 53, 61, 67 Clusteranalyse 360 coef() 281 cohen.d() 193, 198, 201, 202 Cohens d 192, 198, 201
colors() 143 colSums() 135 confint() 243, 254 contr.helmert() 258 contr.poly() 258 contr.sum() 258 contr.treatment() 258 contrasts() 257, 258, 283 Cook’s Distance 251, 252 cooks.distance() 252 cor() 129, 135, 200 cor.plot() 295 cor.test() 132, 135 corr.test() 130, 135 corrgram-Paket 295 cortest.bartlett() 295 cov() 134, 135 CRAN 17 Cronbach’s α 305 Cross-Level-Interaktion 339 csv-Datei exportieren 346, 347 importieren 64 cumsum() 124 curve() 184 Data Frames 50 betrachten 68 exportieren 346 Fälle hinzufügen 97 reduzieren 89 sortieren 95 speichern 59, 69, 346 umstrukturieren 101 umstrukturieren von Long zu Wide 106 umstrukturieren von Wide zu Long 102 Variablen hinzufügen 99 zusammenfügen 97
Sachwortverzeichnis
data.frame() 50, 53, 61, 90, 129 Dateienstruktur 353 Dateipfad 353 Daten betrachten 68 exportieren 346 speichern 58, 69 Datenaufbereitung 71 Datenfeldtrennzeichen 63, 68 Datenstruktur 101, 221 Long-Format 105 Ultralong-Format 103 Wide-Format 106 Datenvisualisierung Siehe Diagramme density() 165, 180 desc() 96, 110 describe() 42, 118, 124, 189, 199, 289 describeBy() 122, 124, 174, 194, 204, 212, 219, 222, 229, 237, 290, 292 Deskriptive Kennwerte 117 Exzess 118 Getrimmter Mittelwert 118 Gruppenvergleiche 122 Maximum 118 Median 118 Median Absolute Deviation 118 Minimum 118 Mittelwert 118 Modalwert 120 Quantile 121 Quartile 121 Range 118 Schiefe 118 Standardabweichung 118 Standardfehler 118 Deskriptive Statistik bivariat 126 univariat 113
Determinationskoeffizient 244, 246, 311 dev.off() 349, 352 Devianz 280, 332 Devianzentest 332, 336 Dezimaltrennzeichen 64 DfBETA 252 dfbeta() 252 DfBETAS 252 dfbetas() 252 DfFits 252 dffits() 252 Diagramme 137 Boxplot 138, 171 Dotplot 337 Fehlerbalkendiagramm Siehe Mittelwerts-Diagramm Histogramm 164 Index-Diagramm 138 Interaktionsdiagramm 217, 235, 269, 339 Kerndichte-Diagramm 164 Korrelogramm 295 Mittelwerts-Diagramm 174, 209, 227 Mosaik-Diagramm 138 Pfaddiagramm 324 Q-Q-Plot 251 Residuenplot 249 Säulendiagramm 138, 159 Streudiagramm 138, 174, 238, 275 Streudiagramm-Matrix 138, 178 Wahrscheinlichkeitsverteilungen 184 Diagramme anordnen ggplot2 157 klassisch 149 Diagramme bearbeiten, ggplot2 152 Achsen 155
369
370
Sachwortverzeichnis
Darstellung in Abhängigkeit von weiteren Variablen 154 Datenpunkte 153 Elemente hinzufügen 157 Farben 154 Funktionskurven 151, 185 Legende 157 Linien 153 Themen 156 Titel 157 Diagramme bearbeiten, klassisch 139 Achsen 145, 149 Darstellung in Abhängigkeit von weiteren Variablen 144 Datenpunkte 140, 149 Elemente hinzufügen 146 Farben 142 Funktionskurven 149, 184 Geraden 149 Legende 146, 149, 161, 185 Linien 142, 149 Pfeile 149 Symbole 149 Texte 149 Titel 149 Diagramme exportieren 348 Diagrammtyp festlegen ggplot2 150 klassisch 138 dim() 69, 70 dir() 58, 61 Dividieren 36 dnorm() 183 Dollarzeichen 54, 61, 245 Doppelpunkt, doppelter 41 Doppelpunkt, einfacher 91 dotplot() 337, 341 Download MacOS 18
Pakete 27 R 17 RStudio 18 Windows 17 dplyr-Paket 73, 118, 129, 162, 176, 246, 334 drop_na() 95, 110 dt() 184, 188 Dummycodierung 257, 258 Durbin-Watson-Test 254 durbinWatsonTest() 254 effectsize-Paket 193 Effektcodierung 213, 214, 257 Effektgröße η² Siehe eta² Cohen’s d 192, 198, 201 eta² 207, 215, 224, 259 Odds Ratio 280 omega² 215 R² 244, 259 Standardisierte Mittelwertsdifferenz 192, 198, 201 standardisierte Regressionskoeffizienten 240 effsize-Paket 193, 198, 201 Einfaktorielle Varianzanalyse mit Messwiederholung 222 ohne Messwiederholung 204 Einflussreiche Werte 251, 252 Einstichproben-t-Test 189 EMAtools-Paket 328 emmeans() 208, 215, 219, 226, 232, 237, 263, 283 emmeans-Paket 174, 205, 208, 210, 215, 219, 226, 231, 235, 262, 270, 339 emtrends() 270, 272, 284, 339, 341 Encodierung 24, 357
Sachwortverzeichnis
Environment 25, 47, 56 Environment-Fenster 25, 46 error.bars() 174 error.bars.by() 174 eta² 207, 215, 224, 259 exp() 36, 281 Exploratorische Faktorenanalyse Siehe Faktorenanalyse Exponentialfunktion 36 Exportieren Andere Statistik-Programme 346 csv 346, 347 Data Frames 346 Daten 346 Diagramme 348 SPSS 346 Stata 346 Tabellen 347 Textdateien 346 Exzess 118 ez-Paket 205, 231 fa() 300, 308 fa.parallel() 297, 308 facet_grid() 170, 181 factor() 49, 53, 61, 78, 109 Faktoren 49 in Vektoren konvertieren 78 Faktorenanalyse Anzahl der Faktoren 296 Bass Ackwards-Methode 299 Exploratorische 294 Hauptachsenanalyse 299 Hauptkomponentenanalyse 304 Komplexe Faktorstrukturen 304 Konfirmatorische 317 Maximum-LikelihoodFaktorenanalyse 299 Modellgüte 297, 302, 319 Parallelanalyse 297
Faktorwerte 303 Fälle auswählen 92 filtern 92 sortieren 95 FALSE 37 Fehlende Werte 87, 119 codieren 68 eingeben 67 entfernen 94 imputieren 360 listenweiser Ausschluss 130 paarweiser Ausschluss 130 Fehlerbalkendiagramm Siehe Mittelwerts-Diagramm Fehlermeldungen, häufige 356 filter() 93, 110 Filtern 92 fisher.test() 288 fitMeasures() 319, 325 fitted() 243, 254 Flächenanteile 186 foreign-Paket 68, 346 Freiheitsgrade, approximative 333 full_join() 101, 111 Fünf-Punkte-Zusammenfassung 117 Funktionen Argumente 38 Aufbau 38 Hilfe 41 F-Verteilung 183 geom_abline() 151 geom_area() 151 geom_bar() 151, 162 geom_boxplot() 151, 172 geom_curve() 151 geom_density() 151, 167 geom_dotplot() 151 geom_errorbar() 174
371
372
Sachwortverzeichnis
geom_histogram() 167 geom_jitter() 151, 239 geom_line() 151, 167 geom_point() 150, 151, 174, 177, 276 geom_qq() 151 geom_segment() 151 geom_smooth() 151 geom_step() 151 geom_violin() 151, 173 Getrimmter Mittelwert 118 getwd() 58, 61 ggbeeswarm-Paket 209 ggcorrplot-Paket 295 ggplot() 150, 181 ggplot2-Paket 150, 185, 210, 238, 271, 349 ggsave() 349 ggthemes-Paket 156 ggtitle() 157 glm() 279, 284 glmer() 327 Grafiken Siehe Diagramme Grafik-Funktionen, ggplot2 Aussehen des Diagramms ändern 152 Diagramme anordnen 157 Diagrammtyp festlegen 150 Grafik-Funktionen, klassische Aussehen des Diagramms ändern 139 Diagramme anordnen 149 Diagrammtyp festlegen 138 Grafik-Funktionen, klassische 138 Grand-mean centering 334 Greenhouse-Geisser-Korrektur 224 Groß- und Kleinschreibung 29, 44 group_by() 109, 111, 334 Group-mean centering 334 growth() 325
Gruppenvergleiche 122, 144, 154, 168, 171, 173, 174, 194, 204, 234, 256, 262, 286, 325 gt-Paket 352 Häufigkeiten absolute 113, 126 relative 114, 127 Häufigkeitstabellen drei oder mehr Variablen 128 eine Variable 113 zwei Variablen 126 Hauptachsenanalyse 299 Hauptkomponentenanalyse 304 haven-Paket 68 head() 69 Hebelwert 251 help() 32, 35, 41 help.search() 33, 35 here() 354 here-Paket 354 Hierarchische Regression 245 Hilfe zu R 31, 355 Bücher 35 Cheatsheets 34 Funktionen 41 Hilfe-Dateien 32 Internet 33 Internetforen 34 Soziale Medien 34 hist() 164, 180 Histogramm 164 Homoskedastizität 251 Huynh-Feldt-Korrektur 224 I() 277 icc() 330 ifelse() 84, 109 Importieren Andere Datenformate 68 csv-Datei 64
Sachwortverzeichnis
Datenfeldtrennzeichen 63, 68 Dezimaltrennzeichen 64 Textdatei 63 Imputation fehlender Werte 360 Index-Diagramm 138 Index-Funktion 55, 61, 91, 93 inner_join() 101, 111 install.packages() 29, 35 Installation MacOS 18 R 17 RStudio 18 Windows 17 interact_plot() 273, 284, 341 interaction_plot() 271 interactions-Paket 271, 273, 341 Interaktionsdiagramm Mehrebenenanalyse 339 Moderierte Regression 269 Varianzanalyse mit Messwiederholung 235 Varianzanalyse ohne Messwiederholung 217 Interne Konsistenz 304, 307 Intraklassenkorrelation 253, 330 IQR() 119 is.na() 87 Item Response Theory 360 Itemanalyse 304 Item-Schwierigkeit 307 johnson_neyman() 274, 284 Johnson-Neyman-Intervall 273 jpeg() 352 jtools-Paket 156, 211 kableExtra-Paket 352 Kerndichte-Diagramm 164 Klassische Testtheorie 360 knitr-Paket 352 Kollinearitätsdiagnosen 252
Kommentare 43 Konfidenzband 177, 239, 271, 273, 341 Konfidenzintervall asymmetrisch 315 Cohen's d 193 Effektgröße 193 Fehlerbalkendiagramm 174 indirekter Effekt 315 Korrelationskoeffizient 131 Mediation 315 Mittelwert 191, 192 Regressionskoeffizienten 242 Konfirmatorische Faktorenanalyse Siehe Faktorenanalyse Konsole 20 Kontingenztabellen mehrdimensionale 128 zweidimensionale 126 Kontraste 208, 215, 226, 231 Konvertieren Faktor in Vektor 79 Vektor in Faktor 78 Korrelation biseriale 135 Partialkorrelation 129 polychorische 135 polyseriale 135 Produkt-Moment-Korrelation 129 Semipartialkorrelation 129 tetrachorische 135 Korrelationsmatrix 129, 295 Korrelogramm 295 Kovarianz 133 Kovarianzanalyse 260 Kreuztabellen Siehe Kontingenztabellen Kritische Werte 186 kruskal.test() 292, 293
373
374
Sachwortverzeichnis
Kruskal-Wallis-Test 292 kurtosi() 119 Kurtosis Siehe Exzess lattice-Paket 337 lavaan-Paket 309 lavaanPlot-Paket 324 Leerzeichen 43, 45, 54, 68, 76 left_join() 101, 111 legend() 185 Legende 146, 149, 157, 161, 185 length() 49, 61 levels() 78, 109, 278 Levene-Test 195, 202 leveneTest() 195, 202 library() 29 Likelihood-Ratio-Test 281, 320 Lineare Strukturgleichungsmodelle Siehe Strukturgleichungsmodelle lines() 149, 166, 177 list() 53, 123, 212 Listen 52 Listenweiser Fallausschluss 130 lm() 176, 240, 244, 254, 283 lme4-Paket 231, 327, 328 lmer() 328, 330, 333, 338, 341 lmerTest::lmer() 341 lmerTest-Paket 333, 335 load() 60, 62 Loess-Kurve 176, 177, 239, 275 log() 36 Logarithmus, natürlicher 36 Logische Abfrage 37, 83 Logistische Regression 278 Log-normale Verteilung 183 Long-Format 101, 105, 221 lowess() 177 Lowess-Kurve Siehe Loess-Kurve Machine Learning Siehe Maschinelles Lernen
MANOVA Siehe Multivariate Varianzanalyse Markdown Siehe R Markdown Maschinelles Lernen 360 Mathematische Funktionen 36 Mathematische Operatoren 36 Matrizen 52 Mauchly-Test 224, 231 max() 119, 121 Maximum 118 Maximum Likelihood 299, 312, 328 MBESS-Paket 192, 344 mean() 39, 119 Median 118 Median Absolute Deviation 118 median() 119 Mediation 311 Mediatorvariable 311 Mehrebenenanalyse 327 Bedingte Regressionsgleichungen 339 Cross-Level-Interaktion 339 Devianzentest 332, 336 Ebene-2-Prädiktoren 338 Freiheitsgrade 333 Grafische Darstellung der festen Effekte 337 Interaktionsdiagramm 339 Intraklassenkorrelation 330 Modellvergleiche 332 Nullmodell 327 Poweranalyse 345 Prädiktoren zentrieren 334, 338 Random-Coefficient-Modell 335 Random-Intercept-Modell 330 Random-Slopes-Modell 335 Signifikanztests 332, 336 Mehrfaktorielle Varianzanalyse mit Messwiederholung 228
Sachwortverzeichnis
ohne Messwiederholung 211 merge() 100, 110 merTools-Paket 328 Messinvarianz 325 Meta-Analyse 360 metafile() 352 min() 119 Minimum 118 Mittelwert 118 Mittelwerts-Diagramm 174 mixed() 231 Modalwert 120 Modellgüte Exploratorische Faktorenanalyse 302 Exploratorische Faktorenanalyse 297 Konfirmatorische Faktorenanalyse 319 Logistische Regressionsanalyse 280 Regressionsanalyse 244, 246 Strukturgleichungsmodelle 319 Modellvergleiche hierarchische Regression 245 konfirmatorische Faktorenanalyse 320 logistische Regressionsanalyse 281 Mehrebenenanalyse 332 Strukturgleichungsmodelle 320 Moderierte Regression 263 Modifikations-Indices 319 modindices() 319, 325 Mosaik-Diagramm 138 Multikollinearität 252 Multiplizieren 36 Multivariate Varianzanalyse 225 mutate() 75, 110, 334 na.omit() 94, 110, 176, 246
na.rm 89, 119 na.rm 124 names() 61, 69, 76 Natürlicher Logarithmus 36 ncol() 69, 70 nice() 215, 219, 224, 237 nlme-Paket 328 Nonparametrische Verfahren 285 Normalverteilung 183, 251 Normalverteilung 187 nortest-Paket 187 nrow() 69, 70, 110 Nullmodell 327 objects() 57, 61 Objekte 45 anlegen 45 auflisten 57 Elemente 53 löschen 57 Namen 45 Objekttypen 66 Objekttypen ändern 77 speichern 59 Objekteigenschaften 57 Objekttypen Data Frames 50 Faktoren 49 Listen 52 Matrizen 52 Tibbles 52 Vektoren 46, 48 Odds Ratio 280 Öffnen .RData-Dateien 60 Daten 58, 59, 60 Skript 25 oii-Paket 135 omega() 304, 307 omega² 215
375
376
Sachwortverzeichnis
omega-Koeffizient 307 Operatoren lavaan 314 mathematische 36 options() 133 order() 95, 110 Ordnerstruktur 353 Paarweiser Fallausschluss 130 pairs() 209, 219, 227, 233, 237, 263, 270 pairs.panels() 178, 180, 295 Pakete 27, 40 aktualisieren 31 installieren 27 laden 29 pamm-Paket 345 papaja-Paket 348, 352 par() 139, 149, 180 Parallelanalyse 297 parameterEstimates() 316, 325 partial.r() 129 Partialkorrelation 129 patchwork-Paket 157 pcor() 129 pcor.test() 129 pdf() 348, 349, 352 Permutation 95 Pfadanalyse 311 Pfaddiagramm 312, 324 Pfadmodell 311 Pipe 73, 108, 162 pirateplot() 173 pivot_longer() 103, 104, 111 pivot_wider() 106, 107, 111 plot() 138, 165, 175, 180, 210, 219, 249, 254 png() 348, 352 points() 149 Poisson-Verteilung 183
polychoric() 135 polyserial() 135 Post-hoc-Tests 208, 215, 226, 231 Potenzieren 36 Poweranalysen 343 powerlmm-Paket 345 ppcor-Paket 129 Prädiktoren kategoriale 256 standardisieren 240 zentrieren 260, 264, 334, 338 predict() 243 principal() 304 print() 219 Probabilistische Testtheorie 360 Projekte Siehe RStudio-Projekte Prompt 20 prop.table() 114, 124, 127 Prozentwerte 127 psych-Paket 42, 118, 122, 130, 135, 178, 189, 193, 204, 222, 229, 289, 290, 292, 295, 296, 299, 305 pt() 187, 188 p-Wert 186 pwr.anova.test() 343 pwr.chisq.test() 343 pwr.f2.test() 343 pwr.r.test() 343 pwr.t.test () 343 pwr.t.test() 343 pwr2ppl-Paket 344 pwr-Paket 343 pwrSEM-Paket 345 Q-Q-Plot 251 qt() 186, 188 Quadratsummen-Typen 214, 230, 265, 268, 333 Quadratwurzel 36 Quantile 121, 183, 186
Sachwortverzeichnis
quantile() 121, 122, 125 Quartile 121 R Markdown 349 R² 244, 246, 311 Random-Coefficient-Modell 335 Random-Intercept-Modell 330 Random-Slopes-Modell 335 ranef() 337, 341 Range 118 range() 119 rbind() 53, 61, 98, 110 RColorBrewer-Paket 143 RData-Dateien öffnen 60 speichern 59 read.csv() 64, 65 read.csv2() 64, 65, 70 read.fwf() 68, 70 read.table() 67, 70 readr-Paket 68 recode() 86, 110 Reference Cards 34 Regression multiple 243 Poweranalyse 343 Regressionsanalyse einfache lineare 238 Grafische Darstellung 238, 275 hierarchische 245 Interaktionsdiagramm 269 kategoriale Prädiktoren 256 Konfidenzintervalle 242 lavaan 309 logistische 278 Modellannahmen 249 Modellgüte 244, 246 Modellvergleiche 245 moderierte 263 nicht-lineare 275
Residuen 243 Residuenplot 249 Signifikanztests 241 vorhergesagte Werte 243 Regressionsgerade 176, 177 Regressionskoeffizienten standardisierte 240, 311 unstandardisierte 240 relevel() 257, 283 Reliabilität 304 remove() 57, 61 rename() 110 resid() 243, 252, 254 Residuen chi²-Test 287 Logistische Regression 280 Mehrebenenanalyse 329 Normalverteilung 251 Regressionsanalyse 242, 243, 249, 252 Regressionsanalyse 251 Regressionsanalyse 253 Strukturgleichungsmodelle 313 Unabhängigkeit 253 Residuenplot 249 rgb() 143 R-Homepage 33 right_join() 101, 111 rm() 57 RMSEA Siehe Root Mean Square Error of Approximation Robuste Verfahren 360 Root Mean Square Error of Approximation 297, 319 round() 39, 115, 124 rowMeans() 88, 109 rowSums() 88, 109, 135 rstandard() 252 rstudent() 252
377
378
Sachwortverzeichnis
RStudio 19 anpassen 25 Benutzeroberfläche 19 Environment-Fenster 25 Konsole 20 schließen 26 Skript-Fenster 22 RStudio-Projekte 353 Säulendiagramm 138, 159 save() 59, 62 save.image() 62 scale() 81, 109, 240, 261, 334, 338 scale_ () 181 scale_x_continuous(), scale_y_continuous() 181 Schiefe 118 sd() 119 search() 31, 35 select() 91, 110, 118, 129, 176, 246, 305 sem() 310, 312, 323, 325 Semipartialkorrelation 129 semPaths() 324, 325 semPlot-Paket 324 semTools-Paket 325 setwd() 58, 61, 353 simr-Paket 345 Simulationen 344 sjPlot-Paket 269 sjstats-Paket 215 Skalenwerte berechnen 87 skew() 119 Skript 22 Encodierung 24, 357 formatieren 43, 354 öffnen 25 speichern 23 strukturieren 43, 354 Skript-Fenster 22
Sonderzeichen, Darstellung von 24 sort() 114, 124 Sortieren 95, 114 spcor() 129 spcor.test() 129 Speichern Daten 58, 59, 69 Diagramme 348 Konsole 21 Objekte 58, 59 Skript 23 Sphärizität 224, 231 sqrt() 36 Standardabweichung 118 Standardfehler 118, 174 Standardisieren 81, 240 Standardisierte Mittelwertsdifferenz Siehe Cohen's d Standardnormalverteilung 183 Standardschätzfehler 242 stat_function() 185 stat_smooth() 177, 181, 276 Stichprobengröße 69, 100, 118 Einstichproben-t-Test 189, 191 Konfirmatorische Faktorenanalyse 318 Korrelation 130 Mehrebenenanalyse 329 Regressionsanalyse 242, 248 Stichprobenumfangsplanung 343 t-Test für abhängige Stichproben 199, 201 t-Test für unabhängige Stichproben 194, 197 Varianzanalyse mit Messwiederholung 222, 229 Varianzanalyse ohne Messwiederholung 204, 212
Sachwortverzeichnis
Stichprobenumfangsplanung Siehe Poweranalysen Stilregeln 43 Dateinamen 353 Groß- und Kleinschreibung 44 Leerzeichen 43, 76 Objektnamen 45 Skript 354 Variablen benennen 76 str() 51, 61, 69, 245 Streudiagramm 138, 174, 238, 275 Streudiagramm-Matrix 138, 178 Strukturgleichungsmodelle 309, 322 Bayesianische 325 Modellgüte 319 Modellvergleiche 320 Modifikation-Indices 319 Pfaddiagramm 324 Poweranalyse 345 subset() 92, 110 Subtrahieren 36 Suchmaschinen 34 sum() 36 summary() 69, 117, 124, 241, 254, 310 Summe 36 Superpower-Paket 345 symbols() 149 t.test() 190, 196, 200, 202 Tabellen exportieren 347 formatieren 352 table() 114, 124, 126, 135 Taschenrechner 36 Tcl/Tk-Erweiterung 31 Testkonstruktion 294 Teststärke Siehe Poweranalysen Testtheorie klassische 294, 360
probabilistische 294, 360 tetrachoric() 135 text() 149 Textdatei exportieren 346 importieren 63 theme() 157, 181 Themen (ggplot2) 156 Tibbles 52 tidyr-Paket 73 tidyverse-Pakete 68, 72 tiff() 348, 352 Tilde 171 Tippfehler, typische 355 TLI 319 Toleranz 252 Trennschärfe 307 Troubleshooting 355 TRUE 37 t-Test abhängige Stichproben 199 Effektgröße 192, 198, 201 eine Stichprobe 189 Poweranalyse 343 unabhängige Stichproben 194 t-Verteilung 183 Typ-III-Quadratsummen Siehe Quadratsummen-Typen Typ-II-Quadratsummen Siehe Quadratsummen-Typen Ultralong-Format 103 Umcodieren 83 Untergruppen auswählen 92 update.packages() 31, 35 var() 119 VarCorr() 341 Variablen auswählen 90 bearbeiten 71
379
380
Sachwortverzeichnis
benennen 76 hinzufügen 109 latente 317 neu erstellen 74 Skalenwerte berechnen 87 standardisieren 81 umbenennen 75 umcodieren 83 umpolen 81 Variablentyp ändern 77 zentrieren 81, 260, 264, 334, 338 Variablennamen 76 Variance Inflation Factor (VIF) 252 Varianzanalyse Effektgrößemaße 215 einfaktorielle 204, 222 Grafische Darstellung 209, 217, 227, 235 Interaktionsdiagramm 217, 235 Kontraste 208, 215, 226, 231 mehrfaktorielle 211 mehrfaktorielle gemischte 228 mit Messwiederholung 221 multivariate 225 ohne Messwiederholung 204 Post-hoc-Tests 208, 215, 226, 231 Poweranalyse 343, 345 Varianzhomogenität Regressionsanalyse 251 t-Test 195 Varianz-Kovarianz-Matrix 134, 318 vcd-Paket 135 Vektoren 46, 48 in Faktoren konvertieren 79 View() 51, 69 VIF Siehe Variance Inflation Factor vif() 252, 254 vioplot-Paket 173 VSS() 298
Wachstumskurvenmodelle, latente 325 Wahrscheinlichkeitsverteilungen 183 Welch-Test 197 Wert, absoluter 36 Werte, fehlende 87 Wertebereich 118 Wertelabels 78 Wettquotienten 281 which() 83, 93, 109 which.max() 120, 124 which.min() 125 Wide-Format 101, 106, 221 wilcox.test() 289, 290, 291, 293 Wilcoxon-Test 288 abhängige Stichproben 290 eine Stichprobe 289 zwei unabhängige Stichproben 290 win.metafile() 348 Workflow 353 Working Directory 58 Workspace 47, 56 write.csv() 347, 352 write.csv2() 348, 352 write.dta() 346 write.foreign() 346 write.table() 352 Wurzel ziehen 36 xlsx-Paket 347 XQuartz 31 yarrr-Paket 173 Zeilennummern 50, 67 Zentrieren 81, 260, 264, 334, 338 Zusammenfügen von Data Frames Fälle hinzufügen 97 Variablen hinzufügen 99 Zusammenhangsmaße Kovarianz 133
Sachwortverzeichnis
metrische Variablen 129 nicht-metrische Variablen 135 Produkt-Moment-Korrelation 129 Zuweisungspfeil 45, 61
Powered by TCPDF (www.tcpdf.org)
z-Werte 81 %>% Siehe Pipe
381