ANÁLISIS EXPLORATORIO DE DATOS

Ver video

https://www.youtube.com/watch?v=UeMpYEktLfU&ab_channel=Comunicaci%C3%B3nNum%C3%A9rica

El análisis exploratorio de datos (EDA por sus siglas en inglés) implica el uso de gráficos y visualizaciones para explorar y analizar un conjunto de datos. El objetivo es explorar, investigar y aprender, no confirmar hipótesis estadísticas.

¿Cuándo debo utilizarlo?

El análisis exploratorio de datos es una potente herramienta para explorar un conjunto de datos. Incluso cuando su objetivo es efectuar análisis planificados, el EDA puede utilizarse para limpiar datos, para análisis de subgrupos o simplemente para comprender mejor los datos. Un paso inicial importante en cualquier análisis de datos es representar los datos gráficamente.

No gráfico: Calcula estadísticas descriptivas de las variables

Gráfico: Calcula estadísticas de forma gráfica

Univariado: Analiza una sola variable a la vez

Multivariado: Analiza dos o más variables

A su vez, cada uno de esas dividisiones puede subdividirse según los tipos de datos con los que trabajemos: cateógicos o numéricos.

Cargar paquetes

Lo primero que tenemos que hacer es cargar los paquetes que vamos a utilizar para el análisis. En este caso vamos a usar:

require(tidyverse)
## Loading required package: tidyverse
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.2     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(dplyr)
library(ggplot2) 
library(readxl)
library(gmodels)
library(Hmisc)
## 
## Attaching package: 'Hmisc'
## 
## The following objects are masked from 'package:dplyr':
## 
##     src, summarize
## 
## The following objects are masked from 'package:base':
## 
##     format.pval, units
library(ggthemes)
require(magrittr)
## Loading required package: magrittr
## 
## Attaching package: 'magrittr'
## 
## The following object is masked from 'package:purrr':
## 
##     set_names
## 
## The following object is masked from 'package:tidyr':
## 
##     extract
library(readr)
require(tibble)

(Recordar que si no ha instalado estos paquetes debe correr primero el comando: install.packages(“nombre del paquete”))

R como calculadora

Puedes usar el programa R como una calculadora, basta con conocer cuáles son los signos y comandos a utilizar para realizar las opereaciones. Copia los comandos en tu script de R y ejecútalos para ver los resultados.

#suma
2+2
## [1] 4
#multiplicación
2*2
## [1] 4
#división
2/2
## [1] 1
#potencia
4^2
## [1] 16
#raíz cuadrada
sqrt(16)
## [1] 4

Abrir una base de R-STUDIO y resumir

R ya incorpora una serie de bases de datos que te pueden resultar de utilidad para empezar a explorar las posibilidades de análisis estadístico que te ofrece este programa.

Como ejemplo vamos a explorara la base de datos llamada “cars”.

#cargar la base
data(cars)
#visualizar los encabezados
head(cars)
##   speed dist
## 1     4    2
## 2     4   10
## 3     7    4
## 4     7   22
## 5     8   16
## 6     9   10
#resumir con algunas estadísticas las variables de la base 
summary(cars)
##      speed           dist       
##  Min.   : 4.0   Min.   :  2.00  
##  1st Qu.:12.0   1st Qu.: 26.00  
##  Median :15.0   Median : 36.00  
##  Mean   :15.4   Mean   : 42.98  
##  3rd Qu.:19.0   3rd Qu.: 56.00  
##  Max.   :25.0   Max.   :120.00

Incluir gráficas

Puedes agregar fácilmente gráficos a tu análisis. Por ejemplo:

data(pressure)
head(pressure)
##   temperature pressure
## 1           0   0.0002
## 2          20   0.0012
## 3          40   0.0060
## 4          60   0.0300
## 5          80   0.0900
## 6         100   0.2700
plot(pressure)

Cargar datos

edad<-c(11,12,15,20,41)
edad
## [1] 11 12 15 20 41
altura=c(50,65,120,156,182)
altura
## [1]  50  65 120 156 182
datos=data.frame(edad,altura)
datos
##   edad altura
## 1   11     50
## 2   12     65
## 3   15    120
## 4   20    156
## 5   41    182
plot(datos,type="b")

Análisis Exploratorio de Datos de PRECIOS_DE_COMBUSTIBLES_MINENERGIA.

La presente base de datos contiene información acerca de los precios de diversos combustibles durante los años 2017, 2018, 2019 y 2020p. También contiene información acerca de municipios, departamentos, meses del año, entre otras variables.

#Limpiar la consola y el entorno 
cat('\f')
rm(list=ls())
#Importar base de datos
p_comb <- read_csv("Precios_de_Combustibles_MinEnergia.csv")
## Rows: 418853 Columns: 12
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (10): mes, CodigoDepartamento, NombreDepartamento, CodigoMunicipio, muni...
## dbl  (2): periodo, precio
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

