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.