So ersetzen Sie fehlende Werte (NA) in R: na.omit & na.rm
⚡ Intelligente Zusammenfassung
Das Ersetzen fehlender Werte in R umfasst das Erkennen von NA-Werten, das Entfernen unvollständiger Zeilen mit `na.omit()` und das Ersetzen dieser Werte durch den Mittelwert oder Median mittels `mutate()`. Diese Anleitung verwendet den Titanic-Datensatz, in dem sowohl Alter als auch Fahrpreis fehlende Werte aufweisen.
Was sind fehlende Werte in R?
Fehlende Werte treten auf, wenn in einer Spalte kein Wert für eine Beobachtung gespeichert ist oder wenn an der Stelle einer Zahl ein nicht-numerischer Platzhalter steht. Sie müssen vor jeder Berechnung entfernt oder ersetzt werden, da die meisten R-Funktionen NA zurückgeben, sobald ein fehlender Wert vorhanden ist.
Dieses Tutorial zeigt, wie man mit der dplyr-Bibliothek, die Teil des tidyverse-Ökosystems für die Datenanalyse ist, mit fehlenden Werten umgeht.
Der erste Schritt besteht immer darin, herauszufinden, wie viele Werte fehlen und wo.
Wie man fehlende Werte in R erkennt und zählt
Bevor Sie entscheiden, wie Sie mit fehlenden Werten umgehen, müssen Sie wissen, wie viele es sind und wo sie sich befinden. R bietet vier Prüfmöglichkeiten, von einer einfachen Ja/Nein-Antwort bis hin zur vollständigen Auflistung pro Spalte.
# 1. Is there any NA at all? anyNA(df_titanic) # 2. How many in total? sum(is.na(df_titanic)) # 3. How many per column, the most useful view colSums(is.na(df_titanic)) # 4. Percentage missing per column round(colMeans(is.na(df_titanic)) * 100, 1)
In der Praxis empfiehlt sich die Funktion `colSums()`. Sie gibt einen benannten Vektor mit einer Anzahl pro Spalte zurück und zeigt so sofort an, ob eine Variable einige wenige Werte vermissen lässt oder größtenteils leer ist.
Zählen vollständiger Zeilen. complete.cases() gibt TRUE für Zeilen zurück, die nirgendwo fehlende Werte enthalten, was Ihnen im Voraus mitteilt, wie viele Daten na.omit() verwerfen würde:
sum(complete.cases(df_titanic)) # rows that would survive sum(!complete.cases(df_titanic)) # rows that would be dropped
Ein Warnhinweis zu Platzhaltern. R erkennt nur NA. Datensätze kodieren fehlende Werte häufig als leere Zeichenkette, Leerzeichen, „N/A“, „-“ oder eine Sentinel-Nummer wie -99 oder 999. Diese werden bei allen oben genannten Prüfungen nicht erkannt. Konvertieren Sie sie beim Import, damit der restliche Workflow korrekt funktioniert.
df <- read.csv(PATH, na.strings = c("", " ", "NA", "N/A", "-", "-99"))
Überprüfen Sie nach dem Import immer den Wertebereich jeder numerischen Spalte. Ein Alter von -99 oder ein Fahrpreis von 9999 ist viel gefährlicher als ein korrekter NA-Wert, da keine Funktion Sie davor warnt.
Arten fehlender Daten: MCAR, MAR und MNAR
Die Gründe für das Fehlen eines Wertes entscheiden darüber, ob dessen Zuweisung sicher ist. Statistiker unterscheiden drei Mechanismen.
- MCAR, fehlt völlig zufällig. Die Wahrscheinlichkeit, dass etwas fehlt, steht in keinem Zusammenhang mit irgendetwas, ob beobachtet oder nicht, beispielsweise einem Sensor, der zufällig ausfällt.ping oder dass das Ersetzen dieser Zeilen keine Verzerrung, sondern lediglich einen Genauigkeitsverlust mit sich bringt.
- MAR, fehlt zufällig. Die Wahrscheinlichkeit hängt von anderen beobachteten Variablen ab, nicht aber vom fehlenden Wert selbst. Wenn bei älteren Passagieren die Wahrscheinlichkeit geringer ist, dass ihr Alter erfasst wurde, ist das Alter angesichts der anderen Spalten eine MAR (Missing Arbitrary Likelihood). Eine Imputation, die diese Spalten verwendet, kommt damit gut zurecht.
- MNAR, fehlt nicht zufällig. Die Wahrscheinlichkeit hängt vom fehlenden Wert selbst ab, beispielsweise davon, dass Gutverdiener ihr Einkommen nicht angeben. Kein Imputationsverfahren kann dies allein anhand der Daten beheben, und die fehlenden Werte selbst enthalten Informationen, die es wert sind, in einer Kennzeichnungsspalte festgehalten zu werden.
Die in diesem Tutorial verwendete Mittelwertimputation ist nur unter MCAR- und einfachen MAR-Bedingungen vertretbar. Selbst dann birgt sie bekannte Nachteile: Das Auffüllen jeder Lücke mit demselben Wert verringert die Varianz der Spalte und schwächt ihre Korrelation mit allen anderen Werten. Für anspruchsvollere Analysen empfiehlt sich ein modellbasiertes Verfahren wie das mice-Paket. Führen Sie stets eine Spalte, die die imputierten Werte kennzeichnet.
mutieren()
mutate() ist die dplyr Ein Verb, das eine neue Variable erzeugt oder eine bestehende überschreibt, ist daher das natürliche Werkzeug zum Erstellen einer bereinigten Kopie einer Spalte.
Wir werden in zwei Teilen vorgehen. Wir werden lernen, wie man:
- Fehlende Werte aus einem Datenrahmen ausschließen
- fehlende Werte mit Mittelwert und Median unterstellen
Das Verb mutate() ist sehr einfach zu verwenden. Wir können eine neue Variable mit dieser Syntax erstellen:
mutate(df, name_variable_1 = condition, ...) arguments: -df: Data frame used to create a new variable -name_variable_1: Name and the formula to create the new variable -...: No limit constraint. Possibility to create more than one variable inside mutate()
Fehlende Werte (NA) ausschließen
`na.omit()` ist eine Basisfunktion von R und kein Verb von dplyr, funktioniert aber trotzdem einwandfrei. Sie entfernt alle Zeilen, die mindestens einen fehlenden Wert (NA) enthalten. Das ist die schnellste, aber selten die beste Option, da ein einzelner fehlender Wert die gesamte Beobachtung verwirft.
Um das Problem fehlender Beobachtungen anzugehen, werden wir den Titanic-Datensatz verwenden. In diesem Datensatz haben wir Zugriff auf die Informationen der Passagiere an Bord während der Tragödie. Dieser Datensatz enthält viele NA, die berücksichtigt werden müssen.
Laden Sie die CSV-Datei aus dem Internet und listen Sie anschließend die Spalten auf, die NA enthalten:
PATH <- "https://raw.githubusercontent.com/guru99-edu/R-Programming/master/test.csv" df_titanic <- read.csv(PATH, sep = ",") # Return the column names containing missing observations list_na <- colnames(df_titanic)[ apply(df_titanic, 2, anyNA) ] list_na
Ausgang:
## [1] "age" "fare"
Dabei steht:
colnames(df_titanic)[apply(df_titanic, 2, anyNA)]
Gibt die Namen der Spalten zurück, die mindestens einen fehlenden Wert enthalten.
In den Spalten „Alter“ und „Tarif“ fehlen Werte.
Wir können sie mit na.omit() löschen.
library(dplyr) # Exclude the missing observations df_titanic_drop <-df_titanic %>% na.omit() dim(df_titanic_drop)
Ausgang:
## [1] 1045 13
Der neue Datensatz enthält 1045 Zeilen im Vergleich zu 1309 im ursprünglichen Datensatz.
Fehlende Daten durch Mittelwert und Median ersetzen
Fehlende Werte können durch den Mittelwert oder den Median ersetzt werden. Es empfiehlt sich, zwei separate Variablen für den Mittelwert und den Median anzulegen. Anschließend können die fehlenden Werte durch die neu erstellten Variablen ersetzt werden.
Wir werden die Apply-Methode verwenden, um den Mittelwert der Spalte mit NA zu berechnen. Sehen wir uns ein Beispiel an
Schritt 1) Zu Beginn des Tutorials haben wir den Spaltennamen mit den fehlenden Werten in der Liste list_na gespeichert. Wir werden diese Liste verwenden
Schritt 2) Berechnen Sie den Mittelwert mit dem Argument `na.rm = TRUE`. Dieses Argument ist erforderlich, da die Spalten fehlende Daten enthalten; es weist R an, diese zu ignorieren.
# Create mean average_missing <- apply(df_titanic[,colnames(df_titanic) %in% list_na], 2, mean, na.rm = TRUE) average_missing
Code Erläuterung:
Wir übergeben 4 Argumente in der apply-Methode.
- df: df_titanic[,colnames(df_titanic) %in% list_na]. Dieser Code gibt den Spaltennamen aus dem list_na-Objekt zurück (z. B. „Alter“ und „Fahrpreis“).
- 2: Berechnen Sie die Funktion für die Spalten
- Mittelwert: Berechnen Sie den Mittelwert
- na.rm = TRUE: Fehlende Werte ignorieren
Ausgang:
## age fare ## 29.88113 33.29548
Wir haben erfolgreich den Mittelwert der Spalten erstellt, die fehlende Beobachtungen enthalten. Diese beiden Werte werden verwendet, um die fehlenden Beobachtungen zu ersetzen.
Schritt 3) Ersetzen Sie die NA-Werte
Das Verb mutate aus der dplyr-Bibliothek ist nützlich beim Erstellen einer neuen Variablen. Wir möchten nicht unbedingt die ursprüngliche Spalte ändern, damit wir eine neue Variable ohne NA erstellen können. Mutate ist einfach zu verwenden. Wir wählen einfach einen Variablennamen und definieren, wie diese Variable erstellt wird. Hier ist der vollständige Code
# Create a new variable with the mean and median df_titanic_replace <- df_titanic %>% mutate(replace_mean_age = ifelse(is.na(age), average_missing[1], age), replace_mean_fare = ifelse(is.na(fare), average_missing[2], fare))
Code Erläuterung:
Wir erstellen zwei Variablen, replace_mean_age und replace_mean_fare, wie folgt:
- replace_mean_age = ifelse(is.na(age), Average_missing[1], age)
- replace_mean_fare = ifelse(is.na(fare), Average_missing[2],fare)
Wenn in der Spalte „Alter“ Werte fehlen, ersetzen Sie diese durch das erste Element von „average_missing“ (Mittelwert des Alters). Andernfalls behalten Sie die ursprünglichen Werte bei. Dieselbe Logik für den Fahrpreis
sum(is.na(df_titanic_replace$age))
Ausgang:
## [1] 263
Nach dem Austausch enthält die neue Spalte überhaupt keine fehlenden Werte mehr:
sum(is.na(df_titanic_replace$replace_mean_age))
Ausgang:
## [1] 0
Die ursprüngliche Spalte „Alter“ enthält 263 fehlende Werte, während in der neuen Spalte „replace_mean_age“ alle diese Werte durch das Durchschnittsalter ersetzt wurden.
Schritt 4) Wir können die fehlenden Beobachtungen auch durch den Median ersetzen.
median_missing <- apply(df_titanic[,colnames(df_titanic) %in% list_na], 2, median, na.rm = TRUE) df_titanic_replace <- df_titanic %>% mutate(replace_median_age = ifelse(is.na(age), median_missing[1], age), replace_median_fare = ifelse(is.na(fare), median_missing[2], fare)) head(df_titanic_replace)
Ausgang:
Schritt 5) Bei großen Datensätzen wird die schrittweise Vorgehensweise mühsam. Die Funktion `sapply()` fasst den gesamten Vorgang in einer einzigen Anweisung zusammen, allerdings werden die imputierten Werte dabei nicht angezeigt.
sapply erstellt kein Datenrahmen, sodass wir die Funktion sapply() in data.frame() einschließen können, um ein Datenrahmenobjekt zu erstellen.
# Quick code to replace missing values with the mean df_titanic_impute_mean <- data.frame( sapply( df_titanic, function(x) ifelse(is.na(x), mean(x, na.rm = TRUE), x)))
Moderne Imputation mit replace_na() und across()
Die oben genannten Ansätze apply() und sapply() funktionieren weiterhin, aber tidyr und dplyr drücken dieselben Operationen jetzt sicherer und lesbarer aus.
replace_na() für feste Werte. tidyr::replace_na() erwartet eine benannte Liste von Spalten und deren Ersetzungen:
library(tidyr) df_titanic %>% replace_na(list(age = 29.88, fare = 33.30))
across() für jede numerische Spalte. Dies ist der direkte, typsichere Ersatz für die Einzeiler-Funktion sapply(), und im Gegensatz zu sapply() greift sie niemals auf Zeichen- oder Faktorspalten zu:
library(dplyr) # Mean-impute every numeric column df_titanic %>% mutate(across(where(is.numeric), ~ ifelse(is.na(.x), mean(.x, na.rm = TRUE), .x))) # Median-impute instead df_titanic %>% mutate(across(where(is.numeric), ~ ifelse(is.na(.x), median(.x, na.rm = TRUE), .x)))
⚠️ Warum die sapply()-Abkürzung riskant ist: Das einzeilige sapply()-Beispiel läuft über alles, Die Spalte enthält sowohl Zeichenketten als auch Faktoren. Der Aufruf von `mean()` gibt `NA` mit einer Warnung zurück, und `sapply()` wandelt das gesamte Ergebnis anschließend in eine Zeichenkette um. Die oben verwendete Variante `cross(where(is.numeric), …)` umgeht dieses Problem vollständig.
coalesce() für Fallback-Spalten. Wenn eine zweite Spalte den fehlenden Wert liefern kann, gibt coalesce() den ersten nicht fehlenden Eintrag aller Argumente zurück:
df %>% mutate(age_final = coalesce(age, age_estimated, 0))
Notieren Sie sich, was Sie geändert haben. Fügen Sie vor der Imputation ein Flag hinzu, damit spätere Modelle aus der Tatsache lernen können, dass ein Wert fehlte:
df_titanic %>%
mutate(age_was_missing = is.na(age),
age = ifelse(is.na(age), mean(age, na.rm = TRUE), age))
Umgang mit fehlenden Werten in R: Methodenreferenz
In diesem Tutorial werden drei Ansätze behandelt:
- Schließen Sie alle fehlenden Beobachtungen aus
- Mit dem Mittelwert imputieren
- Mit dem Median imputieren
Die folgende Tabelle fasst Erkennung und Entfernung zusammen:
| Bibliothek | Ziel | Code |
|---|---|---|
| Base | Listen Sie fehlende Beobachtungen auf |
colnames(df)[apply(df, 2, anyNA)] |
| Base | Entfernen Sie alle Zeilen, die NA enthalten. |
na.omit(df) |
Die Imputation mit Mittelwert oder Median kann auf zwei Arten erfolgen
- Mit apply
- Verwendung von Sapply
| Methodik | Details | Vorteile | Nachteile |
|---|---|---|---|
| Schritt für Schritt mit bewerben | Überprüfen Sie die fehlenden Spalten, berechnen Sie den Mittelwert/Median, speichern Sie den Wert und ersetzen Sie ihn durch mutate() | Sie können den berechneten Mittelwert oder Median sehen. | Mehr Ausführungszeit. Kann bei großen Datensätzen langsam sein |
| Schneller Weg mit Sapply | Verwenden Sie sapply() und data.frame(), um fehlende Werte automatisch zu suchen und durch Mittelwert/Median zu ersetzen | Kurzer Code und schnell | Die berechneten Werte werden nie angezeigt. |




