2011-11-02 18 views
55

Posiadamy ramkę danych z pliku CSV. Ramka danych DF ma kolumny, które zawierają obserwowane wartości i kolumnę (VaR2), która zawiera datę, w której dokonano pomiaru. Jeśli data nie została zarejestrowana, plik CSV zawiera wartość NA dla brakujących danych.Podzbiór wierszy zawierających wartości NA (brakujące) w wybranej kolumnie ramki danych

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

Chcielibyśmy użycie polecenia podzbiór zdefiniować nową ramkę danych new_DF tak, że zawiera tylko wierszy, które mają wartość NA' z kolumny (VaR2). W podanym przykładzie tylko wiersz 2 będzie zawarty w nowym DF.

Polecenie

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

nie działa, wynikający ramki danych nie ma pozycji rzędu.

Jeśli w oryginalnym pliku CSV wartość NA zostanie wymieniona na NULL, to samo polecenie wygeneruje oczekiwany wynik: new_DF<-subset(DF,DF$Var2=="NULL").

Jak mogę uruchomić tę metodę, jeśli dla ciągu znaków wartość NA jest podana w oryginalnym pliku CSV?

Odpowiedz

92

Nigdy nie używaj == 'NA' do testowania brakujących wartości. Zamiast tego użyj is.na(). Należy to zrobić:

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

lub w przypadku, gdy chcesz sprawdzić konkretną kolumnę, można również użyć

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

w przypadku gdy masz NA charakter wartości, najpierw uruchomić

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

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

+2

Dzięki za szybką odpowiedź (to było szybkie)!Rzeczywiście, z powodu dostarczania danych CSV, "NA" to wartości znaków, a twoje drugie stwierdzenie może być bardzo użyteczne. Czy możesz również wyjaśnić swoje pierwsze zdanie? Użycie rowSums() nie jest dla mnie jasne, ponieważ sprawdzę tylko konkretną kolumnę (jest mnóstwo kolumn). Jeśli ta konkretna kolumna (w przykładzie byłaby kolumną Var2) ma tam łańcuch znaków "NA" (zastąpię go twoją drugą instrukcją), wtedy chciałbym wybrać cały wiersz, aby był częścią nowej ramki danych . – John

+0

@John: updated. Chodzi o to, by użyć is.na, błędnie zinterpretowałem, że chciałeś sprawdzić wszystkie zmienne. –

+3

powinno to być 'new_DF <- DF [is.na (DF $ Var),]', tzn. Wydaje się, że istnieje dodatkowe '(' nawias po DF ['? – PatrickT

34

NA jest specjalną wartością w R, nie mieszaj wartości NA z łańcuchem "NA". W zależności od sposobu importowania danych, komórki "NA" i "NULL" mogą być różnego rodzaju (domyślnym zachowaniem jest zamiana łańcuchów "NA" na wartości NA i pozostawienie ciągów "NULL" bez zmian).

Jeśli korzystasz z read.table() lub read.csv(), powinieneś rozważyć argument "na.strings", aby importować czyste dane i zawsze pracować z prawdziwymi wartościami R NA.

Przykładem, pracując w obu przypadkach "null" i komórki "NA":

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

Dziękuję za odpowiedź.Jeśli rozumiem to poprawnie pierwsze zdanie zrobiłoby to samo co Df [Df == 'NA'] <- NA w przykładzie Jorisa? (mała) różnica polegałaby na tym, że jest to zrobione w twojej statucie bezpośrednio na początku, kiedy ramka danych jest tworzona (jest to bardzo czysta metoda programowania i dlatego ją lubię) – John

+0

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

+0

Odpowiedź Joris'a jest właściwie "preferowanym" sposobem wykonania tego wyczynu (jeśli piszesz to w skrypcie). Patrz: http://stackoverflow.com/questions/9860090/in- r-why-is-better-than-subset – Jonathan

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

@ZheyuanLi Jeśli nie podoba ci się odpowiedź, po prostu ją głosuj. Edytowanie odpowiedzi w celu zalecania oznaczania NIE jest odpowiednią akcją. Pozostaw komentarz, jeśli czujesz taką potrzebę. –

5

complete.cases daje TRUE gdy wszystkie wartości w rząd nie są NA

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

Zdecydowanie najszybszy. –

1

Spróbuj zmienić w ten sposób:

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

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

+0

new_DF <-dplyr :: filter (DF, is.na (Var2)) w zasadzie korzysta z funkcji filtra pakietu dplyr i odfiltrowuje dowolną obserwację w kolumnie Var2, która spełnia warunek is.na tzn. Wybiera wszystkie obserwacje za pomocą NA – drhnis

+0

Bardziej ładnie wyrażony jako 'DF%>% filter (is.na (Var2))' after 'library (dplyr)'. – Joe