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?

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.


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

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)]

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.


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.


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

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

powinieneś spróbowaćpurrr:discard
qwr
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.