En primer lugar, se hace necesario limpiar la base de datos

head(p_comb) #Primeras filas de la base de datos
## # A tibble: 6 × 12
##   periodo mes   CodigoDepartamento NombreDepartamento CodigoMunicipio municipio 
##     <dbl> <chr> <chr>              <chr>              <chr>           <chr>     
## 1    2017 Enero 13                 HUILA              645             GARZON    
## 2    2017 Enero 9                  CESAR              439             BECERRIL  
## 3    2017 Enero 9                  CESAR              436             AGUACHICA 
## 4    2017 Enero 9                  CESAR              435             VALLEDUPAR
## 5    2017 Enero 3                  BOGOTA D.C.        182             BOGOTA D.…
## 6    2017 Enero 9                  CESAR              437             AGUSTIN C…
## # ℹ 6 more variables: nombrecomercial <chr>, bandera <chr>, direccion <chr>,
## #   producto <chr>, precio <dbl>, estado <chr>
dim(p_comb) #Dimensiones de los datos: 418.853 registros y 12 variables:
## [1] 418853     12
nombres1<- names(p_comb); nombres1 #Nombres de las columnas
##  [1] "periodo"            "mes"                "CodigoDepartamento"
##  [4] "NombreDepartamento" "CodigoMunicipio"    "municipio"         
##  [7] "nombrecomercial"    "bandera"            "direccion"         
## [10] "producto"           "precio"             "estado"
p_comb %>% glimpse #Tipos de variables
## Rows: 418,853
## Columns: 12
## $ periodo            <dbl> 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 201…
## $ mes                <chr> "Enero", "Enero", "Enero", "Enero", "Enero", "Enero…
## $ CodigoDepartamento <chr> "13", "9", "9", "9", "3", "9", "11", "9", "13", "8"…
## $ NombreDepartamento <chr> "HUILA", "CESAR", "CESAR", "CESAR", "BOGOTA D.C.", …
## $ CodigoMunicipio    <chr> "645", "439", "436", "435", "182", "437", "519", "4…
## $ municipio          <chr> "GARZON", "BECERRIL", "AGUACHICA", "VALLEDUPAR", "B…
## $ nombrecomercial    <chr> "ESTACION DE SERVICIO ZULUAGA", "ESTACION DE SERVIC…
## $ bandera            <chr> "BIOMAX", "SAVE", "PETROMIL", "TERPEL", "PETROBRAS"…
## $ direccion          <chr> "CALLE 4 No. 2-15", "Cra 5 No. 6-36", "KILOMETRO 62…
## $ producto           <chr> "BIODIESEL EXTRA", "BIODIESEL EXTRA", "GASOLINA COR…
## $ precio             <dbl> 8055, 6500, 6100, 6520, 7685, 6550, 7929, 7000, 823…
## $ estado             <chr> "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "…
p_comb %<>% mutate_if(is.character, as.factor);p_comb %>% glimpse #Convertir en factor las variables que son character
## Rows: 418,853
## Columns: 12
## $ periodo            <dbl> 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 201…
## $ mes                <fct> Enero, Enero, Enero, Enero, Enero, Enero, Enero, En…
## $ CodigoDepartamento <fct> 13, 9, 9, 9, 3, 9, 11, 9, 13, 8, 8, 1, 23, 22, 1, 1…
## $ NombreDepartamento <fct> "HUILA", "CESAR", "CESAR", "CESAR", "BOGOTA D.C.", …
## $ CodigoMunicipio    <fct> 645, 439, 436, 435, 182, 437, 519, 440, 659, 420, 4…
## $ municipio          <fct> "GARZON", "BECERRIL", "AGUACHICA", "VALLEDUPAR", "B…
## $ nombrecomercial    <fct> ESTACION DE SERVICIO ZULUAGA, ESTACION DE SERVICIO …
## $ bandera            <fct> BIOMAX, SAVE, PETROMIL, TERPEL, PETROBRAS, SAVE, OC…
## $ direccion          <fct> "CALLE 4 No. 2-15", "Cra 5 No. 6-36", "KILOMETRO 62…
## $ producto           <fct> BIODIESEL EXTRA, BIODIESEL EXTRA, GASOLINA CORRIENT…
## $ precio             <dbl> 8055, 6500, 6100, 6520, 7685, 6550, 7929, 7000, 823…
## $ estado             <fct> A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, …

Verifiar los NA:

