Análisis Exploratorio de Datos (EDA)

El Análisis Exploratorio de Datos (EDA) es un proceso iterativo en el que:

Objetivo del EDA

El objetivo principal es:

  • Identificar posibles errores en los datos
  • Detectar valores atípicos
  • Analizar relaciones entre variables
  • Realizar análisis descriptivos mediante gráficos y estadísticas

Pasos del Análisis Exploratorio

El análisis exploratorio se puede dividir en tres etapas principales.

1. Carga de datos

Este paso consiste en importar el dataset al entorno de trabajo.
Aunque puede parecer trivial, en la práctica suele ser complejo cuando los datos provienen de diferentes fuentes o formatos.

2. Limpieza de datos

En esta etapa se busca preparar los datos para el análisis.

Las tareas más comunes son:

Formatos y tipos de datos

Se debe verificar que cada variable tenga el tipo correcto (numérica, categórica, etc.).

Valores nulos

Existen distintas estrategias:

  • eliminar observaciones
  • imputar valores
  • sustituir por medias o medianas

Siempre debe hacerse con cuidado para no alterar la información real.

Registros duplicados

Si un registro aparece repetido muchas veces, el modelo podría sesgarse hacia ese valor.


Paquetes comunes utilizados en EDA

Paquete Función Uso
dplyr select seleccionar columnas
dplyr filter filtrar filas
dplyr mutate crear o modificar variables
dplyr summarise calcular estadísticas
dplyr arrange ordenar datos
dplyr group_by agrupar datos
Paquete Función Uso
tidyr pivot_longer convertir datos de formato ancho a largo
tidyr pivot_wider convertir datos de largo a ancho

Detección de valores faltantes

Primero se detectan los valores faltantes en el dataset.

options(repos = c(CRAN = "https://cloud.r-project.org"))
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.3
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(insuranceData)

data("dataCar")

dataCar %>% 
  summarise(across(everything(), ~ sum(is.na(.))))
##   veh_value exposure clm numclaims claimcst0 veh_body veh_age gender area
## 1         0        0   0         0         0        0       0      0    0
##   agecat X_OBSTAT_
## 1      0         0

is.na() detecta valores faltantes y summarise() permite contar cuántos hay por variable.

También es posible localizar la posición exacta de los valores faltantes.

which(is.na(dataCar$veh_value))
## integer(0)
which(is.na(dataCar), arr.ind = TRUE)
##      row col

El argumento arr.ind = TRUE devuelve las coordenadas de fila y columna donde se encuentran los valores NA.

Ejemplo con un dataset pequeño:

dataCar2 <- data.frame(
  veh_body2 = c("Sedan","SUV",NA,"TRUCK","Sedan"),
  veh_value2 = c(20000,30000,25000,NA,22000),
  exposure2 = c(1.2,0.8,1.5,1.0,NA)
)

dataCar2
##   veh_body2 veh_value2 exposure2
## 1     Sedan      20000       1.2
## 2       SUV      30000       0.8
## 3      <NA>      25000       1.5
## 4     TRUCK         NA       1.0
## 5     Sedan      22000        NA
which(is.na(dataCar2), arr.ind = TRUE)
##      row col
## [1,]   3   1
## [2,]   4   2
## [3,]   5   3

Análisis Exploratorio con el dataset Boston

Primero se cargan los paquetes necesarios.

El paquete pacman permite cargar múltiples librerías al mismo tiempo usando p_load().

install.packages("pacman")
## Installing package into 'C:/Users/Lenovo/AppData/Local/R/win-library/4.4'
## (as 'lib' is unspecified)
## package 'pacman' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\Lenovo\AppData\Local\Temp\RtmpWGpu0o\downloaded_packages
library(pacman)
## Warning: package 'pacman' was built under R version 4.4.3
p_load(MASS, tidyverse, GGally, skimr)

options(scipen = 999)

Carga y exploración del dataset

El dataset Boston contiene información sobre viviendas en distintos barrios.

data("Boston")

