Teilmenge von Zeilen mit NA-Werten (fehlende Werte) in einer ausgewählten Spalte eines Datenrahmens

95

Wir haben einen Datenrahmen aus einer CSV-Datei. Der Datenrahmen DFenthält Spalten, die beobachtete Werte enthalten, und eine Spalte ( VaR2), die das Datum enthält, an dem eine Messung durchgeführt wurde. Wenn das Datum nicht aufgezeichnet wurde, enthält die CSV-Datei den Wert NAfür fehlende Daten.

Var1  Var2 
10   2010/01/01
20   NA
30   2010/03/01

Wir möchten den Befehl subset verwenden, um einen neuen Datenrahmen new_DFso zu definieren, dass er nur Zeilen enthält, die einen NA'Wert aus der Spalte ( VaR2) haben. In dem angegebenen Beispiel wird nur Zeile 2 in der neuen enthalten sein DF.

Der Befehl

new_DF<-subset(DF,DF$Var2=="NA") 

funktioniert nicht, der resultierende Datenrahmen hat keine Zeileneinträge.

Wenn in der ursprünglichen CSV-Datei der Wert NAausgetauscht wird NULL, führt derselbe Befehl zum gewünschten Ergebnis : new_DF<-subset(DF,DF$Var2=="NULL").

Wie kann ich diese Methode zum Laufen bringen, wenn für die Zeichenfolge der Wert NAin der ursprünglichen CSV-Datei angegeben ist?

John
quelle

Antworten:

143

Verwenden Sie niemals == 'NA', um auf fehlende Werte zu testen. Verwenden Sie is.na()stattdessen. Dies sollte es tun:

new_DF <- DF[rowSums(is.na(DF)) > 0,]

oder falls Sie eine bestimmte Spalte überprüfen möchten, können Sie auch verwenden

new_DF <- DF[is.na(DF$Var),]

Wenn Sie NA-Zeichenwerte haben, führen Sie diese zuerst aus

Df[Df=='NA'] <- NA

um sie durch fehlende Werte zu ersetzen.

Joris Meys
quelle
2
Vielen Dank für Ihre schnelle Antwort (das war schnell)! In der Tat sind die 'NA' aufgrund der CSV-Übermittlung der Daten Zeichenwerte, und Ihre zweite Aussage kann sehr nützlich sein. Können Sie auch Ihre erste Aussage klarstellen? Die Verwendung von rowSums () ist für mich nicht klar, da ich nur eine bestimmte Spalte überprüfen werde (es gibt viele Spalten). Wenn diese bestimmte Spalte (im Beispiel wäre es die Spalte Var2) eine 'NA'-Zeichenfolge enthält (ich werde sie durch Ihre zweite Anweisung ersetzen), möchte ich die gesamte Zeile als Teil des neuen Datenrahmens auswählen .
John
@ John: aktualisiert. Der Punkt ist, is.na zu verwenden. Ich habe falsch interpretiert, dass Sie alle Variablen überprüfen wollten.
Joris Meys
3
sollte das sein new_DF <- DF[is.na(DF$Var),], dh es scheint eine zusätzliche (Klammer danach zu geben DF[?
PatrickT
39

NA ist ein spezieller Wert in R, verwechseln Sie den NA-Wert nicht mit der Zeichenfolge "NA". Abhängig von der Art und Weise, wie die Daten importiert wurden, können Ihre "NA" - und "NULL" -Zellen unterschiedlichen Typs sein (das Standardverhalten besteht darin, "NA" -Strings in NA-Werte zu konvertieren und "NULL" -Strings unverändert zu lassen).

Wenn Sie read.table () oder read.csv () verwenden, sollten Sie das Argument "na.strings" berücksichtigen, um einen sauberen Datenimport durchzuführen, und immer mit echten R NA-Werten arbeiten.

Ein Beispiel für die Arbeit in beiden Fällen "NULL" - und "NA" -Zellen:

DF <- read.csv("file.csv", na.strings=c("NA", "NULL"))
new_DF <- subset(DF, is.na(DF$Var2))
Maressyl
quelle
1
Danke für deine Antwort. Wenn ich es richtig verstehe, würde die erste Aussage dasselbe tun wie Df [Df == 'NA'] <- NA im Beispiel von Joris? Der (kleine) Unterschied wäre dann, dass es in Ihrer Anweisung direkt am Anfang gemacht wird, wenn der Datenrahmen erstellt wird (dies ist eine sehr saubere Programmiermethode und ich mag sie daher).
John
Genau. Joris schlug vor, "NA" -Strings manuell durch NA-Werte zu ersetzen. Hier empfehle ich nur, die "na.strings" -Funktion von read.table () zu verwenden, um den gleichen Zweck zu erreichen.
Maressyl
Joris 'Antwort ist eigentlich der "bevorzugte" Weg, um dieses Kunststück zu vollbringen (wenn Sie dies in einem Skript schreiben). Siehe: stackoverflow.com/questions/9860090/…
Jonathan
@Jonathan: Zwei unterschiedliche Ideen hier, das Thema, das Sie zitieren, sagt "[" sollte bei "Teilmenge" bevorzugt werden, aber wir sprachen über das Argument "na.strings" in read.table (), meine Teilmenge war nur zur Visualisierung hier die Effekte.
Maressyl
31

complete.casesgibt an, TRUEwenn nicht alle Werte in einer Zeile sindNA

DF[!complete.cases(DF), ]
user3226167
quelle
11
new_data <- data %>% filter_all(any_vars(is.na(.))) 

Dadurch sollte ein neuer Datenrahmen ( new_data) erstellt werden, in dem nur die fehlenden Werte enthalten sind.

Funktioniert am besten, um die Werte zu verfolgen, die Sie später möglicherweise löschen, da sie einige Spalten mit fehlenden Beobachtungen (NA) enthielten.

Ronak Pol
quelle
3

Versuchen Sie dies zu ändern:

new_DF<-dplyr::filter(DF,is.na(Var2)) 
drhnis
quelle
Können Sie erklären, warum dies funktioniert, was dies tut usw.?
Csilk
new_DF <-dplyr :: filter (DF, is.na (Var2)) verwendet grundsätzlich die Filterfunktion des dplyr-Pakets und filtert alle Beobachtungen in der Var2-Spalte heraus, die die Bedingung is.na erfüllen, dh sie wählen alle Beobachtungen mit NA aus
Drhnis
1
Schöner ausgedrückt als DF %>% filter(is.na(Var2))danach library(dplyr).
Joe
-1

Druckt alle Zeilen mit NA-Daten:

tmp <- data.frame(c(1,2,3),c(4,NA,5));
tmp[round(which(is.na(tmp))/ncol(tmp)),]
jstar
quelle
@ZheyuanLi Wenn Ihnen die Antwort nicht gefällt, stimmen Sie sie einfach ab. Das Bearbeiten der Antwort, um das Markieren zu empfehlen, ist NICHT die geeignete Aktion. Hinterlasse einen Kommentar, wenn du das Bedürfnis hast.
Manfred Radlwimmer