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ę?

user1489975
źródło

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))
BenBarnes
źródło
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),]
mnel
źródło
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
amrrs
źródło
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))
Rnoob
źródło
11

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

na.omit(data, cols = c("x", "z"))
Droney
źródło
5
cols=argument jest dostępny w data.table::na.omitbibliotece. Nie podstawa stats::na.omit.
M. Viking
3

Spróbuj tego:

cc=is.na(DF$y)
m=which(cc==c("TRUE"))
DF=DF[-m,]
rockwap
źródło
3

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

DF[!is.na(DF$x)&!is.na(DF$z),]
M. Viking
źródło
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.

Luchao Qi
źródło
10
Proszę wyjaśnij trochę, co się dzieje.
vonbrand