Rimuovi i valori NA da un vettore


191

Ho un vettore enorme che ha un paio di NAvalori e sto cercando di trovare il valore massimo in quel vettore (il vettore è tutti i numeri), ma non posso farlo a causa dei NAvalori.

Come posso rimuovere i NAvalori in modo da poter calcolare il massimo?

Risposte:


266

Provando ?max, vedrai che in realtà ha un na.rm =argomento, impostato di default su FALSE. (Questo è il difetto comune per molte altre funzioni, tra cui R sum(), mean(), etc.)

L'impostazione na.rm=TRUEfa esattamente quello che stai chiedendo:

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

Se vuoi rimuovere tutti NAi messaggi, usa invece questo idioma:

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

Un'ultima nota: altre funzioni (ad es table(). lm(), E sort()) hanno NAargomenti correlati che usano nomi diversi (e offrono opzioni diverse). Quindi, se NAsi verificano problemi in una chiamata di funzione, vale la pena cercare una soluzione integrata tra gli argomenti della funzione. Ho scoperto che di solito ce n'è già uno lì.


Questa è una pessima idea. Fallisce e dà -Infuna ddi tutte le NA.
user3932000

@ user3932000 Per essere chiari per gli altri, il tuo reclamo riguarda davvero il max()comportamento della funzione R di base (come, ad esempio, quando lo fai max(c(NA, NA)). Personalmente, penso che il suo comportamento sia ragionevole; Mi aspetto che sia stato costruito in questo modo in modo da ottenere il risultato atteso quando si fanno cose comea <- c(NA, NA); b <- 1:4; max(c(max(a, na.rm = TRUE), max(b, na.rm = TRUE)))
Josh O'Brien,

@ user3932000 Un po 'tangenzialmente, uno dei tanti punti di forza di R come una piattaforma di analisi dei dati è la sua sofisticata gestione dei dati mancanti, frutto di tanto un'attenta riflessione da parte dei suoi autori. (Se sei interessato all'argomento, vedi qui per una buona discussione di alcuni dei problemi coinvolti, dal punto di vista dei programmatori che erano impegnati NAnell'incorporare le strutture di gestione di tipo R nell'eccellente pacchetto NumPy di Python .)
Josh O'Brien,

@ user3932000: questa risposta è davvero negativa? Quale considereresti il ​​massimo dell'insieme null?
Cliff AB,

@CliffAB Non ha un massimo. Puoi assegnare il massimo a -∞ (e min a + ∞), ma non è sempre desiderato o intuitivo. Inoltre, quando rimuovi tutte le NAs da un vettore di NAs, ti aspetteresti un vettore vuoto, non -∞.
user3932000

94

La na.omitfunzione è ciò che molte routine di regressione usano internamente:

vec <- 1:1000
vec[runif(200, 1, 1000)] <- NA
max(vec)
#[1] NA
max( na.omit(vec) )
#[1] 1000

20

?maxmostra che esiste un parametro aggiuntivo na.rmche è possibile impostare TRUE.

A parte questo, se vuoi davvero rimuovere la NAs, usa qualcosa come:

myvec[!is.na(myvec)]

3
Penso che questo sia il migliore. na.rm e na.omit aggiungono un bel po 'di spazzatura all'output.
MadmanLee,

Tranne che na.omitha anche un metodo dataframe, quindi è più generale.
IRTFM,

15

Puoi chiamare max(vector, na.rm = TRUE). Più in generale, è possibile utilizzare la na.omit()funzione.


14

Nel caso in cui qualcuno nuovo a R desideri una risposta semplificata alla domanda originale

Come posso rimuovere i valori NA da un vettore?

Ecco qui:

Supponi di avere un vettore foocome segue:

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

correre length(foo)dà 22.

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

length(nona_foo) è 21, perché i valori NA sono stati rimossi.

Ricorda is.na(foo)restituisce una matrice booleana, quindi indicizzare foocon l'opposto di questo valore ti darà tutti gli elementi che non sono NA.


13

Usa discardda purrr (funziona con elenchi e vettori).

discard(v, is.na) 

Il vantaggio è che è facile usare tubi; in alternativa, utilizzare la funzione di subsetting integrata [:

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

Si noti che na.omitnon funziona sugli elenchi:

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

$b
[1] 2

$c
[1] NA

2

Ho eseguito un rapido benchmark confrontando i due baseapprocci e risulta che x[!is.na(x)]è più veloce di na.omit. L'utente qwrmi ha suggerito di provare purrr::dicardanche questo - questo si è rivelato notevolmente più lento (anche se accetterò felicemente commenti sulla mia implementazione e test!)

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

Per riferimento, ecco il test originale di 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

dovresti provarepurrr:discard
qwr
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.