skim(Boston)
Data summary
Name Boston
Number of rows 506
Number of columns 14
_______________________
Column type frequency:
numeric 14
________________________
Group variables None

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
crim 0 1 3.61 8.60 0.01 0.08 0.26 3.68 88.98 ▇▁▁▁▁
zn 0 1 11.36 23.32 0.00 0.00 0.00 12.50 100.00 ▇▁▁▁▁
indus 0 1 11.14 6.86 0.46 5.19 9.69 18.10 27.74 ▇▆▁▇▁
chas 0 1 0.07 0.25 0.00 0.00 0.00 0.00 1.00 ▇▁▁▁▁
nox 0 1 0.55 0.12 0.38 0.45 0.54 0.62 0.87 ▇▇▆▅▁
rm 0 1 6.28 0.70 3.56 5.89 6.21 6.62 8.78 ▁▂▇▂▁
age 0 1 68.57 28.15 2.90 45.02 77.50 94.07 100.00 ▂▂▂▃▇
dis 0 1 3.80 2.11 1.13 2.10 3.21 5.19 12.13 ▇▅▂▁▁
rad 0 1 9.55 8.71 1.00 4.00 5.00 24.00 24.00 ▇▂▁▁▃
tax 0 1 408.24 168.54 187.00 279.00 330.00 666.00 711.00 ▇▇▃▁▇
ptratio 0 1 18.46 2.16 12.60 17.40 19.05 20.20 22.00 ▁▃▅▅▇
black 0 1 356.67 91.29 0.32 375.38 391.44 396.22 396.90 ▁▁▁▁▇
lstat 0 1 12.65 7.14 1.73 6.95 11.36 16.96 37.97 ▇▇▅▂▁
medv 0 1 22.53 9.20 5.00 17.02 21.20 25.00 50.00 ▂▇▅▁▁
head(Boston)
##      crim zn indus chas   nox    rm  age    dis rad tax ptratio  black lstat
## 1 0.00632 18  2.31    0 0.538 6.575 65.2 4.0900   1 296    15.3 396.90  4.98
## 2 0.02731  0  7.07    0 0.469 6.421 78.9 4.9671   2 242    17.8 396.90  9.14
## 3 0.02729  0  7.07    0 0.469 7.185 61.1 4.9671   2 242    17.8 392.83  4.03
## 4 0.03237  0  2.18    0 0.458 6.998 45.8 6.0622   3 222    18.7 394.63  2.94
## 5 0.06905  0  2.18    0 0.458 7.147 54.2 6.0622   3 222    18.7 396.90  5.33
## 6 0.02985  0  2.18    0 0.458 6.430 58.7 6.0622   3 222    18.7 394.12  5.21
##   medv
## 1 24.0
## 2 21.6
## 3 34.7
## 4 33.4
## 5 36.2
## 6 28.7
dim(Boston)
## [1] 506  14
str(Boston)
## 'data.frame':    506 obs. of  14 variables:
##  $ crim   : num  0.00632 0.02731 0.02729 0.03237 0.06905 ...
##  $ zn     : num  18 0 0 0 0 0 12.5 12.5 12.5 12.5 ...
##  $ indus  : num  2.31 7.07 7.07 2.18 2.18 2.18 7.87 7.87 7.87 7.87 ...
##  $ chas   : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ nox    : num  0.538 0.469 0.469 0.458 0.458 0.458 0.524 0.524 0.524 0.524 ...
##  $ rm     : num  6.58 6.42 7.18 7 7.15 ...
##  $ age    : num  65.2 78.9 61.1 45.8 54.2 58.7 66.6 96.1 100 85.9 ...
##  $ dis    : num  4.09 4.97 4.97 6.06 6.06 ...
##  $ rad    : int  1 2 2 3 3 3 5 5 5 5 ...
##  $ tax    : num  296 242 242 222 222 222 311 311 311 311 ...
##  $ ptratio: num  15.3 17.8 17.8 18.7 18.7 18.7 15.2 15.2 15.2 15.2 ...
##  $ black  : num  397 397 393 395 397 ...
##  $ lstat  : num  4.98 9.14 4.03 2.94 5.33 ...
##  $ medv   : num  24 21.6 34.7 33.4 36.2 28.7 22.9 27.1 16.5 18.9 ...
summary(Boston)
##       crim                zn             indus            chas        
##  Min.   : 0.00632   Min.   :  0.00   Min.   : 0.46   Min.   :0.00000  
##  1st Qu.: 0.08205   1st Qu.:  0.00   1st Qu.: 5.19   1st Qu.:0.00000  
##  Median : 0.25651   Median :  0.00   Median : 9.69   Median :0.00000  
##  Mean   : 3.61352   Mean   : 11.36   Mean   :11.14   Mean   :0.06917  
##  3rd Qu.: 3.67708   3rd Qu.: 12.50   3rd Qu.:18.10   3rd Qu.:0.00000  
##  Max.   :88.97620   Max.   :100.00   Max.   :27.74   Max.   :1.00000  
##       nox               rm             age              dis        
##  Min.   :0.3850   Min.   :3.561   Min.   :  2.90   Min.   : 1.130  
##  1st Qu.:0.4490   1st Qu.:5.886   1st Qu.: 45.02   1st Qu.: 2.100  
##  Median :0.5380   Median :6.208   Median : 77.50   Median : 3.207  
##  Mean   :0.5547   Mean   :6.285   Mean   : 68.57   Mean   : 3.795  
##  3rd Qu.:0.6240   3rd Qu.:6.623   3rd Qu.: 94.08   3rd Qu.: 5.188  
##  Max.   :0.8710   Max.   :8.780   Max.   :100.00   Max.   :12.127  
##       rad              tax           ptratio          black       
##  Min.   : 1.000   Min.   :187.0   Min.   :12.60   Min.   :  0.32  
##  1st Qu.: 4.000   1st Qu.:279.0   1st Qu.:17.40   1st Qu.:375.38  
##  Median : 5.000   Median :330.0   Median :19.05   Median :391.44  
##  Mean   : 9.549   Mean   :408.2   Mean   :18.46   Mean   :356.67  
##  3rd Qu.:24.000   3rd Qu.:666.0   3rd Qu.:20.20   3rd Qu.:396.23  
##  Max.   :24.000   Max.   :711.0   Max.   :22.00   Max.   :396.90  
##      lstat            medv      
##  Min.   : 1.73   Min.   : 5.00  
##  1st Qu.: 6.95   1st Qu.:17.02  
##  Median :11.36   Median :21.20  
##  Mean   :12.65   Mean   :22.53  
##  3rd Qu.:16.95   3rd Qu.:25.00  
##  Max.   :37.97   Max.   :50.00

