Fehlende Werte

Überprüfung auf Vorhandensein, Zufälligkeit und Umgang

Table of Contents


Einleitung

Es kann in der Praxis häufiger vorkommen, dass Datensätze unvollständig sind z.B. wenn Teilnehmende einer Befragung nicht alle Fragen beantworten. Diese fehlenden Einträge nennt man Missings. In R werden sie mit NA (“not available”) gekennzeichnet.

Beim numerischen Datentyp (d.h. Zahlen) sind fehlende Werte immer durch NA repräsentiert. Beim character Datentyp (d.h. Buchstaben, Zeichen) hingegen können fehlende Eingaben auch durch "" (leere Felder) gekennzeichnet sein z.B. wenn bei Freitextfeldern in einer Umfrage nichts eingegeben wurde.

Fehlende Werte sind grundsätzlich mit drei Schwierigkeiten verbunden:

Daher ist es sehr wichtig, sich vor der Auswertung einen Überblick über die fehlenden Werte zu verschaffen.

In diesem Kapitel schauen wir uns an, ob und wenn ja, wo und wie viele Missings sich im Datensatz befinden. Außerdem gibt es einen groben Überblick darüber, ob Missings zufällig sind und wie man mit ihnen umgehen kann.

Der Umgang mit Missings ist ein komplexes Thema. In diesem Kapitel werden wir uns auf zwei gängige Methoden zum Umgang mit Missings beschränken. In Abhängigkeit der eigenen Fragestellung empfiehlt es sich, passende Methoden zu recherchieren.

Beispieldatensatz für dieses Kapitel

Das ist der Code für den Datensatz, an dem wir in diesem Kapitel arbeiten werden.
Wenn du die Befehle dieses Abschnitt ausprobieren möchtest, führe den Code aus und erstelle den Datensatz.


# Data Frame erstellen
daten <- matrix(c(-99, 0, 1, 3, 2, 
                  1, 2, 3, 2, 0, 
                  NA, 1, 3, 99, 0, 
                  1, 3, 3, 1, 2, 
                  2, 0, 2, 99, 3), nrow = 5, ncol = 5)

# in Dataframe umwandeln
daten <- data.frame(daten)

# Spalten und Zeilen benennen
colnames(daten) <- c("Var_1", "Var_2", "Var_3", "Var_4", "Var_5")
rownames(daten) <- c("Vpn_1", "Vpn_2", "Vpn_3", "Vpn_4", "Vpn_5")

      Var_1 Var_2 Var_3 Var_4 Var_5
Vpn_1   -99     1    NA     1     2
Vpn_2     0     2     1     3     0
Vpn_3     1     3     3     3     2
Vpn_4     3     2    99     1    99
Vpn_5     2     0     0     2     3

Anmerkung: Die Variablen sind intervallskaliert mit einer Skala von 0-3.


Hinweis: Wenn du Variablen, die Missings enthalten, für eine Analyse nutzt, denke immer daran, dass sich damit auch die Stichprobengröße \(N\) für diese spezifische Auswertung ändert.


1. Sind die Missings einheitlich kodiert?

In manchen Anwendungen werden Missings nicht mit NA, sondern z.B. wie bei Unipark mit 99 oder -99 kodiert. Daher müssen wir dafür sorgen, dass R Missings auch als solche erkennt. Das gewährleistet man, indem man alle Missings auf NA setzt.

Wenn man weiß, wie Missings im Datensatz kodiert sind, kann man gleich zu Wie kann ich die Missings auf NA setzen? springen. Wenn man weiß, dass alle Missings einheitlich mit NA kodiert sind, kann man den ganzen Abschnitt auslassen.

Wie kann ich prüfen, ob die Missings einheitlich kodiert sind?

Um herauszufinden, ob alle Missings mit NA kodiert sind, schauen wir uns die einzelnen Ausprägungen der Variablen an. Dazu nutzen wir die table()-Funktion, die eine Häufigkeitstabelle erstellt. Das Argument useNA='ifany' legt dabei fest, dass auch die Anzahl der NAs gezählt werden soll.


