El Análisis Exploratorio de Datos (EDA) es un proceso iterativo en el que:
El objetivo principal es:
El análisis exploratorio se puede dividir en tres etapas principales.
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.
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:
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.
| 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 |
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
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)
El dataset Boston contiene información sobre viviendas en distintos barrios.
data("Boston")
skim(Boston)
| 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:
skim() genera un resumen estadístico con mini
histogramashead() muestra las primeras filasdim() indica dimensiones del datasetstr() muestra estructura y tipos de variablessummary() calcula estadísticas básicasSe 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.
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:
geom_histogram() crea histogramasfacet_wrap() divide el gráfico por variablescale_fill_manual() asigna colores personalizadostheme_minimal() aplica un estilo visual limpioBoston %>%
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.
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.
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
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.
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()
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.