Chciałbym usunąć linie w tej ramce danych, które:
a) zawierają NA
s we wszystkich kolumnach. Poniżej znajduje się moja przykładowa ramka danych.
gene hsap mmul mmus rnor cfam
1 ENSG00000208234 0 NA NA NA NA
2 ENSG00000199674 0 2 2 2 2
3 ENSG00000221622 0 NA NA NA NA
4 ENSG00000207604 0 NA NA 1 2
5 ENSG00000207431 0 NA NA NA NA
6 ENSG00000221312 0 1 2 3 2
Zasadniczo chciałbym uzyskać ramkę danych, taką jak poniżej.
gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
6 ENSG00000221312 0 1 2 3 2
b) zawierają NA
s tylko w niektórych kolumnach , więc mogę również uzyskać ten wynik:
gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
4 ENSG00000207604 0 NA NA 1 2
6 ENSG00000221312 0 1 2 3 2
final[complete.cases(final),]
?complete.cases
? Gdybym chciał zachować wiersze z NA zamiast odrzucać?final[ ! complete.cases(final),]
nie współpracuje ...final
jest zmienna ramka danych?Spróbować
na.omit(your.data.frame)
. Jeśli chodzi o drugie pytanie, spróbuj opublikować je jako inne pytanie (dla jasności).źródło
rownames(x) <- NULL
.na.omit()
upuszcza wiersze, które zawierająNA
w dowolnej kolumnietidyr
ma nową funkcjędrop_na
:źródło
drop_na
. Na przykładdf %>% drop_na()
,df %>% na.omit()
idrop_na(df)
wszystkie są w zasadzie równoważne.na.omit
dodaje dodatkowe informacje, takie jak wskaźniki pominiętych przypadków, i - co ważniejsze - nie pozwala na wybranie kolumn - tutajdrop_na
świeci.na.omit
z rurami lub bez, tak jakdrop_na
z rurkami lub bez.Wolę następujący sposób, aby sprawdzić, czy wiersze zawierają jakieś NA:
Zwraca wektor logiczny z wartościami wskazującymi, czy jest jakaś NA w wierszu. Możesz go użyć, aby zobaczyć, ile wierszy będziesz musiał upuścić:
i ostatecznie upuść je
W przypadku filtrowania wierszy z określoną częścią NA staje się to trochę trudniejsze (na przykład możesz podać „końcowy [, 5: 6]”, aby „zastosować”). Ogólnie rzecz biorąc, rozwiązanie Jorisa Meysa wydaje się bardziej eleganckie.
źródło
rowSum(!is.na(final))
wydaje się lepiej nadaje się niżapply()
Inną opcją, jeśli chcesz mieć większą kontrolę nad tym, jak wiersze są uważane za nieprawidłowe, jest
Korzystając z powyższego, to:
Staje się:
... gdzie tylko wiersz 5 jest usuwany, ponieważ jest to jedyny wiersz zawierający NA dla obu
rnor
ANDcfam
. Logikę logiczną można następnie zmienić w celu dopasowania do określonych wymagań.źródło
Jeśli chcesz kontrolować, ile NA jest ważnych dla każdego wiersza, wypróbuj tę funkcję. W przypadku wielu zestawów danych ankiet zbyt wiele pustych odpowiedzi na pytania może zepsuć wyniki. Więc są usuwane po pewnym progu. Ta funkcja pozwoli ci wybrać, ile NA może mieć rząd, zanim zostanie usunięty:
Domyślnie wyeliminuje wszystkie NA:
Lub określ maksymalną dozwoloną liczbę NA:
źródło
Jeśli wydajność jest priorytetem, użyj
data.table
ina.omit()
z opcjonalnym parametremcols=
.na.omit.data.table
jest najszybszy w moim teście porównawczym (patrz poniżej), czy to dla wszystkich kolumn, czy dla wybranych kolumn (pytanie OP część 2).Jeśli nie chcesz używać
data.table
, użyjcomplete.cases()
.Na wanilii
data.frame
,complete.cases
jest szybszy niżna.omit()
lubdplyr::drop_na()
. Zauważ, żena.omit.data.frame
nie obsługujecols=
.Wynik testu
Oto porównanie bazy (niebieski),
dplyr
(różowy) idata.table
(żółtych) metod usuwania wszystkich lub wybranych brakujących obserwacji na hipotetycznym zbiorze danych z 1 milionem obserwacji 20 zmiennych numerycznych z niezależnym 5% prawdopodobieństwem braku oraz podzbiór 4 zmiennych dla części 2.Wyniki mogą się różnić w zależności od długości, szerokości i rzadkości określonego zestawu danych.
Uwaga skala dziennika na osi y.
Skrypt porównawczy
źródło
Za pomocą pakietu dplyr możemy filtrować NA w następujący sposób:
źródło
drop_na()
Zwróci to wiersze, które mają co najmniej JEDNĄ wartość inną niż NA.
Zwróci to wiersze, które mają co najmniej DWIE wartości inne niż NA.
źródło
Na twoje pierwsze pytanie mam kod, dzięki któremu mogę się pozbyć wszystkich NA. Dzięki za @Gregor, aby uprościć.
W przypadku drugiego pytania kod jest tylko alternatywą dla poprzedniego rozwiązania.
Zauważ, że -5 to liczba kolumn w twoich danych. To wyeliminuje wiersze ze wszystkimi NA, ponieważ rowSums sumuje się do 5 i stają się zerami po odjęciu. Tym razem niezbędny jest as.logical.
źródło
W tym celu możemy również użyć funkcji podzestawu.
To da tylko te wiersze, które nie mają NA w mmul i rnor
źródło
Jestem syntezatorem :). Tutaj połączyłem odpowiedzi w jedną funkcję:
źródło
Zakładając, że
dat
jako ramka danych, oczekiwany wynik można uzyskać za pomocą1.
rowSums
2)
lapply
źródło
Jednym ze sposobów, który jest zarówno ogólne i daje dość czytelny kod jest użycie
filter
funkcji i jego warianty w pakiecie dplyr (filter_all
,filter_at
,filter_if
):źródło
Powyższa funkcja usuwa wszystkie wiersze z ramki danych, która ma „NA” w dowolnej kolumnie i zwraca wynikowe dane. Jeśli chcesz sprawdzić wiele wartości, takich jak
NA
i?
zmienićdart=c('NA')
parametr funkcji nadart=c('NA', '?')
źródło
Domyślam się, że można to bardziej elegancko rozwiązać w ten sposób:
źródło
NA
. Myślę, że OP chce:df %>% filter_all(all_vars(!is.na(.)))