Eliminar valores de NA de un vector

191

Tengo un vector enorme que tiene un par de NAvalores, y estoy tratando de encontrar el valor máximo en ese vector (el vector son todos los números), pero no puedo hacer esto debido a los NAvalores.

¿Cómo puedo eliminar los NAvalores para poder calcular el máximo?

CodeGuy
fuente

Respuestas:

265

Al intentarlo ?max, verá que en realidad tiene un na.rm =argumento, establecido de forma predeterminada en FALSE. (Ese es el defecto común para muchas otras funciones, incluyendo R sum(), mean(), etc.)

La configuración na.rm=TRUEhace justo lo que estás pidiendo:

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

Si quieres eliminar todos los NAs, usa este modismo en su lugar:

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

Una nota final: Otras funciones (p table(). Ej . lm(), Y sort()) tienen NAargumentos relacionados que usan nombres diferentes (y ofrecen diferentes opciones). Entonces, si le NAcausa problemas en una llamada de función, vale la pena buscar una solución integrada entre los argumentos de la función. He descubierto que generalmente ya hay uno allí.

Josh O'Brien
fuente
Esta es una muy mala idea. Fracasa y da -Infpor una dde todas las AN.
user3932000
@ user3932000 Solo para que quede claro para los demás, su queja se refiere realmente a cómo se max()comporta la función base R (como, por ejemplo, al hacerlo max(c(NA, NA)). Personalmente, creo que su comportamiento es razonable; Espero que se haya construido de esa manera para que obtenga el resultado esperado al hacer cosas comoa <- c(NA, NA); b <- 1:4; max(c(max(a, na.rm = TRUE), max(b, na.rm = TRUE)))
Josh O'Brien el
@ user3932000 De manera algo tangencial, una de las muchas fortalezas de R como plataforma de análisis de datos es su manejo sofisticado de los datos faltantes, el resultado de un pensamiento muy cuidadoso por parte de sus autores. (Si está interesado en el tema, vea aquí una buena discusión sobre algunos de los temas involucrados, desde el punto de vista de los programadores que se dedicaron a incorporar NAinstalaciones de manejo tipo R en el excelente paquete NumPy de Python ).
Josh O'Brien
@ user3932000: ¿esa respuesta es realmente mala? ¿Cuál consideraría que es el máximo del conjunto nulo?
Cliff AB
@CliffAB No tiene un máximo. Puede asignar el máximo para ser -∞ (y el mínimo para ser + ∞), pero eso no siempre es deseado o intuitivo. Además, cuando elimina todas las NAs de un vector de NAs, esperaría un vector vacío, no -∞.
user3932000
94

La na.omitfunción es lo que muchas de las rutinas de regresión usan internamente:

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

?maxle muestra que hay un parámetro adicional na.rmque puede configurar TRUE.

Aparte de eso, si realmente quieres eliminar el NAs, solo usa algo como:

myvec[!is.na(myvec)]
Nick Sabbe
fuente
3
Creo que esto es lo mejor. na.rm y na.omit agregan bastante basura a la salida.
MadmanLee
Excepto que na.omittambién tiene un método de marco de datos, por lo que es más general.
IRTFM
15

Puede llamar max(vector, na.rm = TRUE). De manera más general, puede usar la na.omit()función.

Michael Hoffman
fuente
14

En caso de que alguien nuevo en R quiera una respuesta simplificada a la pregunta original

¿Cómo puedo eliminar los valores de NA de un vector?

Aquí está:

Suponga que tiene un vector de la foosiguiente manera:

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

correr length(foo)da 22.

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

length(nona_foo) es 21, porque los valores de NA se han eliminado.

Recuerde que is.na(foo)devuelve una matriz booleana, por lo que indexar foocon el opuesto de este valor le dará todos los elementos que no son NA.

Scott C Wilson
fuente
13

Uso discardde purrr (funciona con listas y vectores).

discard(v, is.na) 

El beneficio es que es fácil usar tuberías; alternativamente, use la función de subconjunto incorporada [:

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

Tenga en cuenta que na.omitno funciona en las listas:

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

$b
[1] 2

$c
[1] NA
qwr
fuente
1

Ejecuté un punto de referencia rápido comparando los dos baseenfoques y resulta que x[!is.na(x)]es más rápido que na.omit. El usuario qwrsugirió que lo intentara purrr::dicardtambién: resultó ser mucho más lento (¡aunque felizmente tomaré comentarios sobre mi implementación y prueba!)

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

Como referencia, aquí está la prueba original de 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
fuente
deberías probarpurrr:discard
qwr