table(daten$Var_3, useNA='ifany')

   0    1    3   99 <NA> 
   1    1    1    1    1 

Da wir wissen, dass Var_3 nur die Ausprägungen \(0,1,2,3\) annehmen kann, können wir schließen, dass \(99\) auch ein Missing sein muss.

Wenn man also alle möglichen Ausprägungen seiner Variablen kennt, kann man auf diese Weise einfach herausfinden ob noch anderweitig kodierte Missings im Datensatz vorliegen.

Wie kann ich die Missings auf NA setzen?

Nun wollen wir diese Missings umkodieren. Vorher wollen wir uns noch einmal anschauen, was passiert, wenn man das nicht macht.

Wenn man Missings im Datensatz nicht einheitlich auf NA kodiert, nimmt R an, dass es sich um gültige Werte handelt. Das führt dann zu falschen Ergebnissen. Das schauen wir uns exemplarisch einmal am Mittelwert der Spalte Var_3 an.


# Mittelwert vor Umkodierung
mean(daten$Var_3, na.rm=TRUE)

[1] 25.75

Nun kodieren wir die Missings in Var_3 einheitlich um …


# Umkodierung für einzelne Variablen
daten$Var_3[daten$Var_3 == 99] <- NA

Der Befehl ersetzt in daten Elemente der Spalte Var_3, welche die Ausprägung 99 besitzen, mit NA.


      Var_1 Var_2 Var_3 Var_4 Var_5
Vpn_1   -99     1    NA     1     2
Vpn_2     0     2     1     3     0
Vpn_3     1     3     3     3     2
Vpn_4     3     2    NA     1    99
Vpn_5     2     0     0     2     3

… und schauen uns den Mittelwert von Var_3 wieder an.


# Mittelwert nach Umkodierung
mean(daten$Var_3, na.rm=T)

[1] 1.333333

Hätten wir die Missings nicht einheitlich auf NA kodiert, hätten wir errechnet, dass der Mittelwert von Var_3 25.75 anstatt ~1.33 betragen würde.

Wir sehen also, dass es sehr wichtig ist, in Erfahrung zu bringen, ob im Datensatz alle Missings einheitlich auf NA gesetzt sind, und wenn nicht, diese einheitlich zu kodieren, da man sonst falsche Ergebnisse erhält.

Jetzt enthält die Spalte Var_r schon keine Elemente mit der Ausprägung 99 mehr, aber in Var_1 gibt es noch ein -99 und in Var_5 noch ein 99.

Um nicht einzeln Spalten und Ausprägungen ansprechen zu müssen, kann man alles in einem Befehl kombinieren.


# Umkodierung für den gesamten Datensatz
daten[daten == 99 | daten == -99] <- NA

Hiermit werden im gesamten daten-Datensatz jene Elemente, welche die Ausprägung 99 oder -99 besitzen, durch NA ersetzt.


2. Enthält ein Datensatz Missings?

Wenn wir wissen wie unsere fehlenden Werte kodiert sind, wollen wir in einem nächsten Schritt natürlich wissen, ob ein Datensatz überhaupt Missings enthält. Es gibt zahlreiche Ansätze, um das herauszufinden. Einige davon schauen wir uns einmal genauer an.

Bei kleineren Datensätzen ist eine visuelle Inspektion möglich. Dafür nutzt man entweder View() (Großbuchstabe am Anfang beachten!) oder man klickt auf den Datensatz im Environment (oberes rechtes Panel).


      Var_1 Var_2 Var_3 Var_4 Var_5
Vpn_1    NA     1    NA     1     2
Vpn_2     0     2     1     3     0
Vpn_3     1     3     3     3     2
Vpn_4     3     2    NA     1    NA
Vpn_5     2     0     0     2     3

Um zu überprüfen, ob ein Datensatz mindestens einen fehlenden Wert enthält, kann man anyNA() nutzen. Man bekommt ein TRUE (d.h. ja, mindestens ein Missing enthalten) oder FALSE (d.h. nein, keine Missings enthalten) ausgegeben.


anyNA(daten)

[1] TRUE

