Pomiń wiersze zawierające określoną kolumnę NA


138

Chcę wiedzieć, jak pomijać NAwartości w ramce danych, ale tylko w niektórych kolumnach, które mnie interesują.

Na przykład,

DF <- data.frame(x = c(1, 2, 3), y = c(0, 10, NA), z=c(NA, 33, 22))

ale chcę tylko pominąć dane, w których yjest NA, dlatego wynik powinien być

  x  y  z
1 1  0 NA
2 2 10 33

na.omitwydaje się, że usuń wszystkie wiersze zawierają jakiekolwiek NA.

Czy ktoś może mi pomóc w rozwiązaniu tego prostego pytania?

Ale jeśli teraz zmienię pytanie w stylu:

DF <- data.frame(x = c(1, 2, 3,NA), y = c(1,0, 10, NA), z=c(43,NA, 33, NA))

Jeśli chcę tylko pominąć x=nalub z=nagdzie mogę umieścić |funkcję?

Odpowiedzi:


87

Możesz użyć complete.casesfunkcji i umieścić ją w funkcji w ten sposób:

DF <- data.frame(x = c(1, 2, 3), y = c(0, 10, NA), z=c(NA, 33, 22))

completeFun <- function(data, desiredCols) {
  completeVec <- complete.cases(data[, desiredCols])
  return(data[completeVec, ])
}

completeFun(DF, "y")
#   x  y  z
# 1 1  0 NA
# 2 2 10 33

completeFun(DF, c("y", "z"))
#   x  y  z
# 2 2 10 33

EDYCJA: Zwróć tylko wiersze bez NAs

Jeśli chcesz wyeliminować wszystkie wiersze z co najmniej jednym NAw dowolnej kolumnie, po prostu użyj complete.casesfunkcji prosto w górę:

DF[complete.cases(DF), ]
#   x  y  z
# 2 2 10 33

Lub jeśli completeFunjest już zakorzeniony w Twoim przepływie pracy;)

completeFun(DF, names(DF))

Czy możesz sprawić, że twoje podejście będzie chciwe? Weź wszystkie kolumny, które w ogóle nie mają NA.
Léo Léopold Hertz 준영

1
Masz na myśli po prostu zwracanie wierszy bez NAs? Lubisz completeFun(DF, names(DF))?
BenBarnes

Poprawny! Proszę rozważyć dodanie go do swojej odpowiedzi, ponieważ jest to tutaj powszechna potrzeba. - - Myślę, że odpowiedź Mnella nie może być rozszerzona jako twoja. Twoje podejście do funkcji jest świetne!
Léo Léopold Hertz 준영

1
Gotowe! Dzięki za napiwek @ LéoLéopoldHertz 준영
BenBarnes

Jeśli przeglądasz miniony rok 2020, zrób sobie przysługę i spójrz na nowsze odpowiedzi podane poniżej, na przykład podejście opisane przez @amrrs poniżej przy użyciu drop_na()from tidyrrobi to samo, ale moim zdaniem jest lepszym rozwiązaniem dzisiaj.
Ricky

199

Posługiwać się is.na

DF <- data.frame(x = c(1, 2, 3), y = c(0, 10, NA), z=c(NA, 33, 22))
DF[!is.na(DF$y),]

1
Jak łapczywie zastosujesz to podejście do wszystkich kolumn w zestawie danych? Jeśli którakolwiek z wartości kolumny to NA, pomiń. Zatem dane wyjściowe zestawu danych to tylko druga kolumna.
Léo Léopold Hertz 준영

3
Użyj, na.omitaby zachłannie usunąć wszystkie wiersze z NA w dowolnej kolumniena.omit(DF)
M. Viking

77

Hadley ma tidyrwłaśnie tę niesamowitą funkcjędrop_na

library(tidyr)
DF %>% drop_na(y)
  x  y  z
1 1  0 NA
2 2 10 33

1
Ta metoda umożliwia również określenie więcej niż jednej kolumny (w celu usunięcia wartości NA). Na przykład, można użyć DF%>% drop_na (y, z), aby usunąć wartości NA w obu kolumnach, y i z.
SolingerMUC

33

Użyj „podzbioru”

DF <- data.frame(x = c(1, 2, 3), y = c(0, 10, NA), z=c(NA, 33, 22))
subset(DF, !is.na(y))

11

Możliwe jest użycie na.omitdo data.table:

na.omit(data, cols = c("x", "z"))

5
cols=argument jest dostępny w data.table::na.omitbibliotece. Nie podstawa stats::na.omit.
M. Viking


3

Pomiń wiersz, jeśli jedna z dwóch określonych kolumn zawiera <NA>.

DF[!is.na(DF$x)&!is.na(DF$z),]

1

Po prostu spróbuj tego:

DF %>% t %>% na.omit %>% t

Transponuje ramkę danych i pomija puste wiersze, które były „kolumnami” przed transpozycją, a następnie transponujesz ją z powrotem.


10
Proszę wyjaśnij trochę, co się dzieje.
vonbrand
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.