Podzbiór wierszy zawierających wartości NA (brakujące) w wybranej kolumnie ramki danych


96

Mamy ramkę danych z pliku CSV. Ramka danych DFzawiera kolumny zawierające zaobserwowane wartości i kolumnę ( VaR2) zawierającą datę wykonania pomiaru. Jeśli data nie została zarejestrowana, plik CSV zawiera wartość NAdla brakujących danych.

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

Chcielibyśmy użyć polecenia podzestaw, aby zdefiniować nową ramkę danych, new_DFtak aby zawierała tylko wiersze, które mają NA'wartość z kolumny ( VaR2). W podanym przykładzie tylko wiersz 2 będzie zawarty w nowym DF.

Komenda

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

nie działa, wynikowa ramka danych nie zawiera wpisów wierszy.

Jeśli w oryginalnym pliku CSV Value NAsą wymieniane NULL, to samo polecenie wywołuje pożądany efekt: new_DF<-subset(DF,DF$Var2=="NULL").

Jak mogę sprawić, by ta metoda działała, jeśli dla ciągu znaków wartość NAjest podana w oryginalnym pliku CSV?

Odpowiedzi:


148

Nigdy nie używaj == 'NA' do testowania brakujących wartości. Użyj is.na()zamiast tego. To powinno wystarczyć:

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

lub jeśli chcesz sprawdzić konkretną kolumnę, możesz również użyć

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

Jeśli masz wartości znaków NA, najpierw uruchom

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

aby zastąpić je brakującymi wartościami.


2
Dzięki za szybką odpowiedź (to było szybkie)! Rzeczywiście, ze względu na dostarczenie danych w formacie csv, „NA” to wartości znakowe, a Twoje drugie stwierdzenie może być bardzo przydatne. Czy możesz również wyjaśnić swoje pierwsze stwierdzenie? Użycie funkcji rowSums () nie jest dla mnie jasne, ponieważ sprawdzę tylko konkretną kolumnę (kolumn jest wiele). Jeśli ta konkretna kolumna (w przykładzie byłaby to kolumna Var2) zawiera ciąg znaków `` NA '' (zastąpię go Twoim drugim stwierdzeniem), to chciałbym wybrać cały wiersz jako część nowej ramki danych .
Jan

@John: zaktualizowany. Chodzi o to, aby użyć is.na, błędnie zinterpretowałem, że chcesz sprawdzić wszystkie zmienne.
Joris Meys

3
czy tak powinno być new_DF <- DF[is.na(DF$Var),], tj. wydaje się, że po nim jest dodatkowy (nawias DF[?
PatrickT,

39

NA to specjalna wartość w R, nie należy mylić wartości NA z ciągiem „NA”. W zależności od sposobu importowania danych, komórki „NA” i „NULL” mogą być różnego typu (domyślnym zachowaniem jest konwersja ciągów „NA” na wartości NA i pozostawienie ciągów „NULL” bez zmian).

Jeśli używasz read.table () lub read.csv (), powinieneś rozważyć argument "na.strings", aby dokonać czystego importu danych i zawsze pracować z prawdziwymi wartościami R NA.

Przykład działający w obu przypadkach komórki „NULL” i „NA”:

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

1
Dzięki za odpowiedź. Jeśli dobrze zrozumiem, pierwsze stwierdzenie zrobiłoby to samo, co Df [Df == 'NA'] <- NA w przykładzie Jorisa? (Mała) różnica polegałaby wówczas na tym, że jest to wykonywane bezpośrednio na początku, kiedy ramka danych jest tworzona (jest to bardzo czysta metoda programowania i dlatego mi się podoba).
Jan

Dokładnie. Joris zasugerował ręczne zastąpienie ciągów „NA” wartościami NA, tutaj sugeruję tylko użycie funkcji „na.strings” funkcji read.table (), aby osiągnąć ten sam cel.
maressyl

Odpowiedź Jorisa jest właściwie „preferowanym” sposobem osiągnięcia tego wyczynu (jeśli piszesz to w scenariuszu). Zobacz: stackoverflow.com/questions/9860090/…
Jonathan

@Jonathan: Dwa różne pomysły, cytowany temat mówi: „[” powinno być preferowane jako „podzbiór”, ale rozmawialiśmy o argumencie „na.strings” w read.table (), mój podzbiór był tutaj tylko po to, aby zwizualizować efekty.
maressyl

34

complete.casespodaje, TRUEkiedy wszystkie wartości w wierszu nie sąNA

DF[!complete.cases(DF), ]

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

Powinno to spowodować utworzenie nowej ramki danych ( new_data) zawierającej tylko brakujące wartości.

Najlepiej jest śledzić wartości, które możesz później upuścić, ponieważ zawierały one kolumny z brakującymi obserwacjami (NA).


3

Spróbuj to zmienić:

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

Czy możesz wyjaśnić, dlaczego to działa, co robi itp.?
csilk

new_DF <-dplyr :: filter (DF, is.na (Var2)) w zasadzie używa funkcji filtrującej pakietu dplyr i odfiltrowuje wszelkie obserwacje w kolumnie Var2, które spełniają warunek is.na tj. wybierają wszystkie obserwacje z NA
drhnis

1
Ładniej wyrażone jak DF %>% filter(is.na(Var2))po library(dplyr).
Joe

-1

Drukuje wszystkie wiersze z danymi NA:

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

@ZheyuanLi Jeśli odpowiedź Ci się nie podoba, po prostu zagłosuj w dół. Edycja odpowiedzi w celu rekomendowania zgłaszania NIE JEST właściwym działaniem. Zostaw komentarz, jeśli czujesz taką potrzebę.
Manfred Radlwimmer
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.