Los datos utilizados provienen del Ministerio de Minas y Energía (SICOM). Representan las ventas de Gas Natural Comprimido Vehicular (GNCV) en Colombia. Hay datos desde el 16 de marzo de 2021 hasta el 15 de marzo de 2025, obtenidos diariamente en todas las EDS de distintos municipios de Colombia.

# Cargar paquetes necesarios
library(tidyverse)
library(skimr)
library(scales)
library(dplyr)
library(ggplot2)
library(knitr)
library(kableExtra)
library(sf)
library(leaflet)


# Cargar los datos
datos <- read.csv("Consulta_Ventas_de_Gas_Natural_Comprimido_Vehicular__AUTOMATIZADO__20250316.csv")

# Ver las primeras filas
head(datos)
##   FECHA_VENTA ANIO_VENTA MES_VENTA DIA_VENTA CODIGO_MUNICIPIO_DANE
## 1  2024-10-31       2024        10        31                 50226
## 2  2024-10-31       2024        10        31                 19001
## 3  2024-02-22       2024         2        22                 25754
## 4  2024-10-31       2024        10        31                 68307
## 5  2024-10-13       2024        10        13                  8758
## 6  2024-10-11       2024        10        11                 76001
##      DEPARTAMENTO MUNICIPIO   LATITUD  LONGITUD                  TIPO_AGENTE
## 1            META   CUMARAL  4.232526 -73.31477 ESTACION DE SERVICIO DE GNCV
## 2           CAUCA   POPAYAN  2.471704 -76.59194 ESTACION DE SERVICIO DE GNCV
## 3    CUNDINAMARCA    SOACHA  4.581866 -74.24030 ESTACION DE SERVICIO DE GNCV
## 4       SANTANDER     GIRON  6.976734 -73.20527 ESTACION DE SERVICIO DE GNCV
## 5       ATLANTICO   SOLEDAD 10.906906 -74.77843 ESTACION DE SERVICIO DE GNCV
## 6 VALLE DEL CAUCA      CALI  3.399044 -76.57649 ESTACION DE SERVICIO DE GNCV
##   TIPO_DE_COMBUSTIBLE EDS_ACTIVAS NUMERO_DE_VENTAS VEHICULOS_ATENDIDOS
## 1                 GNV           2              173                 118
## 2                 GNV           1              139                  99
## 3                 GNV           4             1322                1095
## 4                 GNV           1              200                 154
## 5                 GNV           6             3188                2234
## 6                 GNV          47            17270                9687
##   CANTIDAD_VOLUMEN_SUMINISTRADO
## 1                       1220.92
## 2                       1133.75
## 3                      12901.08
## 4                       1287.77
## 5                      17727.51
## 6                     106760.55

Aquí se logra apreciar que en la fila 6 el dato “Valle del Cauca” está escrito con espacios. Conviene reemplazarlos en todos las celdas por guiones bajos, tanto en esta columna como en la de municipio.

datos <- datos %>%
  mutate(DEPARTAMENTO = gsub(" ", "_", DEPARTAMENTO),
         MUNICIPIO = gsub(" ", "_", MUNICIPIO))

