6.13 Limpieza de datos
Esta sección abordará algunos tópicos de limpieza de datos o Data cleaning. Como ya se ha revisado, los valores perdidos o NA
causan problemas en el cálculo de parámetros estadísticos de las bases de datos. Más aún, cuando se pretende modelar la relación de una variable Y con los valores de una variable X, es imposible hacer regresión alguna con valores perdidos. Para estos casos, limpiar la base de datos será crucial.
NA
o no, podrás utilizar la función is.na()
. Esta devolverá un objeto lógico con la misma extensión que el objeto original. En aquellas posiciones donde exista un NA
en la base de datos original, is.na()
mostrará TRUE
.
6.13.1 ¿Cuántos NA existen en la base de datos?
Ejemplo 6.24 Considerando la base de datos WHO
, calcular la cantidad de NA de la base.
# Convertir WHO a tabla lógica
# para ubicar con TRUE a los NA
<- is.na(WHO) WHO_logical
Recuerda que para las funciones estadísticas y matemáticas, como mean()
o sum()
, TRUE
equivale a 1 y FALSE
a 0. Se puede obtener la proporción de TRUE
de un vector con mean()
, o la suma de TRUE
en el vector con sum()
.
# Sumando todos los TRUE (equivalentes a 1)
sum(WHO_logical)
# [1] 2563
6.13.2 ¿Cuántos NA existen en cada columna?
Hay muchas maneras de llegar a este resultado. Pero el procedimiento es similar en concepto al anterior. Se deben sumar los TRUE
(celdas con NA
) pero esta vez columna a columna. Como dato adicional, este objetivo también puede conseguir utilizando la función apply()
(Sección 5.4 Familia apply()).
Ejemplo 6.25 Crear una función que sume los NA de un vector:
<- function(x) sum(is.na(x)) fun_na
Ahora, utilizar la función aplicada a todas las columnas de la base de datos WHO
:
%>%
WHO summarise_all(.funs = fun_na)
# Country Year Status1 Category Level Status2 St2_categ Life_exp Ad_mort Inf_deaths
# 1 0 0 0 0 0 0 0 10 10 0
# Alcohol Per_exp Hep_B Measles BMI U5Y Polio Tot_exp Diph AIDS GDP Pop Thin1_19
# 1 194 0 553 0 34 0 19 226 19 0 448 652 34
# Thin5_9 Income Schooling
# 1 34 167 163
Si son demasiadas columnas para visualizar, considera seleccionar las columnas cuyos valores sean mayores de 0. Crea una función que evalúe un valor y otorgue TRUE
si este es mayor que 0.
# Crear la función
<- function(x) x > 0 fun0
La selección ahora utiliza una función que no se utilizó antes: select_if()
. Como todas las funciones _if
de dplyr, esta necesita condicionales para función. Allí entra en juego la función antes creada:
# Aplicarla en select_if()
%>%
WHO summarise_all(.funs = fun_na) %>%
select_if(fun0)
# Life_exp Ad_mort Alcohol Hep_B BMI Polio Tot_exp Diph GDP Pop Thin1_19 Thin5_9
# 1 10 10 194 553 34 19 226 19 448 652 34 34
# Income Schooling
# 1 167 163
6.13.3 ¿En qué fila o columna están los NA?
Ubicar la posición de fila y columna de los valores NA
(celdas en blanco) se utiliza cuando se conoce que no deberían haber celdas vacías pero las hay. Encontrarlas permite rellenar dicho valor por el correspondiente que fue omitido en el proceso de rellenado de la base de datos.
Ejemplo 6.26 Ubicar los valores NA de la base de datos WHO. Mostrar únicamente las 10 primeras del resultado:
which(WHO_logical, arr.ind=TRUE) %>%
head(10)
# row col
# 625 625 8
# 770 770 8
# 1651 1651 8
# 1716 1716 8
# 1813 1813 8
# 1910 1910 8
# 1959 1959 8
# 2168 2168 8
# 2217 2217 8
# 2714 2714 8
6.13.4 ¿Cómo reemplazar los NA por otro valor?
En ocasiones se necesita reemplazar los NA por algún valor por defecto que en el análisis sea útil. Por ejemplo, en bases que representan datos SIG (Sistemas de Información Geográficas), algunas celdas necesitan ser 9999, o -256, o algún otro valor, para que el análisis los considere bajo la categoría “no hay dato”. Otros estudios, por su parte, utilizan el rellenar los datos con el promedio o la mediana de la columna. En los siguientes ejemplos veremos su aplicación:
Ejemplo 6.27 Rellenar los valores NA
de la base de datos WHO
con el valor 9999999. Es excesivamente largo solo con la finalidad de hacerlo notorio, no por otra razón. Selecciona previamente las columnas Alcohol
, Hep_B
, Measles
, Polio
, Diph
para que el resultado no sea amplio en la consola. Reordenar el resultado por la columna Alcohol y mostrar las últimas 6 filas de la tabla.
Aquí el truco está en una forma especial de mutate_all()
para transformar todas las columnas pero utilizando ~ifelse()
para reemplazar todas la NA
(is.na(.x)
) por 9999999, y las no NA
con el mismo valor original (.x
):
%>%
WHO ::select(Alcohol, Hep_B, Measles, Polio, Diph) %>%
dplyrarrange(Alcohol) %>%
mutate_all(~ifelse(is.na(.x), 9999999, .x)) %>%
tail()
# Alcohol Hep_B Measles Polio Diph
# 2933 1e+07 64 39 65 64
# 2934 1e+07 87 0 87 87
# 2935 1e+07 97 256 97 97
# 2936 1e+07 69 468 63 69
# 2937 1e+07 9 9 9 9
# 2938 1e+07 87 0 88 87
Ejemplo 6.28 Considera el mismo ejemplo anterior 6.27. No obstante, en lugar de reemplazar NA
por 9999999, utiliza la función con mean(.x, na.rm = TRUE)
para que los NA se reemplacen por el promedio de la columna.
%>%
WHO ::select(Alcohol, Hep_B, Measles, Polio, Diph) %>%
dplyrarrange(Alcohol) %>%
mutate_all(~ifelse(is.na(.x), mean(.x, na.rm = TRUE), .x))%>%
tail()
# Alcohol Hep_B Measles Polio Diph
# 2933 4.603 64 39 65 64
# 2934 4.603 87 0 87 87
# 2935 4.603 97 256 97 97
# 2936 4.603 69 468 63 69
# 2937 4.603 9 9 9 9
# 2938 4.603 87 0 88 87