Um einen groben Eindruck davon zu bekommen, welche Elemente fehlen, kann man is.na() nutzen. Der Output besteht aus FALSE oder TRUE für jedes Element des Datensatzes. TRUE bedeutet dabei, dass an dieser Stelle ein Missing ist.


      Var_1 Var_2 Var_3 Var_4 Var_5
Vpn_1  TRUE FALSE  TRUE FALSE FALSE
Vpn_2 FALSE FALSE FALSE FALSE FALSE
Vpn_3 FALSE FALSE FALSE FALSE FALSE
Vpn_4 FALSE FALSE  TRUE FALSE  TRUE
Vpn_5 FALSE FALSE FALSE FALSE FALSE

Den logischen Vektor, den is.na() erzeugt, kann man mit which() kombinieren, um sich die Positionen der Missings ausgeben zu lassen. Mithilfe des Arguments arr.ind = TRUE lässt man sich die Reihe und die Spalte dieser ausgeben.

Ohne arr.ind = TRUE würde man nur die Indizes ausgegeben bekommen. Für Matrizen sind diese weniger leicht zu nutzen, weil die Nummerierung fortlaufend spaltenweise vorliegt. In unserem Fall einer 5 x 5 Matrix heißt das z.B., dass das Element in der 1. Zeile der 3. Spalte (also der eine fehlende Wert) den Index 11 trägt.

Bei Vektoren kann man arr.ind = TRUE weglassen, da diese entweder nur aus einer Spalte oder einer Zeile bestehen.


which(is.na(daten), arr.ind = TRUE)

      row col
Vpn_1   1   1
Vpn_1   1   3
Vpn_4   4   3
Vpn_4   4   5

3. Wie kann man die Missings zählen (und verorten)?

Die genaue Anzahl der Missings zu kennen ist wichtig, um ein Gefühl dafür zu kriegen, wie vollständig ein Datensatz ist. Im Folgenden lernen wir Missings im gesamten Datensatz spalten- bzw. zeilenweise zu zählen.

Dabei greifen wir auf eine Kombination der table()- mit der is.na()-Funktion zurück. Mit dieser Kombination werden die FALSEs (d.h. vorhandenen Werte) und TRUEs (d.h. fehlenden Werte) gezählt.

Alle Missings eines Datensatzes

Zuerst schauen wir uns die Gesamtanzahl der Missings im Datensatz an.


table(is.na(daten))

FALSE  TRUE 
   21     4 

Missings in bestimmten Spalten und Zeilen

Spaltenweises Zählen der Missings gibt Informationen über mögliche Probleme mit bestimmten Variablen. Zeilenweises Zählen der Missings gibt beispielsweise Informationen über Teilnehmende, die die Fragen nicht vollständig beantwortet haben.

Es ist daher wichtig, sich einen Überblick darüber zu machen, ob sich bei bestimmten Variablen oder bei bestimmten Personen besonders viele Missings häufen. Wenn das der Fall sein sollte, muss man überlegen, wie man damit umgeht (dazu mehr im späteren Verlauf).

Missings in einzelnen Spalten oder Zeilen

Wenn man eine bestimmte Spalte oder Zeile betrachten möchte, gibt es verschiedene Wege, das zu tun.
Drei Möglichkeiten dafür schauen wir uns einmal näher an.

Mit dem $

An den Namen des Datensatzes hängt man ein $ und den Namen der Spalte. Diese Möglichkeit funktioniert nur bei Spalten.


table(is.na(daten$Var_1))

FALSE  TRUE 
    4     1 

Mit dem Namen der Spalte bzw. Zeile

Hinter den Namen des Datensatzes kommt in [ ] der Name der Spalte in Anführungszeichen. Möchte man eine Zeile anschauen, dann muss man hinter den in Anführungszeichen geschriebenen Namen der Zeile noch ein Komma setzen.


# Spalte
table(is.na(daten["Var_1"]))

FALSE  TRUE 
    4     1 

# Zeile
table(is.na(daten["Vpn_1",]))

FALSE  TRUE 
    3     2 

Mit dem Index der Spalte bzw. Zeile

