




























































































Besser lernen dank der zahlreichen Ressourcen auf Docsity
Heimse Punkte ein, indem du anderen Studierenden hilfst oder erwirb Punkte mit einem Premium-Abo
Prüfungen vorbereiten
Besser lernen dank der zahlreichen Ressourcen auf Docsity
Download-Punkte bekommen.
Heimse Punkte ein, indem du anderen Studierenden hilfst oder erwirb Punkte mit einem Premium-Abo
Speichern wir zunächst die Item-Korrelationsmatrix in einer Variablen ab. Dabei achten wir darauf, die Korrelation zum Summenscore aus der ...
Art: Skripte
1 / 106
Diese Seite wird in der Vorschau nicht angezeigt
Lass dir nichts Wichtiges entgehen!





























































































Testtheorie mit R
Autor: Martin Papenberg
E-Mail: [email protected]
„Testtheorie mit R“ wird regelmäßig erweitert. Die aktuelle Version
kann unter https://osf.io/y4a6k/ abgerufen werden.
Letzte Aktualisierung: 3. März 2022
Lizenz
Dieses Dokument ist unter einer Creative Commons Attribution 4.
International License veröffentlicht.
auf die inhaltliche Sinnhaftigkeit und Verständlichkeit gelegt; dafür kann es vorkommen, dass – wenn angemessen – Kompromisse bei der technischen Genauigkeit eingegangen werden. Kapitel 2 enthält beispielsweise eine Beschreibung verschiedener Datentypen in R (Zahlen, Text etc.). Diese Liste deckt zwar die für uns wichtigsten Datentypen ab, ist aber nicht vollständig. Aus inhaltlichen Gründen folgt sie außerdem nicht der R-internen „technischen“ Kategorisierung. Auch hat R für so gut wie jede allgemeine Regel mindestens eine Ausnahme. Auf solche Spezialfälle werde ich bei der Beschreibung allgemeiner Grundsätze der Programmiersprache R nicht immer Rücksicht nehmen. Das Skript ist so ausgelegt, dass ein Grundstein an Kenntnissen gelegt wird, jedoch erfordert die Meisterung von R noch weitere eigenständige Einarbeitung.
1.1.1 Feedback und Fehlermeldungen
Für Feedback und eine Rückmeldung bei der Entdeckung von Fehlern im Skript (auch und insbesondere bei der Entdeckung einfacher Rechtschreibfehler, doppelter oder fehlender Wörter, fehlender Kommas etc.) bin ich sehr dankbar! Meldungen können mir an martin. [email protected] gesendet werden.
1.1.2 Danksagung
Ich danke Juli Tkotz für ihre wertvollen Beiträge und ihr nützliches Feedback zum Skript. Hanna Siegers, Marlene Wettstein, Frank Calio, Ingo Weigel, Katharina Sophie Apenbrink, Jutta Peterburs, Sara Vera Brockhaus, Sophie Schalberger und Marlene Hüsken danke ich für Fehlermeldungen.
Zur Erstellung des Skripts wurden R (R Core Team, 2018) und die R-Pakete bookdown (Xie, 2016), knitr (Xie, 2015), rmarkdown (Allaire u. a., 2017) genutzt.
Im Seminar nutzen wir die „integrierte Entwicklungsumgebung“ (engl: integrated development environment; IDE ) RStudio, um mit R zu arbeiten. Zum Nachvollziehen des Skripts und der Übungen solltet ihr deswegen RStudio auf eurem eigenen Rechner/Laptop installieren.^1 Das geht über diesen Link:
https://www.rstudio.com/products/rstudio/download/#download
Vermutlich wollt ihr eine Installationsdatei für Windows herunterladen, es gibt aber auch Optionen für Linux und Mac. Dafür schaut ihr unter „Installers for Supported Platforms“ beispielsweise unter „RStudio 1.1.442 - Windows Vista/7/8/10“.
Wichtig: RStudio ist nur die R-Umgebung, die wir nutzen, aber nicht die Programmiersprache R selbst. R muss noch einmal unter https://cran.r-project.org/ gesondert heruntergeladen werden. (^1) Falls ihr eine andere Umgebung benutzt, ist das natürlich auch kein Problem. Alternativen sind beispiels-
weise rkward (https://rkward.kde.org/) oder emacs ESS (https://ess.r-project.org/).
Hier könnt ihr beispielsweise über „Download R for Windows“ → „install R for the first time” gehen.
1.2.1 Die R-Konsole
Wenn wir R und RStudio installiert haben, können wir unsere ersten Schritte mit R nehmen. Dafür geben wir R-Code in die sogenannte Konsole ein. Im Normalfall finden wir in RStudio die Konsole in der Anzeige auf der linken Seite (je nachdem, wie ihr RStudio geöffnet habt, befindet sich die Konsole auch links unten). Wir erkennen die Konsole daran, dass die Zeile, in die wir unsere R-Befehle eintragen, mit einem > beginnt. Diese spitze Klammer fordert uns zum Eingeben von R-Code auf. Um unseren ersten R-Befehl auszuführen, schreiben wir Folgendes in die Konsole und drücken Enter:
> "Hallo Welt!"
Wenn folgende Ausgabe erscheint, hat die Installation funktioniert:
[1] "Hallo Welt!"
Wir können die Arbeit mit R beziehungsweise der R-Konsole als Kommunikation verstehen: Wir teilen R etwas mit, und R gibt uns dazu passend etwas zurück – wenn unsere Anfrage ein syntaktisch korrekter R-Befehl war. Andernfalls gibt R eine Fehlermeldung aus. Zum Beispiel können wir die R-Konsole als Taschenrechner benutzen:
1 + 3
[1] 4
3 - 17
[1] -
3 ***** 2
[1] 6
3 ^ 2
[1] 9
3 ^ 2 + 4 ^ 2
[1] 25
10 / 5
[1] 2
# Auf Klammerung achten: (3 + 5) / 2
[1] 4
In den ersten zwei Kapiteln beschäftigen wir uns damit, wie R Daten darstellt. Dabei betrachten wir zunächst die grundlegendste Datenstruktur, den Vektor (Kapitel 2). Danach lernen wir data.frames kennen (Kapitel 3) – also Datentabellen, wie wir sie auch aus Excel oder SPSS kennen. In Kapitel 4 werden wir psychometrische Datenauswertungen durchführen und dabei das Wissen anwenden, das wir zuvor erworben haben. In Kapitel 5 lernen wir, wie wir mit Rohdaten aus Fragebögen umgehen, also fehlende Werte auszuschließen und Antworten umzukodieren. In den Kapiteln 6 und 7 lernen wir mit Funktionen und Schleifen wichtige Programmiersprachenelemente kennen und werden sehen, wie wir damit unsere Arbeit automatisieren können.
2 Vektoren
Die einfachste und wichtigste Datenstruktur von R ist der Vektor. Ein Vektor ist beispielsweise eine einzelne Zahl wie in den Taschenrechner-Berechnungen in Kapitel 1. So gilt für die Berechnung 1 + 3:
Das Interessante an Vektoren ist, dass der ein-elementige Vektor nur ein Spezialfall ist. Im Normalfall können Vektoren mehrere Elemente enthalten; die „atomare“ Einheit in R ist also nicht ein einzelnes Element, sondern gleich eine Aneinanderreihung beliebig vieler^4 gleicharti- ger Elemente, etwa Zahlen. Statistische Berechnungen – wie die Berechnung eines Mittelwerts oder einer Standardabweichung – lassen sich direkt auf einer Menge an Daten durchführen, da diese in einem Vektor gespeichert sind. Diese „Vektorbasiertheit“ ist vermutlich die größte Stärke von R für statistische Berechnungen.
Elemente zu Vektoren zusammenfügen (sprich: mehrere Vektoren zu einem Vektor zusam- menfügen) funktioniert mit der Funktion c() – die vermutlich basalste Funktion in R. Sie ist so simpel und grundlegend, dass man sie gegebenenfalls vergisst, wenn man sie braucht – versucht, sie zu erinnern!
## Füge mehrere Zahlen zu einem Vektor zusammen: c (0.5, 1, 1.5) # Kommazahlen mit DezimalPUNKT schreiben
[1] 0.5 1.0 1.
Man kann die Funktion c() auch auf eine einzelne Zahl anwenden. Das ist dasselbe als würde man nur die Zahl eingeben:
c (1)
[1] 1
Folgendes geht auch, da c() mehrere Vektoren zu einem einzelnen Vektor „verschmilzt“:
c (0.5, 1, 1.5, c (1, 2, 3))
[1] 0.5 1.0 1.5 1.0 2.0 3.
Auf mehrelementigen Vektoren kann man statistische Berechnungen durchführen, wie etwa die Bestimmung des arithmetischen Mittels, einer Standardabweichung, der Varianz, oder des Minimums oder Maximums:^5
## Berechne einen Mittelwert mean ( c (0.5, 1, 1.5))
(^4) Interessanterweise gibt es sogar Vektoren der Länge 0 – also Vektoren, die gar kein Element beinhalten. Das soll uns aber erst einmal nicht beschäftigen. (^5) R würde oft auch bei einelementigen Vektoren ein Ergebnis ausgeben, aber das ist zum Beispiel beim Mittelwert wenig sinnvoll.
der mir dieses Ergebnis generiert – hier: var(c(0.5, 1, 1.5)).
Eine nützliche und oft verwendete Kurzform, um Vektoren aufsteigender, ganzer Zahlen zu erstellen ist folgende:
1 : 20
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
So lässt sich beispielsweise sehr einfach die Summe aller Zahlen von 1 bis 1,000 berechnen:
sum (1 : 1000)
[1] 500500
Wir können auch absteigende Sequenzen erstellen:
5 :- 5
[1] 5 4 3 2 1 0 -1 -2 -3 -4 -
Diese Tabelle enthält einige nützliche Funktionen, die auf Vektoren anwendbar sind (in R-Jargon: sie nehmen einen Vektor als Argument an) und jeweils selber auch einen Vektor zurückgeben:
Name Funktionalität mean Berechnet den Mittelwert eines Vektors median Berechnet den Median eines Vektors sum Berechnet die Summe aller Elemente eines Vektors max Gibt den größten Wert eines Vektors zurück min Gibt den kleinsten Wert eines Vektors zurück length Gibt die Zahl der Elemente eines Vektors zurück sd Berechnet die Standardabweichung eines Vektors var Berechnet die Varianz eines Vektors sort Sortiert einen Vektor aufsteigend rev Kehrt die Reihenfolge der Elemente im Vektor um round Rundet die Elemente in einem Vektor sqrt Berechnet für jedes Element im Vektor die Quadratwurzel unique Gibt alle unterschiedlichen Werte eines Vektors aus
Für die Funktionen in dieser Tabelle gilt, dass sie zwar alle einen Vektor zurückgeben, aber die Länge des Ausgabevektors unterschiedlich sein kann. Die Funktionen mean() und sum() ergeben etwa Vektoren der Länge 1, da sie genau einen Kennwert bestimmen. Die Funktionen sort(), sqrt() und round() geben hingegen einen Vektor zurück, der aus genauso vielen Elementen besteht wie der Eingabevektor.
Basale mathematische Berechnungen werden gleich auf alle Elemente eines Vektors angewen- det: 1 : 10 ***** 2
[1] 2 4 6 8 10 12 14 16 18 20 (1 : 10 ***** 2) - 1
[1] 1 3 5 7 9 11 13 15 17 19 Hierbei werden die Operationen * 2 bzw. -1 direkt auf alle Elemente der Vektoren 1:10 bzw. (1:10 * 2) angewendet; die Ausgabe ist jeweils ein Vektor der Länge 10. Bei gleich langen Vektoren werden solche Operationen im Allgemeinen komponentenweise angewendet: 2 : 4 ***** 4 : 6 # entspricht c(24, 35, 4*6)
[1] 8 15 24
Dieses Verhalten ist typisch für R: Viele Funktionen und Operationen in R arbeiten kompo- nentenweise, wenn zwei Vektoren gleicher Länge übergeben werden. Das Element an Position 1 im einen Vektor wird dann mit dem Element an Position 1 im anderen Vektor gepaart, das Element an Position 2 im einen Vektor mit dem Element an Position 2 im anderen Vektor – und so weiter. Werden ein ein-elementiger Vektor und ein mehr-elementiger Vektor mit einer Berechnung (etwa einer Addition) verknüpft, wird normalerweise das einzelne Element mit allen Elementen des anderen Vektors „gepaart“.
Wir werden nur diese Fälle betrachten: Entweder wird ein ein-elementiger Vektor mit einem längeren Vektor verknüpft oder zwei gleich lange Vektoren werden miteinander verknüpft. Es ist auch möglich, andere Kombinationen von Vektorlängen zu paaren, was wir jedoch erst einmal vernachlässigen; interessierte Leser können die folgenden Befehle in die R-Konsole eingeben und beobachten, was passiert. c (1,2) ***** 1 : 4 c (1,2) ***** 1 : 3
Wir wollen unsere Daten nicht nur in der Konsole ausgeben lassen, sondern auch abspeichern und damit arbeiten. Ein essentieller Bestandteil einer jeden Programmiersprache ist es, Daten in Variablen abzuspeichern. Variablen sind Namen, mit deren Hilfe wir auf gespeicherte Daten zugreifen. Wenn wir Daten in einer Variablen abgespeichert haben, können wir unter dem Namen der Variablen immer wieder darauf zugreifen. In R funktioniert das mit der Zuweisung <-.
2.2.1 Ausgabe versus Abspeichern
Wir haben jetzt zwei verschiedene Möglichkeiten kennengelernt, Objekte^6 in R zu verwenden:
[1] -3 2 3 3 5 6 7 9
Die Funktion sort() sortiert den numerischen Vektor bar aufsteigend. Wie sieht der Vektor bar nach der Operation aus? Es gibt zwei Möglichkeiten:
Wir können die Frage leicht klären, indem wir bar in der Konsole ausgeben: bar
[1] 3 2 6 3 9 5 7 -
Offensichtlich hat sort(bar) den Vektor, der in der Variablen bar gespeichert ist, nicht geändert. Das ist eine fundamentale Eigenschaft der Programmiersprache R: Funktionen nehmen Daten an und sie geben Daten zurück – sie verändern aber nicht die eingegebenen Daten. Wenn wir wollen, dass bar die Zahlenfolge in sortierter Reihenfolge enthält, können wir die folgende Befehlkette verwenden: bar <- c (3, 2, 6, 3, 9, 5, 7, -3) bar <- sort (bar)
In diesem Fall geht der Ursprungsvektor verloren und wir behalten nur den sortierten Vektor. Generell gilt: wenn wir Daten in der Konsole ausgeben lassen, verschwinden diese sozusagen im „Nirvana“. Wenn wir mit Daten weiterarbeiten wollen, müssen wir die Ausgabe einer Funktion in einer Variablen speichern. Beide Verwendungszwecke sind denkbar: Manchmal benötige ich nur die Ausgabe einer Berechnung, manchmal möchte ich das Ergebnis abspeichern.
2.2.2 Variablennamen
Generell bestehen Variablennamen aus Buchstaben und Zahlen und den Zeichen. und _. Folgende Einschränkungen sind zu beachten:
- bla bla <- c(1, 2) funktioniert nicht - blabla <- c(1, 2) funktioniert
Eine fundamentale Schwierigkeit beim Programmieren ist das Finden guter Variablennamen; bla und blabla sind denkbar schlechte Variablennamen. Gute Variablennamen sprechen , d.h. sie machen eine Aussage darüber, was für Daten sie beinhalten.
## Schlechter Variablenname: foo <- mean (age)
## Ggf. etwas besser: mean_age <- mean (age)
Beachtet immer folgende Regel: Variablennamen sollten nicht lügen, also verwendet niemals einen Namen der folgenden Art:
mean_age <- sd (age) # Niemals machen!
Man ist schnell geneigt einen unsinnigen Variablennamen zu vergeben, um keine Zeit mit der Namensfindung zu verschwenden – man hat ja schließlich wichtigen Code zu schreiben! Man sollte sich jedoch so gut wie immer kurz Zeit nehmen, einen sinnigen Namen zu finden – das zukünftige Selbst wird es einem danken. Unsinnige Variablennamen sind in Ordnung, wenn man sich zu 100% sicher ist, dass man die Variable nach einmaliger Nutzung nicht mehr verwendet. Wenn man eine Variable nicht mehr benutzen möchte, kann man sie mit der rm() Funktion löschen:
foo <- 1 : 10 # Wegwerfvariable rm (foo) foo Fehler : Objekt 'foo' nicht gefunden
Weiterhin ist es guter Stil konsistent in der Vergebung der Variablennamen zu sein. Variablen- namen sollen einen semantischen Gehalt haben, das heißt sie machen eine Aussage darüber, welche Daten sie enthalten. Häufig ist diese Information nicht in einem Wort erklärbar. Um auszusagen, dass eine Variable „das mittlere Alter“ enthält, müssen mindestens die Anteile „mittel“ und „Alter“ enthalten sein. Wie soll das verknüpft werden? Verschiedene
In erster Linie werden wir Vektoren vom Typ character für Datenzugriffe verwenden; im Speziellen werden wir sie einsetzen, um Spalten in Datentabellen zu adressieren, da Spalten normalerweise per Namen angesteuert werden (siehe Kapitel 3).
2.3.2 logical
Es hat sich als nützlich erwiesen, einen Datentyp einzuführen, der „Wahrheit“ kodiert. Dieser Datentyp wird in R „logical“ genannt; er kennt nur die Ausprägungen TRUE und FALSE. Eine sonst gängige Bezeichnung für diesen Datentyp ist auch „boolean“.
wahr <- TRUE falsch <- FALSE
Im Allgemeinen interpretieren wir TRUE/FALSE als logische Bedingungen, die entweder erfüllt sind oder nicht. Ist die Ampel grün? Hat die Versuchsperson eine Reaktionszeit von 2000ms oder mehr? Ist der Kuchen schon 60 Minuten im Ofen? Wir werden häufig vom Typ logical Gebrauch machen, wenn wir in Datentabellen Fälle auswählen; dann wird jeweils überprüft, welche Fälle die gewünschten Bedingungen erfüllen und anhand dessen findet eine Auswahl statt (etwa: wähle alle weiblichen oder männlichen Teilnehmer/innen in einer Umfrage aus).
Mit logischen Werten kann man die logischen Operationen UND (in R: & ), ODER (in R: | ) und NICHT (in R:! ) umsetzen. UND und ODER verknüpfen jeweils zwei logische Bedingungen (sprich: zwei logische Werte, also TRUE/FALSE) miteinander und geben selbst einen logischen Wert zurück. UND gibt dann TRUE aus, wenn beide Bedingungen erfüllt sind, also nur dann, wenn die erste und die zweite Bedingung erfüllt ist:
## Logisches UND TRUE & TRUE
[1] TRUE
TRUE & FALSE
[1] FALSE
FALSE & FALSE
[1] FALSE
ODER ist etwas weniger streng und gibt auch dann schon TRUE aus, wenn mindestens eine Bedingung erfüllt ist, also wenn die erste oder die zweite Bedingung erfüllt ist:
## Logisches ODER TRUE | TRUE
[1] TRUE
TRUE | FALSE
[1] TRUE
Beachtet, dass ODER immer TRUE ausgibt, wenn mindestens eine Bedingung erfüllt ist; also auch dann, wenn beide Bedingungen erfüllt sind – es ist kein umgangssprachliches entweder/oder.
Das logische NICHT invertiert die Eingabe: Aus TRUE wird FALSE und umgekehrt.
## Logisches NICHT ! TRUE
[1] FALSE
! FALSE
[1] TRUE
Die logischen Operationen UND und ODER arbeiten komponentenweise auf Vektoren, die mehr als ein Element enthalten:
c (TRUE, FALSE, FALSE) & c (TRUE, TRUE, FALSE)
[1] TRUE FALSE FALSE
c (TRUE, FALSE, FALSE) | c (TRUE, TRUE, FALSE)
[1] TRUE TRUE FALSE
Auch das logische NICHT arbeitet vektorisiert. Es kann auf einen logischen Vektor angewendet werden, der beliebig viele Elemente enthält und kehrt alle Elemente darin um:
!c (TRUE, FALSE)
[1] FALSE TRUE
Während die Operationen UND, ODER und NICHT an dieser Stelle nur abstrakt einge- führt werden, werden wir in weiteren Abschnitten (Kapitel 2 und Kapitel 3) noch lernen, wie wir logische Bedingungen verwenden, um gezielt Daten mit bestimmten Eigenschaften auszuwählen.
2.3.3 factor
Vektoren vom Typ factor stellen kategoriale Variablen dar – etwa die unabhängigen Variablen in einer Varianzanalyse. Mithilfe der Funktion factor() können wir einen Vektor vom Typ factor erstellen:
laune <- c (1, 2, 3, 1, 2, 1)
laune_faktor <- factor ( laune,