nas<-!complete.cases(p_comb) #Determinar filas con al menos un NA
Nas_tabla<-p_comb[nas,] #Tabla registros con NA, 3 datos faltantes en nombre comercial
Nas_tabla
## # A tibble: 3 × 12
##   periodo mes   CodigoDepartamento NombreDepartamento CodigoMunicipio municipio
##     <dbl> <fct> <fct>              <fct>              <fct>           <fct>    
## 1    2017 Enero 1                  ANTIOQUIA          34              MEDELLIN 
## 2    2017 Enero 1                  ANTIOQUIA          34              MEDELLIN 
## 3    2017 Enero 1                  ANTIOQUIA          34              MEDELLIN 
## # ℹ 6 more variables: nombrecomercial <fct>, bandera <fct>, direccion <fct>,
## #   producto <fct>, precio <dbl>, estado <fct>

El nombre comercial es una variable categórica que podría ser reemplazada consultando con el dueño de la data.

Gráfica que identiica los NA

require(Amelia)
## Loading required package: Amelia
## Loading required package: Rcpp
## ## 
## ## Amelia II: Multiple Imputation
## ## (Version 1.8.1, built: 2022-11-18)
## ## Copyright (C) 2005-2023 James Honaker, Gary King and Matthew Blackwell
## ## Refer to http://gking.harvard.edu/amelia/ for more information
## ##
missmap(p_comb) 
## Warning: Unknown or uninitialised column: `arguments`.
## Unknown or uninitialised column: `arguments`.
## Warning: Unknown or uninitialised column: `imputations`.

#Observar datos atípicos:

summary(p_comb)
##     periodo            mes         CodigoDepartamento       NombreDepartamento
##  Min.   :2017   Junio    : 38293   1      : 43434     ANTIOQUIA      : 46126  
##  1st Qu.:2017   Julio    : 37827   3      : 34921     BOGOTA D.C.    : 36961  
##  Median :2018   Agosto   : 37742   11     : 34788     CUNDINAMARCA   : 35539  
##  Mean   :2018   Mayo     : 37574   24     : 32621     VALLE DEL CAUCA: 34696  
##  3rd Qu.:2019   Noviembre: 36982   17     : 31249     NARIÑO         : 31843  
##  Max.   :2019   Octubre  : 36890   21     : 17773     SANTANDER      : 18864  
##                 (Other)  :193545   (Other):224067     (Other)        :214824  
##  CodigoMunicipio                municipio     
##  182    : 34938   BOGOTA, D.C.       : 21910  
##  1035   : 12893   BOGOTA D.C.        : 15051  
##  34     :  9718   MEDELLIN           : 10333  
##  159    :  7931   BARRANQUILLA       :  8431  
##  183    :  5102   CALI               :  8426  
##  876    :  4481   CARTAGENA DE INDIAS:  5407  
##  (Other):343790   (Other)            :349295  
##                          nombrecomercial       bandera      
##  ESTACION DE SERVICIO SAN ANTONIO:   480   TERPEL  :154766  
##  ESTACION DE SERVICIO EL BOSQUE  :   405   BIOMAX  : 63828  
##  ESTACION DE SERVICIO EL JARDIN  :   362   MOBIL   : 62008  
##  ESTACION DE SERVICIO EL LAGO    :   325   TEXACO  : 42473  
##  ESTACION DE SERVICIO EL EDEN    :   321   PETROMIL: 25365  
##  (Other)                         :416957   ZEUSS   : 13860  
##  NA's                            :     3   (Other) : 56553  
##                              direccion     
##  VEREDA CODEMACO                  :   384  
##  CALLE DEL COMERCIO               :   305  
##  BARRIO EL PINDO DE TUMACO        :   228  
##  CALLE PRINCIPAL                  :   215  
##  KM 1 VIA NEIVA                   :   204  
##  VIA AL MAR KILOMETRO 92 EN TUBARA:   204  
##  (Other)                          :417313  
##                          producto          precio      estado    
##  BIODIESEL EXTRA             :168764   Min.   :  100   1: 12468  
##  GASOLINA CORRIENTE OXIGENADA:165615   1st Qu.: 8000   A:406385  
##  GASOLINA EXTRA OXIGENADA    : 55548   Median : 8755             
##  BIOACEM AL 9%               : 16413   Mean   : 8853             
##  GASOLINA CORRIENTE          :  5332   3rd Qu.: 9450             
##  ACPM - DIESEL               :  3218   Max.   :70910             
##  (Other)                     :  3963
boxplot(p_comb$precio) 

Existe un dato atípico en los precios, valor muy alto

atip<-filter(p_comb, precio>50000);atip #Detección de datos atípico en precios
## # A tibble: 1 × 12
##   periodo mes   CodigoDepartamento NombreDepartamento CodigoMunicipio municipio 
##     <dbl> <fct> <fct>              <fct>              <fct>           <fct>     
## 1    2019 Abril 17                 NARIÑO             799             SAN LOREN…
## # ℹ 6 more variables: nombrecomercial <fct>, bandera <fct>, direccion <fct>,
## #   producto <fct>, precio <dbl>, estado <fct>
p_comb$precio[p_comb$precio>50000]<-NA #Atípico como NA