Hinter den Namen des Datensatzes kommt in [ ] die Position der Spalte. Möchte man eine Zeile anschauen, dann muss man hinter der Positon noch ein Komma setzen.


# Spalte
table(is.na(daten[1]))

FALSE  TRUE 
    4     1 

# Zeile
table(is.na(daten[1,]))

FALSE  TRUE 
    3     2 

Zusätzliche Bemerkung:
Die vorgestellten Möglichkeiten funktionieren so nur bei Dataframes, nicht bei Matrizen. Per Default werden dabei mit den Möglichkeit 2 und 3 Spalten angesprochen. Deswegen muss man nur beim Ansprechen von Zeilen ein Komma setzen.
Für Matrizen kann man Möglichkeit 3 - die Angabe der Position - nutzen. Dabei muss man nur für die Spaltenindexierung noch das Komma setzen: daten[,1].

Missings in allen Spalten oder allen Zeilen

Wenn man sich einen Überblick über die Missings in allen Variablen bzw. bei allen Personen verschaffen möchte, kann man dafür colSums() bzw. rowSums() mit dem bereits bekannten is.na()-Befehl kombinieren. Erstere bilden spalten- bzw. zeilenweise Summen. Wenn wir diesen Funktionen die logischen Argumente übergeben, die is.na() ausgibt, dann werden damit (nur) die TRUEs (d.h. die Missings) gezählt. Wir erhalten also eine Übersicht, in der für jede Spalte bei colSums() bzw. jede Zeile bei rowSums() die Häufigkeiten der Missings stehen.

Um die Größenordnung der Missings besser beurteilen zu können, sollte man sich der maximal möglichen Anzahl der Elemente in einer Spalte bzw. Zeile bewusst sein. Diese können wir mit nrow() bzw. ncol() in Erfahrung bringen. Alternativ kann man sich auch die Angaben zu obs. (observations, Zeilen) und variables (Spalten) im Environment, die rechts vom Datensatz stehen, anschauen.


# a) Übersicht der Missings in allen Variablen (Spalten)
colSums(is.na(daten))

Var_1 Var_2 Var_3 Var_4 Var_5 
    1     0     2     0     1 

# ... im Vergleich zur maximalen Anzahl an Beantwortungen
nrow(daten)

[1] 5

# b) Übersicht der Missings in allen Personen (Zeilen)
rowSums(is.na(daten))

Vpn_1 Vpn_2 Vpn_3 Vpn_4 Vpn_5 
    2     0     0     2     0 

# ... im Vergleich zur maximalen Anzahl der beantwortbaren Fragen
ncol(daten)

[1] 5

Visualisierung der Missings

Mit der Funktion aggr() aus dem Paket VIM kann man sich zwei Plots ausgeben lassen, die 1) den relativen Anteil von Missings in den einzelnen Variablen und 2) die Anzahl an Missings in bestimmten Kombinationen von Variablen (d.h. in den Zeilen) ausgeben.

Wenn man summary(aggr(daten)) nutzt, bekommt man sowohl die grafische Visualisierung als auch eine Übersicht der Häufigkeiten.


library(VIM)
summary(aggr(daten))


 Missings per variable: 
 Variable Count
    Var_1     1
    Var_2     0
    Var_3     2
    Var_4     0
    Var_5     1

 Missings in combinations of variables: 
 Combinations Count Percent
    0:0:0:0:0     3      60
    0:0:1:0:1     1      20
    1:0:1:0:0     1      20

Im linken Plot sehen wir, dass nur Missings in Var_1, Var_3 und Var_5 vorhanden sind. Außerdem sehen wir auf der \(y\)-Achse den relativen Anteil an Fällen in den Variablen. In der Übersicht unter der Tabelle sehen wir die absoluten Häufigkeiten für alle Variablen (Missings per variable). Im rechten Plot sehen wir die vorhanden Kombinationen von Missings in den Variablen. Blau zeigt an, dass kein Missing vorhanden ist; rot zeigt an, dass ein Missing vorhanden ist. Beispielsweise zeigt die unterste Reihe (die komplett blau ist) eine Kombination, in der keine Missings in Variablen vorhanden sind. Rechts daneben sieht man einen Balken, der den Anteil dieser Kombination im Verhältnis zu den anderen Kombinationen darstellt. Der Balken in der untersten Reihe ist der größte, d.h. dass diese Kombination am häufigste vorkommt und somit die meisten Fälle (Personen, Zeilen) im Datensatz keine Missings enthalten. Leider bekommen wir hier keine Häufigkeiten dafür angezeigt. Dazu können wir aber in die unten stehende Übersicht schauen. (Missings in combinations of variables), in der wir absolute und relative Häufigkeiten ausgegeben bekommen.