unique(datos$DEPARTAMENTO)
##  [1] "META"            "CAUCA"           "CUNDINAMARCA"    "SANTANDER"      
##  [5] "ATLANTICO"       "VALLE_DEL_CAUCA" "TOLIMA"          "CORDOBA"        
##  [9] "MAGDALENA"       "BOYACA"          "CESAR"           "LA_GUAJIRA"     
## [13] "CALDAS"          "SUCRE"           "ANTIOQUIA"       "HUILA"          
## [17] "QUINDIO"         "BOLIVAR"         "CASANARE"        "RISARALDA"      
## [21] "BOGOTA_D.C."     "CAQUETA"
unique(datos$MUNICIPIO)
##   [1] "CUMARAL"                     "POPAYAN"                    
##   [3] "SOACHA"                      "GIRON"                      
##   [5] "SOLEDAD"                     "CALI"                       
##   [7] "LERIDA"                      "SAHAGUN"                    
##   [9] "GRANADA"                     "SANTA_MARTA"                
##  [11] "TUNJA"                       "BOSCONIA"                   
##  [13] "IBAGUE"                      "RIOHACHA"                   
##  [15] "SITIONUEVO"                  "MANIZALES"                  
##  [17] "SINCELEJO"                   "HONDA"                      
##  [19] "CAUCASIA"                    "NEIVA"                      
##  [21] "BUENAVENTURA"                "GIRARDOT"                   
##  [23] "SAN_SEBASTIAN_DE_MARIQUITA"  "BARBOSA"                    
##  [25] "SAN_MARTIN"                  "FUSAGASUGA"                 
##  [27] "CARTAGO"                     "CALARCA"                    
##  [29] "TULUA"                       "PUERTO_TRIUNFO"             
##  [31] "PUERTO_COLOMBIA"             "MALAMBO"                    
##  [33] "ACACIAS"                     "MAGANGUE"                   
##  [35] "CIENAGA"                     "VILLAVICENCIO"              
##  [37] "SABOYA"                      "LA_CEJA"                    
##  [39] "YOPAL"                       "ESPINAL"                    
##  [41] "JAMUNDI"                     "AGUACHICA"                  
##  [43] "ARMENIA"                     "GIRARDOTA"                  
##  [45] "RIONEGRO"                    "PALMIRA"                    
##  [47] "ITAGUI"                      "BELLO"                      
##  [49] "FACATATIVA"                  "MONTERIA"                   
##  [51] "FLORIDA"                     "TURBACO"                    
##  [53] "ZIPAQUIRA"                   "CARTAGENA_DE_INDIAS"        
##  [55] "LA_DORADA"                   "CAJICA"                     
##  [57] "SANTA_ROSA_DE_CABAL"         "RIOFRIO"                    
##  [59] "MONTELIBANO"                 "PUERTO_SALGAR"              
##  [61] "LORICA"                      "PEREIRA"                    
##  [63] "APARTADO"                    "VALLEDUPAR"                 
##  [65] "CHIA"                        "GUADALAJARA_DE_BUGA"        
##  [67] "PLANETA_RICA"                "CERETE"                     
##  [69] "GUARNE"                      "DOSQUEBRADAS"               
##  [71] "COROZAL"                     "TENJO"                      
##  [73] "MEDELLIN"                    "DUITAMA"                    
##  [75] "VILLA_DE_SAN_DIEGO_DE_UBATE" "YUMBO"                      
##  [77] "COTA"                        "ENVIGADO"                   
##  [79] "PIEDECUESTA"                 "SOPO"                       
##  [81] "LA_CALERA"                   "LEBRIJA"                    
##  [83] "BARRANCABERMEJA"             "SABANETA"                   
##  [85] "SOGAMOSO"                    "MOSQUERA"                   
##  [87] "MADRID"                      "FLORIDABLANCA"              
##  [89] "PAILITAS"                    "CHIQUINQUIRA"               
##  [91] "BUCARAMANGA"                 "LA_MESA"                    
##  [93] "BARRANQUILLA"                "CHINCHINA"                  
##  [95] "SOTAQUIRA"                   "GUADUAS"                    
##  [97] "BOGOTA,_D.C."                "SANTANDER_DE_QUILICHAO"     
##  [99] "AGUAZUL"                     "SAN_PEDRO"                  
## [101] "ROLDANILLO"                  "ARMERO"                     
## [103] "FUNZA"                       "VILLAMARIA"                 
## [105] "VENADILLO"                   "PAZ_DE_ARIPORO"             
## [107] "VILLANUEVA"                  "EL_CARMEN_DE_BOLIVAR"       
## [109] "LA_UNION"                    "FLORENCIA"                  
## [111] "GACHANCIPA"

Los datos fueron obtenidos de 111 municipios en 22 departamentos. Se procede ahora con un resumen.

