Usuń wartości NA z wektora

191

Mam ogromny wektor, który ma kilka NAwartości, i próbuję znaleźć maksymalną wartość w tym wektorze (wektor to wszystkie liczby), ale nie mogę tego zrobić z powodu NAwartości.

Jak mogę usunąć NAwartości, aby móc obliczyć maksimum?

CodeGuy
źródło

Odpowiedzi:

265

Próbując ?max, zobaczysz, że faktycznie ma na.rm =argument, domyślnie ustawiony na FALSE. (To wspólna domyślna dla wielu innych funkcji, w tym R sum(), mean()etc.)

Ustawienie na.rm=TRUErobi dokładnie to, o co prosisz:

d <- c(1, 100, NA, 10)
max(d, na.rm=TRUE)

Jeśli chcesz usunąć wszystkie NA, użyj zamiast tego tego idiomu:

d <- d[!is.na(d)]

Ostatnia uwaga: Inne funkcje (np table(), lm()i sort()) mają NAzwiązane z modelem argumenty, które używają różnych nazw (oraz oferują różne opcje). Więc jeśli NApowodują problemy w wywołaniu funkcji, warto sprawdzić wbudowane rozwiązanie wśród argumentów funkcji. Odkryłem, że zwykle jest już jeden.

Josh O'Brien
źródło
To bardzo zły pomysł. Nie udaje się i daje -Infjedną dze wszystkich NA.
user3932000,
@ user3932000 Dla jasności dla innych, twoja skarga naprawdę dotyczy tego, jak max()zachowuje się podstawowa funkcja R (jak na przykład podczas działania max(c(NA, NA)). Osobiście uważam, że jego zachowanie jest rozsądne; Spodziewam się, że został skonstruowany w ten sposób, aby uzyskać oczekiwany rezultat podczas robienia takich rzeczya <- c(NA, NA); b <- 1:4; max(c(max(a, na.rm = TRUE), max(b, na.rm = TRUE)))
Josh O'Brien
@ user3932000 Nieco stycznie jedną z wielu mocnych stron R jako platformy do analizy danych jest wyrafinowana obsługa brakujących danych, będąca wynikiem bardzo uważnego przemyślenia jej autorów. (Jeśli interesujesz się tym tematem, zapoznaj się tutaj z dobrym omówieniem niektórych zagadnień z punktu widzenia programistów, którzy byli zaangażowani we włączanie funkcji podobnych do R NAw doskonałym pakiecie NumPy Pythona .)
Josh O'Brien,
@ user3932000: czy ta odpowiedź jest naprawdę zła? Co uważasz za maksimum zestawu zerowego?
Cliff AB
@CliffAB Nie ma maksimum. Możesz przypisać maksimum do -∞ (i min do + ∞), ale nie zawsze jest to pożądane lub intuicyjne. Ponadto, gdy usuniesz wszystkie NAs z wektora NAs, możesz spodziewać się pustego wektora, a nie -∞.
user3932000
94

Ta na.omitfunkcja jest używana wewnętrznie przez wiele procedur regresji:

vec <- 1:1000
vec[runif(200, 1, 1000)] <- NA
max(vec)
#[1] NA
max( na.omit(vec) )
#[1] 1000
IRTFM
źródło
20

?maxpokazuje, że istnieje dodatkowy parametr na.rm, który można ustawić TRUE.

Poza tym, jeśli naprawdę chcesz usunąć NAs, po prostu użyj czegoś takiego:

myvec[!is.na(myvec)]
Nick Sabbe
źródło
3
Myślę, że to jest najlepsze. na.rm i na.omit dodają sporo śmieci do danych wyjściowych.
MadmanLee,
Z wyjątkiem na.omitma również metodę ramki danych, więc jest bardziej ogólna.
IRTFM,
15

Można zadzwonić max(vector, na.rm = TRUE). Mówiąc bardziej ogólnie, możesz użyć tej na.omit()funkcji.

Michael Hoffman
źródło
14

Na wypadek, gdyby ktoś nowy w R chciał uproszczonej odpowiedzi na pierwotne pytanie

Jak mogę usunąć wartości NA z wektora?

Oto on:

Załóżmy, że masz wektor foow następujący sposób:

foo = c(1:10, NA, 20:30)

bieganie length(foo)daje 22.

nona_foo = foo[!is.na(foo)]

length(nona_foo) wynosi 21, ponieważ wartości NA zostały usunięte.

Pamiętaj, że is.na(foo)zwraca macierz boolowską, więc indeksowanie fooodwrotnością tej wartości da ci wszystkie elementy, które nie są NA.

Scott C. Wilson
źródło
13

Użyj discardod mruczenia (działa z listami i wektorami).

discard(v, is.na) 

Zaletą jest to, że rury są łatwe w użyciu; alternatywnie użyj wbudowanej funkcji podziału [:

v %>% discard(is.na)
v %>% `[`(!is.na(.))

Pamiętaj, że na.omitnie działa na listach:

> x <- list(a=1, b=2, c=NA)
> na.omit(x)
$a
[1] 1

$b
[1] 2

$c
[1] NA
qwr
źródło
1

Przeprowadziłem szybki test porównawczy, porównując oba basepodejścia i okazało się, że x[!is.na(x)]jest szybszy niż na.omit. Użytkownik qwrzasugerował, że spróbuję purrr::dicardrównież - okazało się to znacznie wolniejsze (choć chętnie przyjmę komentarze dotyczące mojej implementacji i testów!)

microbenchmark::microbenchmark(
  purrr::map(airquality,function(x) {x[!is.na(x)]}), 
  purrr::map(airquality,na.omit),
  purrr::map(airquality, ~purrr::discard(.x, .p = is.na)),
  times = 1e6)

Unit: microseconds
                                                     expr    min     lq      mean median      uq       max neval cld
 purrr::map(airquality, function(x) {     x[!is.na(x)] })   66.8   75.9  130.5643   86.2  131.80  541125.5 1e+06 a  
                          purrr::map(airquality, na.omit)   95.7  107.4  185.5108  129.3  190.50  534795.5 1e+06  b 
  purrr::map(airquality, ~purrr::discard(.x, .p = is.na)) 3391.7 3648.6 5615.8965 4079.7 6486.45 1121975.4 1e+06   c

Dla porównania, oto oryginalny test x[!is.na(x)]vs na.omit:

microbenchmark::microbenchmark(
    purrr::map(airquality,function(x) {x[!is.na(x)]}), 
    purrr::map(airquality,na.omit), 
    times = 1000000)


Unit: microseconds
                                              expr  min   lq      mean median    uq      max neval cld
 map(airquality, function(x) {     x[!is.na(x)] }) 53.0 56.6  86.48231   58.1  64.8 414195.2 1e+06  a 
                          map(airquality, na.omit) 85.3 90.4 134.49964   92.5 104.9 348352.8 1e+06   b
jsavn
źródło
powinieneś spróbowaćpurrr:discard
qwr