2011-11-02 10 views
55

Abbiamo un frame di dati da un file CSV. Il riquadro dati DF contiene colonne che contengono valori osservati e una colonna (VaR2) che contiene la data in cui è stata eseguita una misurazione. Se la data non è stata registrata, il file CSV contiene il valore NA, per i dati mancanti.Sottoinsieme di righe contenenti valori NA (mancanti) in una colonna scelta di un frame di dati

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

Vorremmo utilizzare il comando sottoinsieme per definire un nuovo frame di dati new_DF tale che esso contenga solo le righe che hanno un valore NA' dalla colonna (VaR2). Nell'esempio fornito, solo la riga 2 sarà contenuta nel nuovo DF.

Il comando

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

non funziona, il frame di dati risultante ha inserzioni di riga.

Se nel file CSV originale il valore NA viene scambiato con NULL, lo stesso comando produce il risultato desiderato: new_DF<-subset(DF,DF$Var2=="NULL").

Come posso far funzionare questo metodo, se per la stringa di caratteri è fornito il valore NA nel file CSV originale?

risposta

92

Non utilizzare mai == 'NA' per verificare i valori mancanti. Utilizzare invece is.na(). Questo dovrebbe farlo:

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

o nel caso in cui si desidera controllare una colonna particolare, è possibile utilizzare anche

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

Nel caso in cui si dispone di NA valori di carattere, prima esecuzione

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

per sostituirli con valori mancanti.

+2

Grazie per la vostra risposta veloce (questo è stato veloce)!Infatti, a causa del csv-delivery dei dati, i 'NA' sono valori di carattere e la tua seconda affermazione potrebbe essere molto utile. Puoi chiarire anche la tua prima affermazione? L'uso di rowSums() non è chiaro per me, dal momento che controllerò solo una particolare colonna (ci sono un sacco di colonne). Se quella particolare colonna (nell'esempio sarebbe la colonna Var2) ha una stringa di caratteri 'NA' (io la sostituirò con la tua seconda affermazione), quindi vorrei scegliere l'intera riga per far parte della nuova cornice dati . – John

+0

@John: aggiornato. Il punto è usare is.na, ho interpretato erroneamente che volevi controllare tutte le variabili. –

+3

dovrebbe essere 'new_DF <- DF [is.na (DF $ Var),]', cioè sembra esserci un extra '(' parentesi dopo 'DF ['? – PatrickT

34

NA è un valore speciale in R, non confondere il valore NA con la stringa "NA". A seconda del modo in cui i dati sono stati importati, le celle "NA" e "NULL" possono essere di vario tipo (il comportamento predefinito è convertire stringhe "NA" in valori NA e lasciare che le stringhe "NULL" siano).

Se si utilizza read.table() o read.csv(), è necessario considerare l'argomento "na.strings" per eseguire l'importazione di dati puliti e utilizzare sempre valori R NA reali.

Un esempio, lavorando in entrambi i casi "NULL" e cellule "NA":

DF <- read.csv("file.csv", na.strings=c("NA", "NULL")) 
new_DF <- subset(DF, is.na(DF$Var2)) 
+1

Grazie per la risposta. Se ho capito bene la prima affermazione farebbe lo stesso di Df [Df == 'NA'] <- NA nell'esempio di Joris? La (piccola) differenza sarebbe che è fatto direttamente nella tua statistica all'inizio, quando il frame dei dati viene creato (questo è un metodo di programmazione molto pulito e quindi mi piace) – John

+0

Esattamente. Joris ha suggerito di sostituire manualmente le stringhe "NA" con i valori NA, qui suggerisco solo di utilizzare la funzionalità "na.strings" di read.table() per raggiungere lo stesso scopo – maressyl

+0

La risposta di Joris è in realtà il modo "preferito" per realizzare questa impresa (se stai scrivendo questo in uno script). Vedi: http://stackoverflow.com/questions/9860090/in- r-why-is-better-than-subset – Jonathan

-1

Stampa tutte le righe con dati NA:

tmp <- data.frame(c(1,2,3),c(4,NA,5)); 
tmp[round(which(is.na(tmp))/ncol(tmp)),] 
+0

@ZheyuanLi Se la risposta non ti piace, basta votarla. Modificare la risposta per raccomandare la segnalazione NON è l'azione appropriata. Lascia un commento se ne senti la necessità. –

5

complete.casesTRUE quando tutti i valori in un riga non è NA

DF[!complete.cases(DF), ] 
+0

Di gran lunga il più veloce. –

1

Provare a cambiare questo:

new_DF<-dplyr::filter(DF,is.na(Var2)) 
+0

Puoi spiegare perché funziona, cosa fa ecc.? – csilk

+0

new_DF <-dplyr :: filter (DF, is.na (Var2)) utilizza fondamentalmente la funzione filtro del pacchetto dplyr e filtra qualsiasi osservazione nella colonna Var2 che soddisfa la condizione is.na cioè selezionano tutta l'osservazione con NA – drhnis

+0

Più espressamente espresso come 'DF%>% filter (is.na (Var2))' dopo 'library (dplyr)'. – Joe