# Resumen estadístico general
summary(datos)
##  FECHA_VENTA          ANIO_VENTA     MES_VENTA        DIA_VENTA    
##  Length:124646      Min.   :2021   Min.   : 1.000   Min.   : 1.00  
##  Class :character   1st Qu.:2022   1st Qu.: 4.000   1st Qu.: 8.00  
##  Mode  :character   Median :2023   Median : 7.000   Median :16.00  
##                     Mean   :2023   Mean   : 6.531   Mean   :15.73  
##                     3rd Qu.:2024   3rd Qu.:10.000   3rd Qu.:23.00  
##                     Max.   :2025   Max.   :12.000   Max.   :31.00  
##  CODIGO_MUNICIPIO_DANE DEPARTAMENTO        MUNICIPIO            LATITUD      
##  Min.   : 5001         Length:124646      Length:124646      Min.   : 1.749  
##  1st Qu.:15759         Class :character   Class :character   1st Qu.: 4.651  
##  Median :25473         Mode  :character   Mode  :character   Median : 5.316  
##  Mean   :38470                                               Mean   : 6.131  
##  3rd Qu.:68081                                               3rd Qu.: 7.204  
##  Max.   :85440                                               Max.   :11.243  
##     LONGITUD      TIPO_AGENTE        TIPO_DE_COMBUSTIBLE  EDS_ACTIVAS     
##  Min.   :-77.12   Length:124646      Length:124646       Min.   :  1.000  
##  1st Qu.:-75.59   Class :character   Class :character    1st Qu.:  1.000  
##  Median :-74.81   Mode  :character   Mode  :character    Median :  1.000  
##  Mean   :-74.70                                          Mean   :  4.429  
##  3rd Qu.:-73.82                                          3rd Qu.:  3.000  
##  Max.   :-70.87                                          Max.   :116.000  
##  NUMERO_DE_VENTAS VEHICULOS_ATENDIDOS CANTIDAD_VOLUMEN_SUMINISTRADO
##  Min.   :    1    Min.   :    1.0     Min.   :      0              
##  1st Qu.:   80    1st Qu.:   64.0     1st Qu.:    964              
##  Median :  211    Median :  161.0     Median :   2365              
##  Mean   : 1194    Mean   :  753.1     Mean   :  12011              
##  3rd Qu.:  650    3rd Qu.:  479.0     3rd Qu.:   6467              
##  Max.   :59792    Max.   :29474.0     Max.   :5708358
# Resumen más detallado con skimr
skim(datos)
Data summary
Name datos
Number of rows 124646
Number of columns 15
_______________________
Column type frequency:
character 5
numeric 10
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
FECHA_VENTA 0 1 10 10 0 1461 0
DEPARTAMENTO 0 1 4 15 0 22 0
MUNICIPIO 0 1 4 27 0 111 0
TIPO_AGENTE 0 1 28 28 0 1 0
TIPO_DE_COMBUSTIBLE 0 1 3 3 0 1 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
ANIO_VENTA 0 1 2022.82 1.16 2021.00 2022.00 2023.00 2024.00 2025.00 ▅▇▇▇▂
MES_VENTA 0 1 6.53 3.47 1.00 4.00 7.00 10.00 12.00 ▇▅▅▅▇
DIA_VENTA 0 1 15.73 8.80 1.00 8.00 16.00 23.00 31.00 ▇▇▇▇▆
CODIGO_MUNICIPIO_DANE 0 1 38470.49 26572.02 5001.00 15759.00 25473.00 68081.00 85440.00 ▇▆▂▃▅
LATITUD 0 1 6.13 2.27 1.75 4.65 5.32 7.20 11.24 ▂▇▅▂▂
LONGITUD 0 1 -74.70 1.13 -77.12 -75.59 -74.81 -73.82 -70.87 ▃▇▆▂▁
EDS_ACTIVAS 0 1 4.43 11.50 1.00 1.00 1.00 3.00 116.00 ▇▁▁▁▁
NUMERO_DE_VENTAS 0 1 1194.31 3754.53 1.00 80.00 211.00 650.00 59792.00 ▇▁▁▁▁
VEHICULOS_ATENDIDOS 0 1 753.06 2364.11 1.00 64.00 161.00 479.00 29474.00 ▇▁▁▁▁
CANTIDAD_VOLUMEN_SUMINISTRADO 0 1 12011.21 58808.60 0.01 964.22 2364.53 6467.03 5708357.62 ▇▁▁▁▁