Anstatt also colSums() bzw. rowSums() mit ncol() (wie oben beschrieben) zu nutzen, kann man alternativ auch aggr() nutzen.


4. Sind die Missings zufällig?

Am Anfang des Kapitels wurde bereits erwähnt, dass systematische Missings eine Auswertung verzerren können. Was es aber genau bedeutet, wenn Missings zufällig oder nicht zufällig sind und wie man das überprüfen kann, beleuchten wir in diesem Abschnitt.

Arten von Missings

MCAR ist eine strengere Annahme als MAR. Wenn die Daten MCAR sind, dann sind sie auch MAR. Bei MAR und MNAR kann es zu Parameterverzerrungen kommen.

Mögliche Methoden zum Umgang mit Missings findet ihr in den im Abschnitt 6. Literaturempfehlungen angegebenen Buchkapiteln.

Test auf MCAR

Exemplarisch wollen wir uns einen möglichen Test anschauen, der überprüft, ob die Annahme von MCAR verletzt ist.

\(\chi^2\)-Test für multivariate Daten von Little (1988):
Dieser überprüft, ob es signifikante Unterschiede zwischen den Mittelwerten der Muster von fehlenden Werten gibt. Die Nullhypothese (\(H_0\)) besagt, dass die Mittelwerte der Variablen (Spalten) nicht in Abhängigkeit der Missingmuster variieren. Die Alternativhypothese (\(H_1\)) besagt, dass die Mittelwerte sich zwischen den verschiedenen Mustern von Missings unterscheiden.

Auch hier muss man sich vorher überlegen, wo man das Signifikanzniveau \(\alpha\) setzt. Für unser Beispiel legen wir es entsprechend der gängigen Konventionen auf \(\alpha= 0.05\) fest.

In R nutzen wir dafür die Funktion LittleMCAR aus dem Paket BaylorEdPsych, welche dabei auch auf das Paket mvnmle zugreifen muss. Falls ihr diese Pakete nicht installiert habt, macht ihr das mit dem ìnstall.packages()-Befehl.


library("BaylorEdPsych")
library("mvnmle")
LittleMCAR(daten)

this could take a while

$chi.square
[1] 7.061173

$df
[1] 6

$p.value
[1] 0.315227

$missing.patterns
[1] 3

$amount.missing
                Var_1 Var_2 Var_3 Var_4 Var_5
Number Missing    1.0     0   2.0     0   1.0
Percent Missing   0.2     0   0.4     0   0.2

$data
$data$DataSet1
      Var_1 Var_2 Var_3 Var_4 Var_5
Vpn_2     0     2     1     3     0
Vpn_3     1     3     3     3     2
Vpn_5     2     0     0     2     3

$data$DataSet2
      Var_1 Var_2 Var_3 Var_4 Var_5
Vpn_1    NA     1    NA     1     2

$data$DataSet3
      Var_1 Var_2 Var_3 Var_4 Var_5
Vpn_4     3     2    NA     1    NA

Gleich zu Beginn weist uns die Funktion darauf hin, dass die Berechnung einige Zeit in Anspruch nehmen kann.
Das ist davon abhängig, wie groß der Datensatz ist. Mehr als 50 Variablen kann die Funktion nicht bearbeiten.

Als erstes gibt sie uns den \(\chi^2\)-Wert, die Anzahl der Freiheitsgrade (\(df\)) und den \(p\)-Wert aus.

Der \(p\)-Wert für den MCAR-Test für unseren Datensatz ist größer als die Irrtumswahrscheinlichkeit \(\alpha\). Dies bedeutet, dass wir die \(H_0\) nicht ablehnen können und (bis auf weiteres) davon ausgehen, dass die missing at random Annahme erfüllt ist.