Reemplazar NA con la mediana de los precios.

p_comb$precio <- replace_na(p_comb$precio,median(p_comb$precio,na.rm = T))

Mejora la distribución de los datos

boxplot(p_comb$precio) 

Estadísticas Descriptivas

Precios a través de los meses y años

p_comb$periodo<-as.factor(p_comb$periodo)

resum1 <- p_comb %>% group_by(mes,periodo) %>%
  summarise(p_prom=mean(precio))
## `summarise()` has grouped output by 'mes'. You can override using the `.groups`
## argument.
resum1
## # A tibble: 34 × 3
## # Groups:   mes [12]
##    mes       periodo p_prom
##    <fct>     <fct>    <dbl>
##  1 Abril     2017     8228.
##  2 Abril     2018     8704.
##  3 Abril     2019     9286.
##  4 Agosto    2017     8334.
##  5 Agosto    2018     8953.
##  6 Agosto    2019     9421.
##  7 Diciembre 2017     8540.
##  8 Diciembre 2018     9230.
##  9 Enero     2017     8117.
## 10 Enero     2018     8581.
## # ℹ 24 more rows
ggplot(resum1, aes(x = mes, y = p_prom, group=1)) +
  geom_line(linetype="dashed",size=1.2, col="cadetblue") +
  ggtitle("Precio promedio de combustibles mensual")+
  xlab("Año")+
  ylab("precio")+
  facet_grid(cols = vars(periodo))+
  theme(axis.text.x = element_text(angle = 90, hjust = 1))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

La tendencia de los precios de los combustibles a lo largo del tiempo ha sido creciente. Los tres gráficos revelan un incremento constante.

#Precios promedios por departamento

resum2 <- p_comb %>% group_by(producto,periodo,mes) %>%
  summarise(p_prom2=mean(precio))
## `summarise()` has grouped output by 'producto', 'periodo'. You can override
## using the `.groups` argument.
ggplot(resum2, aes(x=mes,y=p_prom2, color=producto))+
  geom_point(cex=3)+
  facet_grid(cols = vars(periodo))+
  theme(axis.text.x = element_text(angle = 90, hjust = 1))+
  xlab("mes")+
  ylab("precio promedio")+
  ggtitle("Precio promedio a través de los meses, por departamentos")

La gasolina extra oxigenada se ha mantenido a lo argo del tiempo con el mayor precio, seguida de la gasolina extra. El ACEM- Diesel económico es el combustible más económico. Sin embargo, todos presentan una tendencia creciente en sus precios a lo largo del tiempo.

#Distribución, precio del combustible según tipo:

ggplot(resum2, aes(x=p_prom2, fill=producto))+
  geom_density(alpha=0.4)+
  xlab("Precio promedio")+
  ylab("Densidad")+
  ggtitle("Distribución precio promedio combustibles según tipo")

"Las distribuciones reflejan los rangos de precios variados que presenta cada tipo de combustible"
## [1] "Las distribuciones reflejan los rangos de precios variados que presenta cada tipo de combustible"
ggplot(resum2, aes(x=p_prom2, fill=periodo))+
  geom_density(alpha=0.4)+
  xlab("Precio promedio")+
  ylab("Densidad")+
  ggtitle("Distribución precio promedio combustibles según periodo")

"Al mirar la distribución según los años, se puede apreciar nuevamente la tencdencia creciente."
## [1] "Al mirar la distribución según los años, se puede apreciar nuevamente la tencdencia creciente."

#Analizando el comportamiento de la gasolina corriente:

g_corriente<-subset(p_comb,subset=(producto=="GASOLINA CORRIENTE")) #Filtrar base por gasolina corriente

resum3 <- g_corriente %>% group_by(periodo,mes) %>%
  summarise(p_prom3=mean(precio))
## `summarise()` has grouped output by 'periodo'. You can override using the
## `.groups` argument.

#Precio de la gasolina corriente en el tiempo

ggplot(resum3, aes(x = mes, y = p_prom3, color=periodo)) +
  geom_point(stat="identity")+
  ggtitle("Precio promedio mensual gasolina corriente")+
  xlab("Año")+
  ylab("precio")+
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Al observar el comportamiento del precio promedio de la gasolina corriente, se puede observar un crecimiento alto en los meses de abril a mayo del año 2017, y el mes de julio dle mismo año, alcanzó el precio promedio más elevado.

#Mismo gráfico de manera interactiva

require(plotly)
## Loading required package: plotly
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:Hmisc':
## 
##     subplot
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
plot_ly(resum3, x = ~mes, y = ~p_prom3, type = "scatter", mode = "markers",
        color = ~periodo, colors = "Set1") %>% 
  layout(title = "Precio promedio mensual gasolina corriente",
         xaxis = list(title = "mes"), 
         yaxis = list(title = "Precio promedio"))