El conjunto de datos contiene más de 120 mil instancias (cada una representa una fecha específica en un lugar específico) sin datos faltantes. Hay 15 columnas, pero con lo anterior, se evidencia que las columnas “TIPO_AGENTE” y “TIPO_DE_COMBUSTIBLE” no son útiles, pues todas las filas tienen el mismo valor: “Estación de servicio de GNCV” y “GNV” para ambas columnas respectivamente. Es viable eliminarlas.

datos <- datos %>%
  select(-TIPO_AGENTE, -TIPO_DE_COMBUSTIBLE)
colnames(datos)
##  [1] "FECHA_VENTA"                   "ANIO_VENTA"                   
##  [3] "MES_VENTA"                     "DIA_VENTA"                    
##  [5] "CODIGO_MUNICIPIO_DANE"         "DEPARTAMENTO"                 
##  [7] "MUNICIPIO"                     "LATITUD"                      
##  [9] "LONGITUD"                      "EDS_ACTIVAS"                  
## [11] "NUMERO_DE_VENTAS"              "VEHICULOS_ATENDIDOS"          
## [13] "CANTIDAD_VOLUMEN_SUMINISTRADO"

Enfocándonos en las últimas variables, vemos cómo se distribuyen por departamento, considerando todos los días registrados (sumatoria).

# Agrupar por DEPARTAMENTO y calcular los totales
tabla_departamentos <- datos %>%
  group_by(DEPARTAMENTO) %>%
  summarise(
    CANTIDAD_VOLUMEN_SUMINISTRADO = sum(CANTIDAD_VOLUMEN_SUMINISTRADO, na.rm = TRUE),
    NUMERO_DE_VENTAS = sum(NUMERO_DE_VENTAS, na.rm = TRUE),
    VEHICULOS_ATENDIDOS = sum(VEHICULOS_ATENDIDOS, na.rm = TRUE)
  ) %>%
  arrange(desc(CANTIDAD_VOLUMEN_SUMINISTRADO))  # Ordenar de mayor a menor

# Crear tabla con kable y kableExtra
tabla_departamentos %>%
  kable("html", caption = "Totales por Departamento") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "responsive"), 
                full_width = F, position = "center") %>%
  column_spec(1, bold = TRUE)  # Resaltar la columna de DEPARTAMENTO
Totales por Departamento
DEPARTAMENTO CANTIDAD_VOLUMEN_SUMINISTRADO NUMERO_DE_VENTAS VEHICULOS_ATENDIDOS
BOGOTA_D.C. 617009229 42101625 28186660
VALLE_DEL_CAUCA 143238427 21118098 13185676
ANTIOQUIA 128958719 8247933 6779086
CUNDINAMARCA 89047533 5100147 4165978
ATLANTICO 88945164 15365958 9043304
META 81367630 12846812 6320344
SANTANDER 55038434 7865867 5342441
TOLIMA 40350686 6190899 3195345
BOLIVAR 37177772 1550333 1021226
RISARALDA 33597231 4595396 3258343
MAGDALENA 26882815 4374697 2104219
CORDOBA 22078794 3113985 1642072
BOYACA 21886187 2246451 1565870
CALDAS 21737195 2567684 1359996
QUINDIO 20552284 2903925 1751027
HUILA 18415738 3106540 1623156
CESAR 16324062 984857 714997
CASANARE 15583607 2017263 961334
SUCRE 14693273 2060198 1327310
LA_GUAJIRA 3017107 363305 213109
CAUCA 1217429 139860 101883
CAQUETA 29496 3644 2858

A continuación, la información de esta tabla expuesta con gráficos de barras para una mejor visualización.

# Función para generar gráficos de barras
crear_grafico <- function(df, variable, titulo, etiqueta_y, color) {
  ggplot(df, aes(x = reorder(DEPARTAMENTO, !!sym(variable)), y = !!sym(variable))) +
    geom_bar(stat = "identity", fill = color) +
    labs(title = titulo, x = "Departamento", y = etiqueta_y) +
    theme_minimal() +
    coord_flip() +  # Para mejorar la legibilidad
    scale_y_continuous(labels = comma)  # Evitar notación científica
}