Zusätzlich bekommen wir noch mehr nützliche Informationen ausgegeben:

  • $amount.missing gibt die absoluten (1. Zeile) und relativen (2. Zeile) Häufigkeiten von Missings in den Spalten aus
  • $missing.patterns zeigt an, wie viele Missingmuster es gibt
  • $data strukturiert den Datensatz nach diesen Missingmustern
    • $data$DataSet1 zeigt dabei den Teil der Daten, der zeilenweise keine Missings enthält
Für mehr Informationen zu diesem Test:
Little, R. J. A. (1988). A test of missing completely at random for multivariate data with missing values. Journal of the American Statistical Association, 83(404), 1198–1202.


5. Wie kann man mit Missings umgehen?

Es gibt verschiedene Möglichkeiten, um mit unvollständigen Datensätzen umzugehen. Diese sind mehr oder weniger geeignet in Abhängigkeit davon, welche Annahme (MCAR, MAR, MNAR) die Missings erfüllen. Es gibt aber keine einheitlichen Richtlinien darüber, wie man mit Missings umgehen sollte. Das liegt u.a. auch daran, dass schon die Überprüfung der Zufälligkeit von Missings schwierig ist. Wichtig ist grundsätzlich, dass man sich mit den Missings eines Datensatzes auseinander setzt und einen Weg findet, mit ihnen umzugehen, ohne dass dies die Ergebnisse verzerren könnte. Man muss also für die eigene Fragestellung und Auswertungsmethode einen geeigneten Weg finden.

Im Folgenden wollen wir uns darauf beschränken, uns eine gängige Methode anzuschauen, die man nutzen kann, wenn die Missings MCAR sind. Wenn diese Annahme nicht erfüllt ist, können bei Nutzung der folgenden Methoden verzerrte Parameterschätzungen resultieren.

Dabei exkludiert man entweder ganze Fälle (listwise deletion; d.h. eine gesamte Person wird gelöscht) oder nutzt vorhandene Elemente dieses Falls (pairwise, d.h. vorhandene Werte einer Person in bestimmten Variablen), wenn sie für eine bestimmte Analyse zur Verfügung stehen.

Nachteil von beiden (d.h. des Löschens von ganzen Zeilen bzw. des partiellen Ausschlusses von Zeilen) ist generell, dass die Stichprobengröße \(N\) sinkt und damit einhergehend größere Standardfehler und eine geringere Power resultieren. Ein weiteres Problem beim pairwise-Ausschluss ist außerdem, dass sich die Stichprobengröße \(N\) für unterschiedliche Analysen unterscheiden wird.

Neuen Datensatz erstellen, der keine Missings enthält

Mit na.omit() löscht man casewise, d.h. Fälle, die mindestens ein Missing aufweisen werden komplett gelöscht. Im Folgenden wollen wir illustrativ einmal den ursprünglichen Datensatz mit einem Datensatz nach listwise deletion vergleichen. Dazu speichern wir den alten Datensatz nach listwise deletion via der na.omit() Funktion als ein neues Objekt:


daten_cw <- na.omit(daten)

      Var_1 Var_2 Var_3 Var_4 Var_5
Vpn_2     0     2     1     3     0
Vpn_3     1     3     3     3     2
Vpn_5     2     0     0     2     3

Zur Überprüfung des neuen Datensatz kann man dim() nutzen. Diese Funktion gibt uns die Dimensionen eines Objektes aus. Dabei werden zuerst die Zeilen, und nachfolgend die Spalten ausgegeben.


dim(daten_cw)

[1] 3 5

Wir haben jetzt leider den Nachteil, dass unser Datensatz von fünf auf drei Personen geschrumpft ist (weil zwei Personen mindestens auf einer Variablen ein Missing hatten).

Abhängig von der eigenen Auswertung möchte man das vielleicht eher nicht so machen, sondern die vorhandenen Werte in den hier gelöschten Zeilen noch anderweitig nutzen.

