Contando valores faltantes (NA) en R

Para verificar valores faltantes (también llamados valores perdidos) en R podrás estar tentado a usar el operador == con tu vector a un lado y NA al otro. ¡No lo hagas!

Si insistes, obtendrás un resultado inútil.

x <- c(1, 5, NA, 3, NA)
x == NA
## [1] NA NA NA NA NA

Mejor usa la función is.na().

is.na(x)
## [1] FALSE FALSE  TRUE FALSE  TRUE

Armados con este conocimiento, exploremos cómo obtener algunos valores descriptivos básicos acerca de valores faltantes en tus datos. Primero, para contar el número total de NA en un vector, simplemente puedes sumar el número de valores verdaderos resultantes de is.na() con la función sum().

sum(is.na(x))
## [1] 2

Puede que estés confundido sobre cómo es posible sumar valores verdaderos (TRUE) y falsos (FALSE) en R. De manera automática, R convierte los vectores lógicos (logical) a vectores de números enteros (integer) al aplicar funciones aritméticas. En dicho proceso, TRUE se vuelve 1 y FALSE, 0. De ese modo, sum(is.na(x)) devuelve el total de valores faltantes en el vector x.

Para obtener la proporción de valores faltantes, puedes dividir el resultado de la operación anterior por la longitud del vector de entrada.

sum(is.na(x)) / length(x)
## [1] 0.4

Ahora, si miras con detenimiento el código anterior es posible que esa fórmula te resulte familiar. ¡Sumar todos los elementos de un vector y dividirlos por el número total de elementos es calcular la media aritmética! Entonces, en lugar de usar sum() y length(), simplemente podemos calcular la media con la función mean() para obtener la proporción de NA en un vector.

mean(is.na(x))
## [1] 0.4

Pero suficiente de vectores. Miremos ahora cómo contar valores faltantes en un marco o tabla (en inglés data frame). Para ilustrar estos conceptos, agreguemos primero valores faltantes al juego de datos mtcars.

data(mtcars)
set.seed(1)
mtcars[sample(1:nrow(mtcars), 5), sample(1:ncol(mtcars), 3)] <- NA

La función is.na() es una función genérica y tiene métodos para data frames, por lo que puedes ingresar directamente una tabla como entrada.

na <- is.na(mtcars)
na[1:15, 1:7]
##                      mpg   cyl  disp    hp  drat    wt  qsec
## Mazda RX4          FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE
## Mazda RX4 Wag      FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE
## Datsun 710         FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## Hornet 4 Drive     FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## Hornet Sportabout  FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## Valiant            FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## Duster 360         FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## Merc 240D          FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## Merc 230           FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## Merc 280           FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## Merc 280C          FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE
## Merc 450SE         FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## Merc 450SL         FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## Merc 450SLC        FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## Cadillac Fleetwood FALSE FALSE FALSE FALSE FALSE FALSE FALSE

Como puedes ver, el resultado es una matriz de valores lógicos (logical). Obtener el número total de NA es fácil, porque sum() funciona tanto con matrices como con vectores.

sum(is.na(mtcars))
## [1] 15

Sin embargo, podría decirse que el número total de valores faltantes en un conjunto de datos es una medida algo burda. Resulta mucho más interesante si examinamos los valores que faltan a través de las variables y los registros del juego de datos. Ello permite detectar patrones que podrían informar futuras decisiones de modelización.

Contar NA a lo largo de filas o columnas puede hacerse usando la función apply(). Dicha función recibe tres argumentos: X es la matriz de entrada, MARGIN es un entero y FUN es la función que será aplicada a cada fila o columna. MARGIN = 1 ejecuta la función a las filas de una tabla, mientras que MARGIN = 2 lo hace a las columnas.

apply(X = is.na(mtcars), MARGIN = 1, FUN = sum)
##           Mazda RX4       Mazda RX4 Wag          Datsun 710      Hornet 4 Drive 
##                   3                   3                   0                   0 
##   Hornet Sportabout             Valiant          Duster 360           Merc 240D 
##                   0                   0                   0                   0 
##            Merc 230            Merc 280           Merc 280C          Merc 450SE 
##                   0                   0                   3                   0 
##          Merc 450SL         Merc 450SLC  Cadillac Fleetwood Lincoln Continental 
##                   0                   0                   0                   0 
##   Chrysler Imperial            Fiat 128         Honda Civic      Toyota Corolla 
##                   0                   0                   0                   0 
##       Toyota Corona    Dodge Challenger         AMC Javelin          Camaro Z28 
##                   0                   0                   3                   0 
##    Pontiac Firebird           Fiat X1-9       Porsche 914-2        Lotus Europa 
##                   0                   0                   0                   0 
##      Ford Pantera L        Ferrari Dino       Maserati Bora          Volvo 142E 
##                   3                   0                   0                   0
apply(X = is.na(mtcars), MARGIN = 2, FUN = sum)
##  mpg  cyl disp   hp drat   wt qsec   vs   am gear carb 
##    0    0    0    5    0    0    5    0    5    0    0

Si quieres calcular la proporción de valores faltantes por fila o columna, solo debes cambiar el argumento FUN por mean.

apply(X = is.na(mtcars), MARGIN = 1, FUN = mean)
##           Mazda RX4       Mazda RX4 Wag          Datsun 710      Hornet 4 Drive 
##           0.2727273           0.2727273           0.0000000           0.0000000 
##   Hornet Sportabout             Valiant          Duster 360           Merc 240D 
##           0.0000000           0.0000000           0.0000000           0.0000000 
##            Merc 230            Merc 280           Merc 280C          Merc 450SE 
##           0.0000000           0.0000000           0.2727273           0.0000000 
##          Merc 450SL         Merc 450SLC  Cadillac Fleetwood Lincoln Continental 
##           0.0000000           0.0000000           0.0000000           0.0000000 
##   Chrysler Imperial            Fiat 128         Honda Civic      Toyota Corolla 
##           0.0000000           0.0000000           0.0000000           0.0000000 
##       Toyota Corona    Dodge Challenger         AMC Javelin          Camaro Z28 
##           0.0000000           0.0000000           0.2727273           0.0000000 
##    Pontiac Firebird           Fiat X1-9       Porsche 914-2        Lotus Europa 
##           0.0000000           0.0000000           0.0000000           0.0000000 
##      Ford Pantera L        Ferrari Dino       Maserati Bora          Volvo 142E 
##           0.2727273           0.0000000           0.0000000           0.0000000

Para finalizar, echemos un vistazo a cómo visualizar los datos faltantes. Hay muchos paquetes para ese propósito; a mi personalmente me gusta el paquete {heatmaply}, el cual puede generar mapas de calor (en inglés heatmaps) interactivos

heatmaply::heatmaply_na(mtcars)

Genial, ¿no?

Post traducido al español por Jacobo de la Cuesta.


Thomas Neitmann

base

3620 Words

2021-01-25 00:00 +0700

f932891 @ 2021-02-07

comments powered by Disqus