# Gráfico para Volumen
grafico_volumen <- crear_grafico(tabla_departamentos, "CANTIDAD_VOLUMEN_SUMINISTRADO", "Cantidad de volumen suministrado por departamento", "Volumen", "pink")

# Gráfico para Número de Ventas
grafico_ventas <- crear_grafico(tabla_departamentos, "NUMERO_DE_VENTAS", "Número de Ventas por Departamento", "Número de Ventas", "brown")

# Gráfico para Vehículos Atendidos
grafico_vehiculos <- crear_grafico(tabla_departamentos, "VEHICULOS_ATENDIDOS", "Vehículos Atendidos por Departamento", "Vehículos Atendidos", "purple")

grafico_volumen

grafico_ventas

grafico_vehiculos

De los diagramas se deduce lo siguiente:

Este gráfico sugiere una fuerte concentración del suministro en ciertas regiones, lo cual es acorde a factores como el tamaño de la población, el desarrollo económico o la infraestructura.

Seguimos con la georreferenciación

colombia_map <- st_read("MGN2023_DPTO_POLITICO/MGN_ADM_DPTO_POLITICO.shp")
## Reading layer `MGN_ADM_DPTO_POLITICO' from data source 
##   `C:\Users\f1714\Documents\VD\actividadGeorreferenciacion\MGN2023_DPTO_POLITICO\MGN_ADM_DPTO_POLITICO.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 33 features and 8 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -81.73562 ymin: -4.229406 xmax: -66.84722 ymax: 13.39473
## Geodetic CRS:  MAGNA-SIRGAS
# Extraer los nombres de los departamentos desde la base de datos y el shapefile
dpto_1 <- tolower(tabla_departamentos$DEPARTAMENTO)  # Base de datos
dpto_2 <- tolower(colombia_map$dpto_cnmbr)        # Archivo shapefile

Luego de cargar el mapa se tratan los nombres de los departamentos.

# Verificar qué nombres de la base de datos no están en el shapefile
M1 <- which(is.na(match(dpto_1, dpto_2)))

# Corregir nombres que no coinciden entre la base de datos y el shapefile
dpto_2 <- str_replace_all(dpto_2, "bogotá, d.c.", "bogota_d.c.")
dpto_2 <- str_replace_all(dpto_2, " ", "_")
dpto_2 <- str_replace_all(dpto_2, "á", "a")
dpto_2 <- str_replace_all(dpto_2, "í", "i")
dpto_2 <- str_replace_all(dpto_2, "ó", "o")

# Agregar los nombres corregidos como códigos para unir las bases de datos
tabla_departamentos$codigo <- dpto_1
colombia_map$codigo <- dpto_2

Una vez se hacen coincidir los nombres de los departamentos y se crea una columna con estos, se unen las tablas y se crea el mapa con la cantidad de volumen suministrado durante los años en cuestión.

colombia_mapa_datos <- colombia_map %>%
  left_join(tabla_departamentos, by = "codigo")

ggplot(data = colombia_mapa_datos) +
  geom_sf(aes(fill = CANTIDAD_VOLUMEN_SUMINISTRADO), color = "pink") +
  scale_fill_viridis_c(option = "magma", name = "Volumen suministrado") +
  theme_minimal() +
  labs(title = "Volumen de GNV Suministrado por Departamento en Colombia (Marzo 2021 - Marzo 2025)",
       caption = "Fuente: Datos SICOM y DANE")

La versión interactiva de este mapa está disponible como una aplicación Shiny independiente, a la que se puede acceder en la siguiente dirección: https://5bbtow-peter-sagan.shinyapps.io/colombia-gnv-map/

La aplicación Shiny permite: - Filtrar departamentos por volumen suministrado - Cambiar la paleta de colores del mapa - Mostrar u ocultar los nombres de los departamentos - Descargar los datos agregados