Sottoinsieme di righe contenenti valori NA (mancanti) in una colonna scelta di un frame di dati


96

Abbiamo un data frame da un file CSV. Il data frame DFha 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.

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

Vorremmo utilizzare il comando subset per definire un nuovo frame di dati in new_DFmodo che contenga solo righe che hanno un NA'valore 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 data frame risultante non ha voci di riga.

Se nel file CSV originale Valore NAvengono scambiati 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 il valore NAè fornito nel file CSV originale?

Risposte:


145

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

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

o nel caso in cui desideri controllare una particolare colonna, puoi anche usare

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

Nel caso in cui tu abbia valori di caratteri NA, esegui prima

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

per sostituirli con valori mancanti.


2
Grazie per la tua risposta veloce (questa è stata veloce)! In effetti, a causa della consegna csv dei dati, "NA" sono valori di caratteri e la tua seconda affermazione potrebbe essere molto utile. Puoi anche chiarire la tua prima affermazione? L'uso di rowSums () non è chiaro per me, poiché controllerò solo una particolare colonna (ce ne sono molte). Se quella particolare colonna (nell'esempio sarebbe la colonna Var2) ha una stringa di caratteri 'NA' (la sostituirò con la tua seconda istruzione), allora vorrei scegliere l'intera riga come parte del nuovo frame di dati .
Giovanni

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

3
dovrebbe essere new_DF <- DF[is.na(DF$Var),], cioè sembra che ci sia una (parentesi extra dopo DF[?
PatrickT

39

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 le stringhe "NA" in valori NA e lasciare le stringhe "NULL" così come sono).

Se usi read.table () o read.csv (), dovresti considerare l'argomento "na.strings" per eseguire un'importazione pulita dei dati e lavorare sempre con valori R NA reali.

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

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

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

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

La risposta di Joris è in realtà il modo "preferito" per realizzare questa impresa (se stai scrivendo questo in una sceneggiatura). Vedi: stackoverflow.com/questions/9860090/…
Jonathan

@ Jonathan: Due idee distinte qui, l'argomento che citi dice "[" dovrebbe essere preferito su "subset", ma stavamo parlando dell'argomento "na.strings" in read.table (), il mio sottoinsieme era qui solo per visualizzare gli effetti.
maressyl

32

complete.casesTRUEquando tutti i valori in una riga non lo sonoNA

DF[!complete.cases(DF), ]

11
new_data <- data %>% filter_all(any_vars(is.na(.))) 

Questo dovrebbe creare un nuovo data frame ( new_data) con solo i valori mancanti in esso.

Funziona meglio per tenere traccia dei valori che potresti successivamente eliminare perché avevano alcune colonne con osservazioni mancanti (NA).


3

Prova a cambiare questo:

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

Potresti spiegare perché funziona, cosa fa ecc.?
csilk

new_DF <-dplyr :: filter (DF, is.na (Var2)) fondamentalmente usa la funzione di filtro del pacchetto dplyr e filtra qualsiasi osservazione nella colonna Var2 che soddisfi la condizione is.na cioè scelgono tutte le osservazioni con NA
drhnis

1
Più piacevolmente espresso come DF %>% filter(is.na(Var2))dopo library(dplyr).
Joe

-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)),]

@ZheyuanLi Se non ti piace la risposta, votala semplicemente per difetto. Modificare la risposta per consigliare di contrassegnare NON è l'azione appropriata. Lascia un commento se ne senti il ​​bisogno.
Manfred Radlwimmer
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.