Festlegen, wie Funktionen mit Missings umgehen sollen

Anstatt die Daten in einem ersten Schritt hinsichtlich der fehlenden Werte zu bereinigen, erlauben viele Funktionen den Umgang mit fehlenden Werten direkt mittels zusätzlicher Argumente zu spezifizieren. Um zu erfahren, welche Argumente eine Funktion nutzen kann, könnt ihr in im unteren rechten Panel bei Help nachschauen.

Dazu schauen wir uns exemplarisch drei verschiedene Funktionen und einige ihrer Möglichkeiten im Umgang mit fehlenden Werten an.

na.omit in lm()

Mit lm() kann man eine lineare Regression durchführen. Hierbei kann man auch na.omit nutzen. Dabei wird bei Vorhandenseins eines Missings in einer Zeile die komplette Zeile aus der Berechnung genommen. Das ist der Default in lm(). Mit dem Argument na.action kann man auch andere Möglichkeiten einstellen.

In manchen Situationen ist es wichtig, Informationen darüber zu haben, wo Missings in einer Zeile sind (z.B. bei der Prüfung der Annahmen der Unabhängigkeit der Fehlerterme in der Multiplen Linearen Regression). Wenn ich beispielsweise einen Boxplot der Residuen einer linearen Regression in einer bestimmten Gruppe erstellen möchte, benötige ich einen Vektor der Residuen, in dem noch die Information darüber enthalten ist, in welcher Zeile Werte fehlen. Wenn der Residuenvektor und der Gruppenvektor unterschiedliche Zeilenanzahlen - in Abhängigkeit der Missings - haben, kann ich den Boxplot sonst nicht erstellen. Dafür nutze ich na.action=na.exclude. Hierbei werden die Indizes der Missings nicht einfach gelöscht (und dadurch die Zeilenanzahl reduziert) sondern mit gespeichert.

na.rm in mean()

Die Funktion mean() enthält das Argument na.rm, welches festlegt, ob einzelne fehlende Elemente vor der Ausführung der Funktion entfernt werden sollen. Man schreibt na.rm = TRUE wenn man diese entfernt haben möchte, und na.rm = FALSE wenn man sie behalten möchte. Bei vielen Funktionen ist letzteres voreingestellt (d.h. defaulted), was häufig aber eine Durchführung der Funktion verhindert.


mean(daten$Var_1) # kann nicht berechnet werden

[1] NA

mean(daten$Var_1, na.rm = TRUE)

[1] 1.5

Um den Unterschied zwischen na.omit und na.rm besser zu verstehen, schauen wir uns das noch etwas genauer an:

Während na.rm nur Missings variablenweise ausschließt, werden mit na.omit ganze Zeilen, in denen sich mindestens ein Missing befindet, ausgeschlossen. Schauen wir uns dazu einmal mit colMeans() die Spaltenmittelwerte an. Exemplarisch begrenzen wir das auf die ersten drei Spalten mit [1:3]. Für eine bessere Übersicht runden wir die Ergebnisse mit round().


round(colMeans(daten[1:3], na.rm = TRUE), 3) 

Var_1 Var_2 Var_3 
1.500 1.600 1.333 

round(colMeans(na.omit(daten[1:3])), 3)

Var_1 Var_2 Var_3 
1.000 1.667 1.333 

Wie wir sehen, ist nur der Mittelwert von Var_3 bei beiden Möglichkeiten gleichgeblieben. Bei den Mittelwerten der beiden anderen Spalten unterscheiden sich die Ergebnisse.


      Var_1 Var_2 Var_3
Vpn_1    NA     1    NA
Vpn_2     0     2     1
Vpn_3     1     3     3
Vpn_4     3     2    NA
Vpn_5     2     0     0

Die unterschiedlichen Spaltenmittelwerte kommen daher zustande, dass na.omit für alle Berechnungen Vpn_1 und Vpn_4 ausschließt, wohingegen na.rm die Missings nur in den Spalten ausschließt, die gerade zur Berechnung benötigt werden (z.B. Vpn_4 bei der Berechnung des Mittelwerts von Var_3, aber nicht bei denen von Var_1 und Var_2).