Funciones utilizadas:


Medidas descriptivas

Se seleccionan algunas variables importantes para el análisis.

variables_g1 <- c("medv","rm","lstat","crim","tax")

Boston_g1 <- Boston[, variables_g1]

Se calculan media y desviación estándar.

mean(Boston_g1$medv)
## [1] 22.53281
sapply(Boston[variables_g1], mean)
##       medv         rm      lstat       crim        tax 
##  22.532806   6.284634  12.653063   3.613524 408.237154
sapply(Boston[variables_g1], sd)
##        medv          rm       lstat        crim         tax 
##   9.1971041   0.7026171   7.1410615   8.6015451 168.5371161

sapply() permite aplicar una función a varias columnas al mismo tiempo.


Histogramas de variables principales

Para visualizar varias variables en un mismo gráfico se utiliza pivot_longer().

Esta función transforma los datos de formato ancho a formato largo, permitiendo crear múltiples gráficos mediante facet_wrap().

Funciones importantes:

Boston %>% 
  dplyr::select(medv, rm, lstat) %>% 
  pivot_longer(cols = everything(),
               names_to = "variable",
               values_to = "valor") %>% 
  ggplot(aes(x = valor, fill = variable))+
  geom_histogram(color = "white", bins = 15)+
  facet_wrap(~variable, scales = "free_x")+
  scale_fill_manual(values = c(medv = "blue", rm = "red", lstat = "green"))+
  labs(title="Histogramas de medv, rm y lstat")+
  theme_minimal()

facet_wrap() permite mostrar varios gráficos en una misma figura, uno por cada variable.


Análisis univariante

El análisis univariante estudia cada variable de manera individual.

ggplot(Boston, aes(x=medv))+
  geom_histogram(fill = "blue", color = "white", bins = 10)+
  ggtitle("Histograma de medv")+
  theme_minimal()

ggplot(Boston, aes(x=rm))+
  geom_histogram(fill = "red", color = "white", bins = 15)+
  ggtitle("Histograma de rm")+
  theme_minimal()

ggplot(Boston, aes(x=lstat))+
  geom_histogram(fill = "green", color = "white", bins = 23)+
  ggtitle("Histograma de lstat")+
  theme_minimal()

Estos gráficos permiten analizar la distribución de cada variable.


Boxplots

Los boxplots permiten observar:

Boston %>% 
  pivot_longer(cols = everything(),
               names_to = "variable",
               values_to = "valor") %>% 
  ggplot(aes(x= variable, y = valor, fill = variable))+
  geom_boxplot()+
  scale_fill_brewer(palette = "Set2")+
  ggtitle("Boxplot de variables")+
  theme_minimal()
## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors


Relación entre variables

Para estudiar relaciones entre variables se utilizan gráficos de dispersión (scatter plots).

Boston %>% 
  dplyr::select(medv, rm, lstat, crim, tax) %>% 
  pivot_longer(cols = -medv,
               names_to = "variable",
               values_to = "valor") %>% 
  ggplot(aes(x = valor, y = medv))+
  geom_point()+
  facet_wrap(~variable, scales = "free_x")+
  scale_color_manual(values = c(rm = "blue", crim = "red", lstat = "pink", tax = "orange"))+
  ggtitle("Relación con medv",
          subtitle = "Gráficos por faceta")+
  theme_minimal()
## Warning: No shared levels found between `names(values)` of the manual scale and the
## data's colour values.

geom_point() genera el gráfico de dispersión.
facet_wrap() separa las relaciones por variable.


Análisis bivariante

Relación entre criminalidad y valor de vivienda.

ggplot(Boston, aes(x=crim,y=medv))+
  geom_point(color = "purple")+
  scale_x_log10()+
  ggtitle("medv vs crim (escala log)")+
  theme_minimal()

scale_x_log10() transforma el eje x a escala logarítmica para mejorar la visualización.


Relación entre impuestos y valor de vivienda.

ggplot(Boston, aes(x=tax,y=medv))+
  geom_point(color = "orange")+
  ggtitle("tax vs medv")+
  theme_minimal()


Matriz de correlación visual

La función ggpairs() del paquete GGally permite analizar múltiples relaciones entre variables al mismo tiempo.

ggpairs(Boston[, c("medv","rm","lstat")])

Este gráfico incluye:

lo que facilita identificar relaciones entre variables.