Odpowiedzi:
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=TRUE
robi 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ą NA
związane z modelem argumenty, które używają różnych nazw (oraz oferują różne opcje). Więc jeśli NA
powodują problemy w wywołaniu funkcji, warto sprawdzić wbudowane rozwiązanie wśród argumentów funkcji. Odkryłem, że zwykle jest już jeden.
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)))
NA
w doskonałym pakiecie NumPy Pythona .)
NA
s z wektora NA
s, możesz spodziewać się pustego wektora, a nie -∞.
?max
pokazuje, że istnieje dodatkowy parametr na.rm
, który można ustawić TRUE
.
Poza tym, jeśli naprawdę chcesz usunąć NA
s, po prostu użyj czegoś takiego:
myvec[!is.na(myvec)]
na.omit
ma również metodę ramki danych, więc jest bardziej ogólna.
Można zadzwonić max(vector, na.rm = TRUE)
. Mówiąc bardziej ogólnie, możesz użyć tej na.omit()
funkcji.
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 foo
w 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 foo
odwrotnością tej wartości da ci wszystkie elementy, które nie są NA.
Użyj discard
od 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.omit
nie działa na listach:
> x <- list(a=1, b=2, c=NA)
> na.omit(x)
$a
[1] 1
$b
[1] 2
$c
[1] NA
Przeprowadziłem szybki test porównawczy, porównując oba base
podejścia i okazało się, że x[!is.na(x)]
jest szybszy niż na.omit
. Użytkownik qwr
zasugerował, że spróbuję purrr::dicard
ró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
purrr:discard
-Inf
jednąd
ze wszystkich NA.