complete.obs und pairwise.complete.obs in cor()

Mit cor() kann man Korrelationstabellen berechnen. Dabei kann man mit dem Argument use festlegen, wie mit Missings umgegangen werden sollen. Wir beschränken uns hier auf zwei Möglichkeiten von use. Mit use = complete.obs wird eine Zeile, in der sich ein Missing befinden, aus allen (!) Berechnungen ausgeschlossen. Das ist vergleichbar mit dem Vorgehen von na.omit. Mit use = pairwise.complete.obs wird eine Zeile, in der sich ein Missing befinden, lediglich aus den Berechnungen, in denen die Spalte mit dem Missing genutzt wird, ausgeschlossen. Man kann das mit dem Vorgehen von na.rm vergleichen. Da wir für die Berechnung von einer Korrelation aber zwei Vektoren benötigen, ist das Vorgehen hier etwas anders. Für den Fall, dass man nur eine Korrelation zwischen zwei Vektoren berechnet, gibt es keinen Unterschied in der Berechnung der beiden Methoden (analog zu na.omit und na.rm bei einem Vektor).

Um den Unterschied zwischen den beiden Möglichkeiten besser zu verstehen, schauen wir uns die jeweiligen Korrelationstabellen an.

Exemplarisch schauen wir uns wieder nur die Korrelationen der ersten drei Variablen an. Dafür nutzen wir auch [1:3].

Zur Darstellung der Korrelationstabellen: Da die Korrelationsmatrix symmetrisch ist, d.h. ober- und unterhalb der Diagonalen gleich ist, wird die obere Diagonale für die Tabelle ausgeblendet.


cor_co <- cor(daten[1:3], use = "complete.obs")
cor_co <- round(cor_co, 3) 
Table 1: Korrelation mit complete.obs
Var_1 Var_2 Var_3
Var_1 1
Var_2 -0.655 1
Var_3 -0.327 0.929 1

cor_pco <- cor(daten[1:3],  use = "pairwise.complete.obs")
cor_pco <- round(cor_pco, 3)
Table 2: Korrelation mit pairwise.complete.obs
Var_1 Var_2 Var_3
Var_1 1
Var_2 -0.308 1
Var_3 -0.327 0.929 1

Wenn man die beiden Korrelationstabellen vergleicht, sieht man, dass sich die Korrelation zwischen Var_1 und Var_2 unterscheidet. Das liegt daran, dass Vpn_4 in allen Berechnungen mit complete.obs ausgeschlossen wurde, weil Var_3 dort ein Missing enthält, während pairwise.complete.obs diese Zeile bei der Korrelation von Var_1 und Var_2 miteinbezogen hat.


      Var_1 Var_2 Var_3
Vpn_1    NA     1    NA
Vpn_2     0     2     1
Vpn_3     1     3     3
Vpn_4     3     2    NA
Vpn_5     2     0     0

Aber: Im Gegensatz zu complete.obs basieren die Korrelationen bei pairwise.complete.obs auf Werten aus unterschiedlichen Zeilen (d.h. von unterschiedlichen Personen).


6. Literaturempfehlungen

Für ein tiefergehenden Einblick empfehlen wir Euch die folgenden Arbeiten:

“Missing Data” (S.431-451) aus dem Lehrbuch der Master-Vorlesung “Multivariate Verfahren”
Cohen, J., Cohen, P., West, S. G., & Aiken, L. S. (2003). Applied multiple regression/correlation analysis for the behavioral sciences (3rd ed.). Hillsdale: Erlbaum.
(für HU-Studierende online zugänglich)

“Missing Data” aus dem Handbuch für quantitive Methoden in Psychologie
Allison, P. D. (2002). Missing Data. In P. D. Allison (Ed.), The Sage Handbook of Quantitative Methods in Psychology (pp.72-89). Thousand Oaks, CA: Sage Publications Ltd.
(unter diesem Link zugänglich)

Little, R. J. A. (1988). A test of missing completely at random for multivariate data with missing values. Journal of the American Statistical Association, 83(404), 1198–1202.
(für HU-Studierende online zugänglich)