anyNA()
unique()
is.na()
complete.cases()
Fehlende Werte treten in realen Datensätzen aus unterschiedlichsten Gründen häufig auf, z.B. weil die Information nicht verfügbar ist (weil eine Person die Antwort auf eine Frage verweigert), weil die Information auf eine Person nicht zutrifft (weil ein Unternehmen, das nur im Inland tätig ist, kein Exportvolumen angeben kann) oder weil die Information aus aus Datenschutzgründen nicht weitergegeben wird (weil eine Person ansonsten eindeutig identifizierbar wäre). In R werden fehlende Werte mit NA
(= “not available”) gekennzeichnet. Um diese fehlenden Werte in R zu identifizieren gibt es mehrere Möglichkeiten.
anyNA()
Um zu überprüfen, ob ein Merkmal fehlende Werte aufweist, verwendet man in R die Funtion anyNA(data$X)
. Das Ergebnis dieser Funktion ist TRUE
, wenn die Variable X
im Datensatz data
zumindest einen fehlenden Wert hat (sonst ergibt sie FALSE
).
Zur Veranschaulichung verwenden wir die Daten aus der Passagierliste der Titanic, welche in der Datei titanic.RData
enthalten sind:
load("titanic.RData")
Weist das Merkmal Alter (age
) fehlende Werte auf? Wir verwenden dazu den anyNA()
-Befehl:
anyNA(titanic$age)
## [1] TRUE
Das Ergebnis des Befehls ist TRUE
: Das Merkmal age
im Datensatz titanic
hat fehlende Werte. Wie sieht es mit dem Merkmal Passagierklasse (pclass
) aus? Weist auch dieses fehlende Werte auf?
anyNA(titanic$pclass)
## [1] FALSE
Hier ist das Ergebnis FALSE
: Das Merkmal pclass
im Datensatz titanic
weist keine fehlenden Werte auf.
Wie kann man nun schnell für alle Variablen in einem Datensatz eruieren, ob sie fehlende Werte beinhalten? Dazu nutzen wir die Funktion sapply(data, funktion)
. sapply()
wendet die funktion
automatisch auf jede Spalte (= jede Variable) eines Datensatzes data
. Der Befehl:
sapply(titanic, anyNA)
## pclass survived name sex age sibsp parch
## FALSE FALSE FALSE FALSE TRUE FALSE FALSE
## ticket fare cabin embarked boat body home.dest
## FALSE TRUE FALSE FALSE FALSE TRUE FALSE
evaluiert also für alle Spalten (= Variablen) im Datensatz titanic
die Funktion anyNA()
. Wir sehen, dass neben age
auch die Merkmale fare
und body
fehlende Werte aufweisen.
Anstelle von anyNA
kann man in sapply()
auch beliebige andere Funktionen einsetzen. Die sapply-Funktion gehört zu einer Reihe von R-Befehlen, die wiederholende Aufgaben (wie die Evaluierung, ob eine Variable NA
s enthält) schneller erledigt. Mehr über diese Funktion (und weitere apply-Funktionen) lernen sie im swirl-Kurs “R Programming”.
unique()
Eine weitere Möglichkeit ist die Verwendung der Funktion unique(data$X)
. Diese identifiziert alle unterschiedlichen Ausprägungen eines Merkmals X
, die im Datensatz zumindest einmal vorkommen. Befindet sich darunter auch der Wert NA
, weist das Merkmal fehlende Werte auf.
unique(titanic$age)
## [1] 29.00 0.92 2.00 30.00 25.00 48.00 63.00 39.00 53.00 71.00 47.00
## [12] 18.00 24.00 26.00 80.00 NA 50.00 32.00 36.00 37.00 42.00 19.00
## [23] 35.00 28.00 45.00 40.00 58.00 22.00 41.00 44.00 59.00 60.00 33.00
## [34] 17.00 11.00 14.00 49.00 76.00 46.00 27.00 64.00 55.00 70.00 38.00
## [45] 51.00 31.00 4.00 54.00 23.00 43.00 52.00 16.00 32.50 21.00 15.00
## [56] 65.00 28.50 45.50 56.00 13.00 61.00 34.00 6.00 57.00 62.00 67.00
## [67] 1.00 12.00 20.00 0.83 8.00 0.67 7.00 3.00 36.50 18.50 5.00
## [78] 66.00 9.00 0.75 70.50 22.50 0.33 0.17 40.50 10.00 23.50 34.50
## [89] 20.50 30.50 55.50 38.50 14.50 24.50 60.50 74.00 0.42 11.50 26.50
Das Ergebnis des Befehls ist eine Liste, in der sich auch der Wert NA
befindet. Das Merkmal age
beinhaltet daher fehlende Werte.
Kann ein Merkmal viele unterschiedliche Werte annehmen (wie age
) kann die Überprüfung auf den Wert NA
jedoch schnell unübersichtlich werden. unique()
eignet sich in diesem Kontext daher nur für Merkmale mit wenigen Ausprägungen.
Hinweis: Das Ergebnis von unique()
ist nicht mit dem Wertebereich des Merkmals \(\Omega_X\) gleichzusetzen. Der Wertebereich \(\Omega_X\) eines Merkmals \(X\) kann z.B. Werte annehmen, welche dann in den empirisch beobachteten Werten des Merkmals X
nicht vorkommen. Z.B. beinhaltet der Wertebereich des Merkmals Alter (die Menge jener Werte, welche das Merkmal prinzipiell annehmen kann) den Wert 68. Es gibt keinen Grund, warum ein Passagier nicht 68 Jahre alt sein könnte. Im Datensatz findet sich jedoch keine Person, welche dieses Alter aufweist. Zudem kann das empirische Merkmal die Ausprägung NA
annehmen, welche nicht zum Wertebereich \(\Omega_X\) zählt: Auch eine Person, für die age
gleich NA
ist, hat ein Alter (nur ist es nicht bekannt). NA
ist damit nicht Teil des Wertebereichs \(\Omega_X\), kann aber in den empirischen Daten dennoch vorkommen.
is.na()
Möchte man wissen, welche Beobachtungen fehlende Werte für ein bestimmtes Merkmal aufweisen, verwendet man die Funktion is.na(data$X)
. Diese überprüft für jede statistische Einheit (für jede “Zeile”) im Datensatz data
, ob die Variable X
für diese Einheit den Wert NA
(= “not available”) beinhaltet. Das Ergebnis ist ein Vektor (eine Reihe von Werten) mit gleich vielen Elementen wie Zeilen im Datensatz, der entweder den Wert TRUE
(wenn der Wert tatsächlich nicht verfügbar ist) oder FALSE
(wenn für X ein Wert vorhanden ist) beinhaltet.
Wir überprüfen nun für jede Person auf der Passagierliste, ob das Alter (Merkmal age
) der Person bekannt ist oder nicht (gekürzte Darstellung):
is.na(titanic$age)
## [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [12] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
## [23] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [34] FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE
## [45] FALSE FALSE TRUE FALSE FALSE FALSE
Wir sehen, dass für die meisten Personen das Alter beobachtet wird (is.na()
ergibt FALSE
), während für einige Beobachtungen der Wert fehlt (is.na()
ergibt TRUE
). Da die logischen Werte TRUE
und FALSE
von R mit 1 (TRUE
) und 0 (FALSE
) gleichgesetzt werden, können wir mit der Funktion sum()
die Summe aus diesen Angaben berechnen. Dies gibt uns an, in wie vielen Zeilen des Datensatzes die Variable NA
ist und fehlt:
sum(is.na(titanic$age))
## [1] 263
Wir sehen also, dass es 263 fehlende Beobachtungen für das Merkmal age
im Datensatz titanic
gibt.
Wie viele Beobachtungen haben keine fehlenden Werte? In R können logische Auswertungen (die entweder TRUE
oder FALSE
ergeben) mit einem Rufzeichen !
umgekehrt werden. D.h. die Angabe:
!is.na(titanic$age)
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [12] TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE
## [23] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [34] TRUE TRUE TRUE TRUE FALSE TRUE TRUE FALSE TRUE TRUE TRUE
## [45] TRUE TRUE FALSE TRUE TRUE TRUE
ergibt genau das Gegenteil der obigen Auswertung: Wo oben TRUE
steht, steht nun FALSE
und vice versa. Dementsprechend erhält man mit:
sum(!is.na(titanic$age))
## [1] 1046
die Anzahl der Beobachtungen im Datensatz titanic
, für die das Merkmal age
nicht fehlt (1046).
complete.cases()
Möchte man wissen, welche Beobachtungen in einem Datensatz data
vollständig sind (also keine fehlenden Werte beinhalten), kann man den Befehl complete.cases(data)
verwenden. Dieser überprüft für jede Zeile im Datensatz data
(= jede Beobachtung), ob die Beobachtung “vollständig” ist, d.h. keine fehlenden Werte beinhaltet (TRUE
). Ist irgendein Merkmal einer Beobachtung NA
, ergibt complete.cases()
für diese Beobachtung den Wert FALSE
(gekürzte Darstellung):
complete.cases(titanic)
## [1] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE TRUE TRUE
## [12] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [23] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [34] FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
## [45] FALSE FALSE FALSE FALSE FALSE FALSE
Wir sehen, dass für die meisten Beobachtungen das Ergebnis des Befehls FALSE
ist: Die Beobachtungen sind nicht “komplett”, sondern weisen für mindestens ein Merkmal einen fehlenden Wert auf.
Mit dem sum()
-Befehl kann man erneut zählen, wie viele Beobachtungen komplett sind:
sum(complete.cases(titanic))
## [1] 119
Im Datensatz titanic
sind dies nur 119 Beobachtungen, für 1190 Beobachtungen fehlt mindestens ein Merkmal!
Zur Extraktion der vollständigen Beobachtungen stellt R den Befehl na.omit(data)
zur Verfügung. Der Befehl
titanic_keine_na <- na.omit(titanic)
extrahiert die kompletten Beobachtungen des Datensatzes titanic
und speichert diese in einem neuen Datensatz titanic_keine_na
ab.