#librerias
suppressWarnings(suppressPackageStartupMessages({
library(sf)
library(dplyr)
library(leaflet)
library(tibble)
library(ggplot2)
library(lubridate)
library(e1071)
library(corrplot)
library(RColorBrewer)
library(stringi)
library(viridis)
library(ggthemes)
library(ggspatial)
library(scales)
library(shiny)
library(rsconnect)
}))Precios Promedio de Gas Natural Comprimido Vehicular (GNCV) en diferentes estaciones de servicio de Colombia
Contextualización de la Base de Datos
Descripción General
La base de datos contiene información sobre los precios promedio de Gas Natural Comprimido Vehicular (GNCV) en diferentes estaciones de servicio de Colombia. Los datos incluyen detalles sobre la ubicación geográfica y temporal del precio reportado, permitiendo el análisis de la variabilidad de precios en el tiempo y el espacio.
Objetivo de la Base de Datos
El propósito de esta base de datos es proporcionar información estructurada que permita realizar análisis sobre la distribución de precios del GNCV en Colombia, identificar patrones de variación geográfica y temporal, y facilitar la toma de decisiones en políticas energéticas y económicas.
Descripción de las Variables
Variables Temporales:
- FECHA_PRECIO: Fecha del precio reportado (YYYY-MM-DD).
- ANIO_PRECIO: Año del precio reportado.
- MES_PRECIO: Mes del precio reportado.
- DIA_PRECIO: Día del precio reportado.
Variables Geográficas:
- DEPARTAMENTO_EDS: Departamento donde se encuentra la estación de servicio.
- MUNICIPIO_EDS: Municipio donde se encuentra la estación de servicio.
- CODIGO_MUNICIPIO_DANE: Código DANE del municipio.
- LATITUD_MUNICIPIO: Coordenada de latitud del municipio.
- LONGITUD_MUNICIPIO: Coordenada de longitud del municipio.
Variables de la Estación de Servicio:
- NOMBRE_COMERCIAL_EDS: Nombre comercial de la estación de servicio.
- TIPO_COMBUSTIBLE: Tipo de combustible (en este caso, “GNCV”).
Variable de Precio:
- PRECIO_PROMEDIO_PUBLICADO: Precio promedio del GNCV en la estación de servicio (en pesos colombianos).
Librerias
library(readr)
Attaching package: 'readr'
The following object is masked from 'package:scales':
col_factor
df <- read_csv("/Users/elianafuentes/Documents/DATAVIZMAPASR/Copia de Consulta_Precios_Promedio_de_Gas_Natural_Comprimido_Vehicular__AUTOMATIZADO__20250314.csv")Rows: 9855 Columns: 12
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (7): MES_PRECIO, DIA_PRECIO, DEPARTAMENTO_EDS, MUNICIPIO_EDS, NOMBRE_CO...
dbl (4): ANIO_PRECIO, PRECIO_PROMEDIO_PUBLICADO, LATITUD_MUNICIPIO, LONGITU...
date (1): FECHA_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.
head(df, 10) # Muestra las primeras 10 filas# A tibble: 10 × 12
FECHA_PRECIO ANIO_PRECIO MES_PRECIO DIA_PRECIO DEPARTAMENTO_EDS MUNICIPIO_EDS
<date> <dbl> <chr> <chr> <chr> <chr>
1 2024-09-01 2024 09 01 SANTANDER BUCARAMANGA
2 2024-07-01 2024 07 01 SANTANDER BUCARAMANGA
3 2024-10-01 2024 10 01 CUNDINAMARCA CHIA
4 2024-10-01 2024 10 01 CALDAS MANIZALES
5 2024-10-01 2024 10 01 BOGOTA D.C. BOGOTA, D.C.
6 2024-10-01 2024 10 01 VALLE DEL CAUCA CALI
7 2024-10-01 2024 10 01 VALLE DEL CAUCA CALI
8 2024-10-01 2024 10 01 RISARALDA PEREIRA
9 2024-10-01 2024 10 01 BOGOTA D.C. BOGOTA, D.C.
10 2024-10-01 2024 10 01 VALLE DEL CAUCA CALI
# ℹ 6 more variables: NOMBRE_COMERCIAL_EDS <chr>,
# PRECIO_PROMEDIO_PUBLICADO <dbl>, TIPO_COMBUSTIBLE <chr>,
# CODIGO_MUNICIPIO_DANE <chr>, LATITUD_MUNICIPIO <dbl>,
# LONGITUD_MUNICIPIO <dbl>
df_variables <- tibble(
Macro_Variable = c("FECHA_PRECIO", "MES", "DEPARTAMENTO_EDS", "MUNICIPIO_EDS",
"NOMBRE_COMERCIAL_EDS", "TIPO_COMBUSTIBLE", "PRECIO_PROMEDIO_PUBLICADO"),
Tipo = c("Cuantitativa Discreta", "Cualitativa Ordinal", "Cualitativa Nominal",
"Cualitativa Nominal", "Cualitativa Nominal", "Cualitativa Nominal",
"Cuantitativa Continua")
)
print(df_variables)# A tibble: 7 × 2
Macro_Variable Tipo
<chr> <chr>
1 FECHA_PRECIO Cuantitativa Discreta
2 MES Cualitativa Ordinal
3 DEPARTAMENTO_EDS Cualitativa Nominal
4 MUNICIPIO_EDS Cualitativa Nominal
5 NOMBRE_COMERCIAL_EDS Cualitativa Nominal
6 TIPO_COMBUSTIBLE Cualitativa Nominal
7 PRECIO_PROMEDIO_PUBLICADO Cuantitativa Continua
Tipos de Variables
Variables Cuantitativas
- FECHA_PRECIO (Discreta): Representa el día en que se registró el precio del GNCV.
- PRECIO_PROMEDIO_PUBLICADO (Continua): Indica el precio promedio del GNCV en las estaciones de servicio.
Variables Cualitativas
- MES (Ordinal): Indica el mes del año.
- DEPARTAMENTO_EDS y MUNICIPIO_EDS (Nominales): Ubican geográficamente las estaciones de servicio.
- NOMBRE_COMERCIAL_EDS (Nominal): Identifica la marca o nombre de la estación.
- TIPO_COMBUSTIBLE (Nominal): Indica el tipo de combustible vendido en la estación.
Valores Faltantes
cat("\nPorcentaje de valores faltantes por columna:\n")
Porcentaje de valores faltantes por columna:
colMeans(is.na(df)) * 100 # Multiplicamos por 100 para obtener el porcentaje FECHA_PRECIO ANIO_PRECIO MES_PRECIO
0 0 0
DIA_PRECIO DEPARTAMENTO_EDS MUNICIPIO_EDS
0 0 0
NOMBRE_COMERCIAL_EDS PRECIO_PROMEDIO_PUBLICADO TIPO_COMBUSTIBLE
0 0 0
CODIGO_MUNICIPIO_DANE LATITUD_MUNICIPIO LONGITUD_MUNICIPIO
0 0 0
Análisis
- No hay valores faltantes en ninguna de las variables, lo que indica que la base de datos está completa y lista para su análisis sin necesidad de imputaciones o limpiezas adicionales.
# Seleccionar solo las variables numéricas
df_numeric <- df[, c("ANIO_PRECIO", "PRECIO_PROMEDIO_PUBLICADO", "LATITUD_MUNICIPIO", "LONGITUD_MUNICIPIO")]
# Ver el resumen estadístico
summary(df_numeric) ANIO_PRECIO PRECIO_PROMEDIO_PUBLICADO LATITUD_MUNICIPIO LONGITUD_MUNICIPIO
Min. :2021 Min. : 0 Min. : 1.749 Min. :-77.12
1st Qu.:2022 1st Qu.: 1800 1st Qu.: 4.500 1st Qu.:-75.80
Median :2023 Median : 2089 Median : 4.653 Median :-74.83
Mean :2023 Mean : 2170 Mean : 5.825 Mean :-75.01
3rd Qu.:2024 3rd Qu.: 2438 3rd Qu.: 6.258 3rd Qu.:-74.08
Max. :2025 Max. :19719 Max. :11.122 Max. :-70.87
Interpretación de los Datos
# Contar valores únicos
unique_values <- list(
"Departamentos únicos" = n_distinct(df$DEPARTAMENTO_EDS),
"Municipios únicos" = n_distinct(df$MUNICIPIO_EDS),
"Estaciones de servicio únicas" = n_distinct(df$NOMBRE_COMERCIAL_EDS),
"Tipos de combustible" = unique(df$TIPO_COMBUSTIBLE)
)
# Mostrar resultados
unique_values$`Departamentos únicos`
[1] 21
$`Municipios únicos`
[1] 85
$`Estaciones de servicio únicas`
[1] 471
$`Tipos de combustible`
[1] "GNCV"
Cobertura geográfica:
La base de datos abarca 21 departamentos y 85 municipios de Colombia, lo que permite realizar análisis espaciales y regionales sobre la distribución y variación de precios del GNCV.Número de estaciones de servicio:
Se cuenta con información de 471 estaciones de servicio, lo que indica una cobertura amplia y suficiente para realizar estudios sobre el comportamiento de precios en distintas regiones.Variedad de combustibles:
En este conjunto de datos, solo se encuentra el tipo de combustible “GNCV”, lo que confirma que el análisis se centrará exclusivamente en este tipo de energía vehicular.
Distribución de precios promedio de GNCV
# Crear el histograma de precios con densidad
ggplot(df, aes(x = PRECIO_PROMEDIO_PUBLICADO)) +
geom_histogram(aes(y = after_stat(density)), bins = 50, fill = "blue", color = "white", alpha = 0.7) + # Histograma
geom_density(color = "black", size = 1) + # Línea de densidad
geom_vline(aes(xintercept = mean(PRECIO_PROMEDIO_PUBLICADO, na.rm = TRUE)),
color = "red", linetype = "dashed", linewidth = 1.2) + # Línea de la media
ggtitle("Distribución de Precios Promedio de GNCV") +
xlab("Precio Promedio (COP)") +
ylab("Densidad") +
theme_minimal()Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
Analisis
Forma de la distribución:
La distribución tiene una fuerte asimetría positiva (sesgo a la derecha), lo que indica que la mayoría de los precios promedio están concentrados en un rango bajo, pero existen valores atípicos elevados que extienden la cola de la distribución.Rango de precios:
La mayoría de los precios se encuentran entre 2,000 y 3,000 COP, con una alta frecuencia en este intervalo.Posición de la media:
La media, representada por la línea roja punteada, está ligeramente desplazada hacia la derecha, lo que confirma el sesgo positivo. Esto significa que algunos precios elevados están influyendo en la media, elevándola por encima del valor más frecuente.
Analisis Sesgo
# Calcular el sesgo de la variable PRECIO_PROMEDIO_PUBLICADO
sesgo <- skewness(df$PRECIO_PROMEDIO_PUBLICADO, na.rm = TRUE)
# Mostrar el resultado
print(paste("Sesgo de la distribución:", round(sesgo, 3)))[1] "Sesgo de la distribución: 5.893"
# Interpretación del sesgo
if (sesgo > 0) {
print("La distribución está sesgada a la derecha (positiva).")
} else if (sesgo < 0) {
print("La distribución está sesgada a la izquierda (negativa).")
} else {
print("La distribución es simétrica.")
}[1] "La distribución está sesgada a la derecha (positiva)."
# Calcular sesgo y curtosis
sesgo <- skewness(df$PRECIO_PROMEDIO_PUBLICADO, na.rm = TRUE)
curtosis <- kurtosis(df$PRECIO_PROMEDIO_PUBLICADO, na.rm = TRUE)
# Mostrar resultados
print(paste("Sesgo de la distribución:", round(sesgo, 3)))[1] "Sesgo de la distribución: 5.893"
print(paste("Curtosis de la distribución:", round(curtosis, 3)))[1] "Curtosis de la distribución: 164.676"
# Interpretación
if (sesgo > 0) {
print("La distribución está sesgada a la derecha (positiva).")
} else if (sesgo < 0) {
print("La distribución está sesgada a la izquierda (negativa).")
} else {
print("La distribución es simétrica.")
}[1] "La distribución está sesgada a la derecha (positiva)."
if (curtosis > 3) {
print("La distribución es leptocúrtica (colas pesadas, valores extremos).")
} else if (curtosis < 3) {
print("La distribución es platicúrtica (más plana, menos valores extremos).")
} else {
print("La distribución es mesocúrtica (similar a la normal).")
}[1] "La distribución es leptocúrtica (colas pesadas, valores extremos)."
Interpretaciones
“La distribución es leptocúrtica (colas pesadas, valores extremos)”, significa que la curtosis es mayor a 3. Esto implica que:
La distribución tiene colas más pesadas que una normal, lo que indica una mayor presencia de valores extremos (outliers).
Los datos están más concentrados alrededor de la media, pero con más valores atípicos en los extremos.
Análisis de la Distribución de Precios por Departamento
# Boxplot simplificado y elegante
ggplot(df, aes(x = reorder(DEPARTAMENTO_EDS, PRECIO_PROMEDIO_PUBLICADO, FUN = median),
y = PRECIO_PROMEDIO_PUBLICADO,
fill = DEPARTAMENTO_EDS)) +
# Boxplot básico con colores agradables
geom_boxplot(alpha = 0.7, width = 0.6) +
# Paleta de colores sencilla pero atractiva
scale_fill_viridis_d(option = "C") +
# Formato para valores numéricos
scale_y_continuous(labels = scales::comma_format(big.mark = ".", decimal.mark = ",")) +
# Título y etiquetas simples
labs(
title = "Precios por Departamento",
x = "",
y = "Precio Promedio (COP)"
) +
# Tema minimalista
theme_minimal() +
theme(
# Textos simplificados
plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1, size = 10),
# Eliminar elementos innecesarios
legend.position = "none",
panel.grid.major.x = element_blank(),
# Más espacio entre elementos
plot.margin = margin(15, 15, 15, 15)
) +
# Orientación horizontal para mejor visualización
coord_flip()interpretaciones
La gráfica presenta la distribución de precios promedio en diferentes departamentos de Colombia. A continuación, se realiza un análisis de la información proporcionada:
Interpretación de la Gráfica
Departamentos Representados: La gráfica incluye una lista de departamentos colombianos, como Santander, Cundinamarca, Caldas, Bogotá D.C., Valle del Cauca, entre otros.
Rango de Precios: Los precios promedio están distribuidos en un rango que va desde 2,500 COP hasta 20,000 COP, con incrementos de 2,500 COP.
Análisis
Variabilidad Regional: La gráfica sugiere una variabilidad significativa en los precios promedio entre los diferentes departamentos, lo que podría reflejar diferencias en el desarrollo económico, la oferta y la demanda, y otros factores regionales.
Implicaciones: Esta distribución de precios puede ser útil para identificar áreas con mayores oportunidades de inversión, regiones con necesidades específicas de políticas económicas, o para el análisis de mercados específicos.
Grafica Evolucion del Precio por Departamento
# Definir los nombres de las columnas
departamento_col <- "DEPARTAMENTO_EDS"
fecha_col <- "FECHA_PRECIO"
precio_col <- "PRECIO_PROMEDIO_PUBLICADO"
# Seleccionar los 8 departamentos con más datos
dptos_con_mas_datos <- df %>%
count(.data[[departamento_col]], sort = TRUE) %>%
top_n(8, n) %>%
pull(.data[[departamento_col]])
# Filtrar el dataset
df_seleccionados <- df %>%
filter(.data[[departamento_col]] %in% dptos_con_mas_datos)
# Agrupar por fecha y departamento para obtener el precio promedio mensual
df_tiempo <- df_seleccionados %>%
mutate(!!fecha_col := floor_date(.data[[fecha_col]], "month")) %>%
group_by(.data[[fecha_col]], .data[[departamento_col]]) %>%
summarise(precio_prom = mean(.data[[precio_col]], na.rm = TRUE), .groups = "drop")
# Crear el gráfico
p <- ggplot(df_tiempo, aes(x = .data[[fecha_col]], y = precio_prom,
color = .data[[departamento_col]], group = .data[[departamento_col]])) +
geom_line(linewidth = 1) +
geom_point(size = 2) +
ggtitle("Evolución del Precio de GNCV por Departamento (2021-2025)") +
xlab("Fecha") +
ylab("Precio Promedio (COP)") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
scale_color_viridis_d(name = "Departamento")
# Mostrar el gráfico
print(p)# Guardar como imagen
ggsave("evolucion_precios_gncv_colombia.png", plot = p, dpi = 300, width = 14, height = 8, units = "in")Analisis
Tendencia Temporal:
- 2021Q1 - 2025Q1: La gráfica muestra la evolución trimestral del precio, lo que permite identificar tendencias a corto y largo plazo.
Variabilidad por Departamento:
- Diferencias Regionales: Los precios pueden variar significativamente entre departamentos debido a factores como la infraestructura de distribución, la demanda local y los costos operativos.
- Departamentos con Mayor Variación: Algunos departamentos pueden mostrar una mayor fluctuación en los precios, lo que podría estar relacionado con eventos específicos o cambios en la oferta y demanda.
Factores Influentes:
- Económicos: Cambios en la economía global o nacional, como fluctuaciones en los precios del petróleo, pueden afectar los precios del GNCV.
- Políticos: Políticas gubernamentales, subsidios o impuestos pueden influir en la evolución de los precios.
Tendencia General:
- Aumento Gradual: Si los precios muestran un incremento constante a lo largo del tiempo, esto podría indicar un aumento en los costos de producción, distribución o una mayor demanda de GNCV.
Diferencias por Departamento:
- Departamentos con Mayor Aumento: Algunos departamentos pueden mostrar un aumento más pronunciado en los precios, lo que podría estar relacionado con una mayor demanda, costos de distribución más altos o limitaciones en la infraestructura.
- Departamentos con Menor Aumento o Estabilidad: Otros departamentos pueden experimentar aumentos menores o mantener precios estables, lo que podría indicar una mejor infraestructura, menor demanda o políticas locales que estabilizan los precios.
Tendencia Temporal de Precios Promedio
# Asegurar que la columna de fecha es tipo Date
df$FECHA_PRECIO <- as.Date(df$FECHA_PRECIO)
# Agrupar por fecha y calcular el precio promedio
df_temporal <- df %>%
group_by(FECHA_PRECIO) %>%
summarise(PRECIO_PROMEDIO_PUBLICADO = mean(PRECIO_PROMEDIO_PUBLICADO, na.rm = TRUE)) # Promedio ignorando NAs
# Graficar la tendencia temporal
ggplot(df_temporal, aes(x = FECHA_PRECIO, y = PRECIO_PROMEDIO_PUBLICADO, group = 1)) +
geom_line(linetype = "dashed", size = 1.2, col = "cadetblue") + # Línea discontinua
geom_point(size = 2, col = "cadetblue") + # Puntos en la línea
ggtitle("Tendencia Temporal de Precios Promedio") +
xlab("Fecha") +
ylab("Precio Promedio") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) # Rotar etiquetas del eje XAnalisis
1. Tendencia General
- Se observa una clara tendencia alcista en los precios a lo largo del período analizado.
- Entre 2021 y mediados de 2022, el precio se mantiene relativamente estable, con pequeñas fluctuaciones.
- A partir de mediados de 2022, se inicia un aumento sostenido en los precios, que continúa hasta alcanzar su punto máximo en 2025.
2. Etapas Clave
- 2021 - 2022: Variabilidad moderada con ligeros picos, pero sin una tendencia definida.
- 2022 - 2023: Se observa un crecimiento acelerado en los precios, con un incremento constante.
- 2023 - 2024: Periodo de relativa estabilidad con fluctuaciones menores.
- 2024 - 2025: Se presenta un aumento significativo en los precios, alcanzando un pico alrededor de finales de 2024, seguido por un leve descenso.
Distribución de Densidad del Precio según el Periodo
df <- df %>%
mutate(periodo = as.factor(ANIO_PRECIO))
ggplot(df, aes(x = PRECIO_PROMEDIO_PUBLICADO, fill = periodo)) +
geom_density(alpha = 0.5) +
scale_fill_viridis_d(name = "Periodo") +
ggtitle("Distribución de Densidad del Precio según el Periodo") +
xlab("Precio Promedio Publicado") +
ylab("Densidad") +
theme_minimal() +
xlim(0, 5000) # Limitar el eje X hasta 5000Warning: Removed 5 rows containing non-finite outside the scale range
(`stat_density()`).
Interpretación
- Aumento de precios: Se observa un desplazamiento hacia la derecha, indicando un incremento en los precios promedio con el tiempo.
- Mayor variabilidad en años recientes: En 2024 y 2025, la dispersión es mayor, sugiriendo precios menos estables.
- Sesgo a la derecha: La presencia de valores altos en 2024 y 2025 sugiere un aumento de precios extremos.
- Tendencia general: El mercado del GNCV ha experimentado incrementos progresivos.
Precios Promedio por Departamento
# Análisis por departamento
cat("\nPrecios promedio por departamento:\n")
Precios promedio por departamento:
precio_por_departamento <- df %>%
group_by(DEPARTAMENTO_EDS) %>%
summarise(Precio_Promedio = mean(PRECIO_PROMEDIO_PUBLICADO, na.rm = TRUE)) %>%
arrange(desc(Precio_Promedio))
print(precio_por_departamento)# A tibble: 21 × 2
DEPARTAMENTO_EDS Precio_Promedio
<chr> <dbl>
1 CAUCA 2744
2 QUINDIO 2580.
3 CALDAS 2433.
4 ANTIOQUIA 2412.
5 VALLE DEL CAUCA 2393.
6 HUILA 2363.
7 RISARALDA 2244.
8 META 2228.
9 CAQUETA 2200
10 SANTANDER 2174.
# ℹ 11 more rows
Interpretación de los Precios Promedio por Departamento
La tabla presenta los precios promedio publicados:
Análisis General
Rango de Precios: Los precios promedio varían desde aproximadamente 1,950 COP hasta 2,744 COP. Esto indica una variabilidad significativa en los precios entre los diferentes departamentos.
Departamentos con Precios Más Altos:
- Cauca (2,744 COP): Este departamento tiene el precio promedio más alto, lo que podría deberse a factores como una mayor demanda, costos de distribución más elevados o una oferta limitada.
- Quindío (2,580 COP) y Caldas (2,433 COP): Estos departamentos también presentan precios relativamente altos, lo que podría estar relacionado con características económicas o geográficas específicas.
Departamentos con Precios Más Bajos:
- Bolívar (1,950 COP) y Atlántico (1,959 COP): Estos departamentos tienen los precios promedio más bajos, lo que podría indicar una mayor oferta, menores costos de distribución o una menor demanda.
- Bogotá D.C. (1,981 COP): A pesar de ser la capital, tiene uno de los precios más bajos, lo que podría deberse a una mayor competencia o una infraestructura más eficiente.
Top 10 Municipios con Precios Más Altos
# Análisis por municipio (Top 10 municipios con precios más altos)
cat("\nTop 10 municipios con precios más altos:\n")
Top 10 municipios con precios más altos:
top_municipios <- df %>%
group_by(MUNICIPIO_EDS) %>%
summarise(Precio_Promedio = mean(PRECIO_PROMEDIO_PUBLICADO, na.rm = TRUE)) %>%
arrange(desc(Precio_Promedio)) %>%
slice_head(n = 10)
print(top_municipios)# A tibble: 10 × 2
MUNICIPIO_EDS Precio_Promedio
<chr> <dbl>
1 FLORIDA 3315
2 SANTANDER DE QUILICHAO 3024.
3 LA CEJA 2813.
4 RIOFRIO 2750.
5 PIEDECUESTA 2749.
6 TULUA 2691.
7 ENVIGADO 2685
8 AGUACHICA 2619
9 ARMENIA 2590.
10 POPAYAN 2585.
# Gráfico de barras para el top 10 municipios
ggplot(top_municipios, aes(x = Precio_Promedio, y = reorder(MUNICIPIO_EDS, Precio_Promedio), fill = Precio_Promedio)) +
geom_col() +
scale_fill_viridis_c(option = "magma") +
ggtitle("Top 10 Municipios con Precios Más Altos") +
xlab("Precio Promedio") +
ylab("Municipio") +
theme_minimal()Descripción de la Gráfica
Esta visualización muestra los 10 municipios con los precios promedio más altos. Están ordenados de mayor a menor, siendo Florida el municipio con el precio más alto y Popayán el de menor precio dentro de este top.
Interpretación
1. Municipios con Precios Más Altos
- Florida y Santander de Quilichao lideran la lista con los precios más elevados.
- Esto podría deberse a una alta demanda, costos de producción elevados o características geográficas y económicas específicas de la región.
2. Municipios con Precios Intermedios en el Ranking
- La Ceja, Riofrío y Piedecuesta presentan precios similares, lo que sugiere una tendencia estable en estas zonas.
3. Municipios en la Parte Baja del Ranking
- Envigado, Aguachica, Armenia y Popayán cierran la lista, aunque siguen estando entre los más caros del país.
- A pesar de estar en los últimos lugares de este top, sus precios siguen siendo relativamente altos en comparación con otros municipios.
Matriz de Correlación
# Calcular la matriz de correlación
corr_matrix <- cor(df_numeric, use = "complete.obs")
# Configurar un mejor aspecto visual
par(mar = c(1, 1, 2, 1)) # Ajustar márgenes
# Crear una matriz de correlación más legible y atractiva
corrplot(corr_matrix,
# Método de visualización con círculos - más intuitivo
method = "circle",
# Paleta de colores más profesional
col = brewer.pal(11, "RdBu"),
# Ordenar las variables por similitud para mejor interpretación
order = "hclust",
# Añadir coeficientes pero solo para correlaciones significativas
addCoef.col = "black",
# Tamaño de los coeficientes - más legible
number.cex = 0.6,
# Mostrar solo la mitad triangular para mayor claridad
type = "upper",
# Mejorar el aspecto del texto de las etiquetas
tl.col = "black",
tl.cex = 0.7,
tl.srt = 45,
# Título del gráfico
title = "Matriz de Correlación de Variables",
mar = c(0, 0, 1, 0),
# Agregar líneas diagonales para separar mejor
diag = FALSE)
# Añadir un borde al gráfico para mejor definición
box("outer", lwd = 0.5, col = "gray70")Interpretación de las correlaciones
1️ Relación entre Año y Precio Promedio Publicado (0.65)
- Hay una correlación positiva moderada entre el año y el precio promedio publicado.
- Esto sugiere que los precios han aumentado con el tiempo, aunque no es una relación perfecta.
Relación entre Precio Promedio y Latitud/Longitud
- Latitud vs. Precio Promedio (-0.17) y Longitud vs. Precio Promedio (-0.29) muestran correlaciones negativas débiles.
- Esto indica que la ubicación geográfica tiene poca influencia directa sobre el precio promedio.
- Sin embargo, podría haber factores externos (como infraestructura o demanda) que expliquen mejor la variación de precios.
Relación entre Latitud y Longitud (0.21)
- La latitud y longitud tienen una correlación positiva baja, lo que es esperable ya que ambas están relacionadas con la ubicación geográfica.
Conclusión
- El precio promedio ha tendido a subir con los años.
- La ubicación (latitud/longitud) no parece ser un factor determinante en los precios, al menos de forma directa.
Graficos Shiny
# 2. Configurar tu cuenta de shinyapps.io
rsconnect::setAccountInfo(
name = "mqvqxd-eliana-fuentes",
token = "301725374EB1D98BD7C76D435C994E0C",
secret = "6cyhAjh4HtZcfoIvrqbKeZl5c8qPnlspmOI1LNuw"
)
# 3. Definir la ruta de la aplicación
app_dir <- "/Users/elianafuentes/mi_app_shiny"
# 4. Asegurarse de que el directorio existe
if (!dir.exists(app_dir)) {
dir.create(app_dir, recursive = TRUE)
cat("Directorio creado:", app_dir, "\n")
} else {
cat("El directorio ya existe:", app_dir, "\n")
}El directorio ya existe: /Users/elianafuentes/mi_app_shiny
# Define la interfaz de usuario
ui <- fluidPage(
# Título de la aplicación
titlePanel("Análisis de Precios de GNCV en Colombia"),
# Menú de carga de datos
sidebarLayout(
sidebarPanel(
fileInput("file", "Cargar archivo CSV con datos",
accept = c(".csv")),
helpText("Formato esperado: archivo CSV con columnas PRECIO_PROMEDIO_PUBLICADO, DEPARTAMENTO_EDS, FECHA_PRECIO, ANIO_PRECIO, MUNICIPIO_EDS"),
# Información sobre la aplicación
hr(),
h4("Controles"),
sliderInput("bins", "Bins para histograma:",
min = 10, max = 100, value = 50),
sliderInput("top_n", "Top municipios:",
min = 5, max = 20, value = 10),
numericInput("xlim", "Límite del eje X para densidad:",
value = 5000)
),
# Panel principal con pestañas para diferentes gráficos
mainPanel(
tabsetPanel(
tabPanel("Distribución de Precios",
plotOutput("histograma_densidad", height = "500px"),
verbatimTextOutput("estadisticas")),
tabPanel("Precios por Departamento",
plotOutput("boxplot_departamentos", height = "700px")),
tabPanel("Evolución Temporal",
plotOutput("evolucion_general", height = "500px"),
hr(),
plotOutput("evolucion_departamentos", height = "500px")),
tabPanel("Comparación por Periodo",
plotOutput("densidad_periodos", height = "500px")),
tabPanel("Top Municipios",
plotOutput("top_municipios", height = "500px")),
tabPanel("Correlaciones",
plotOutput("correlacion", height = "700px"))
)
)
)
)
# Define el servidor
server <- function(input, output) {
# Función reactiva para leer y procesar el archivo de datos
datos <- reactive({
req(input$file) # Requiere que se haya cargado un archivo
# Leer el archivo CSV
df <- read_csv(input$file$datapath)
# Asegurar que las fechas sean de tipo Date
if("FECHA_PRECIO" %in% colnames(df)) {
df$FECHA_PRECIO <- as.Date(df$FECHA_PRECIO)
}
return(df)
})
# 1. HISTOGRAMA DE PRECIOS CON DENSIDAD
output$histograma_densidad <- renderPlot({
df <- datos()
ggplot(df, aes(x = PRECIO_PROMEDIO_PUBLICADO)) +
geom_histogram(aes(y = after_stat(density)),
bins = input$bins,
fill = "blue",
color = "white",
alpha = 0.7) +
geom_density(color = "black", size = 1) +
geom_vline(aes(xintercept = mean(PRECIO_PROMEDIO_PUBLICADO, na.rm = TRUE)),
color = "red",
linetype = "dashed",
linewidth = 1.2) +
ggtitle("Distribución de Precios Promedio de GNCV") +
xlab("Precio Promedio (COP)") +
ylab("Densidad") +
theme_minimal()
})
# Estadísticas descriptivas
output$estadisticas <- renderPrint({
df <- datos()
stats <- summary(df$PRECIO_PROMEDIO_PUBLICADO)
print(stats)
})
# 2. BOXPLOT DE PRECIOS POR DEPARTAMENTO
output$boxplot_departamentos <- renderPlot({
df <- datos()
ggplot(df, aes(x = reorder(DEPARTAMENTO_EDS, PRECIO_PROMEDIO_PUBLICADO, FUN = median),
y = PRECIO_PROMEDIO_PUBLICADO,
fill = DEPARTAMENTO_EDS)) +
geom_boxplot(alpha = 0.7, width = 0.6) +
scale_fill_viridis_d(option = "C") +
scale_y_continuous(labels = scales::comma_format(big.mark = ".", decimal.mark = ",")) +
labs(
title = "Precios por Departamento",
x = "",
y = "Precio Promedio (COP)"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1, size = 10),
legend.position = "none",
panel.grid.major.x = element_blank(),
plot.margin = margin(15, 15, 15, 15)
) +
coord_flip()
})
# 3. EVOLUCIÓN TEMPORAL GENERAL
output$evolucion_general <- renderPlot({
df <- datos()
# Agrupar por fecha y calcular el precio promedio
df_temporal <- df %>%
group_by(FECHA_PRECIO) %>%
summarise(PRECIO_PROMEDIO_PUBLICADO = mean(PRECIO_PROMEDIO_PUBLICADO, na.rm = TRUE))
# Graficar la tendencia temporal
ggplot(df_temporal, aes(x = FECHA_PRECIO, y = PRECIO_PROMEDIO_PUBLICADO, group = 1)) +
geom_line(linetype = "dashed", size = 1.2, col = "cadetblue") +
geom_point(size = 2, col = "cadetblue") +
ggtitle("Tendencia Temporal de Precios Promedio") +
xlab("Fecha") +
ylab("Precio Promedio") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
})
# 4. EVOLUCIÓN TEMPORAL POR DEPARTAMENTO
output$evolucion_departamentos <- renderPlot({
df <- datos()
departamento_col <- "DEPARTAMENTO_EDS"
fecha_col <- "FECHA_PRECIO"
precio_col <- "PRECIO_PROMEDIO_PUBLICADO"
# Seleccionar los 8 departamentos con más datos
dptos_con_mas_datos <- df %>%
count(.data[[departamento_col]], sort = TRUE) %>%
top_n(8, n) %>%
pull(.data[[departamento_col]])
# Filtrar el dataset
df_seleccionados <- df %>%
filter(.data[[departamento_col]] %in% dptos_con_mas_datos)
# Agrupar por fecha y departamento para obtener el precio promedio mensual
df_tiempo <- df_seleccionados %>%
mutate(!!fecha_col := floor_date(.data[[fecha_col]], "month")) %>%
group_by(.data[[fecha_col]], .data[[departamento_col]]) %>%
summarise(precio_prom = mean(.data[[precio_col]], na.rm = TRUE), .groups = "drop")
# Crear el gráfico
ggplot(df_tiempo, aes(x = .data[[fecha_col]], y = precio_prom,
color = .data[[departamento_col]], group = .data[[departamento_col]])) +
geom_line(linewidth = 1) +
geom_point(size = 2) +
ggtitle("Evolución del Precio de GNCV por Departamento") +
xlab("Fecha") +
ylab("Precio Promedio (COP)") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
scale_color_viridis_d(name = "Departamento")
})
# 5. DENSIDAD POR PERIODOS
output$densidad_periodos <- renderPlot({
df <- datos()
df <- df %>%
mutate(periodo = as.factor(ANIO_PRECIO))
ggplot(df, aes(x = PRECIO_PROMEDIO_PUBLICADO, fill = periodo)) +
geom_density(alpha = 0.5) +
scale_fill_viridis_d(name = "Periodo") +
ggtitle("Distribución de Densidad del Precio según el Periodo") +
xlab("Precio Promedio Publicado") +
ylab("Densidad") +
theme_minimal() +
xlim(0, input$xlim) # Límite ajustable
})
# 6. TOP MUNICIPIOS
output$top_municipios <- renderPlot({
df <- datos()
# Crear el top de municipios
top_municipios <- df %>%
group_by(MUNICIPIO_EDS) %>%
summarise(Precio_Promedio = mean(PRECIO_PROMEDIO_PUBLICADO, na.rm = TRUE)) %>%
arrange(desc(Precio_Promedio)) %>%
head(input$top_n) # Usar el control
# Gráfico de barras para el top municipios
ggplot(top_municipios, aes(x = Precio_Promedio, y = reorder(MUNICIPIO_EDS, Precio_Promedio), fill = Precio_Promedio)) +
geom_col() +
scale_fill_viridis_c(option = "magma") +
ggtitle(paste0("Top ", input$top_n, " Municipios con Precios Más Altos")) +
xlab("Precio Promedio") +
ylab("Municipio") +
theme_minimal()
})
# 7. MATRIZ DE CORRELACIÓN
output$correlacion <- renderPlot({
df <- datos()
# Seleccionar solo columnas numéricas
df_numeric <- df %>%
select(where(is.numeric))
# Calcular la matriz de correlación
corr_matrix <- cor(df_numeric, use = "complete.obs")
# Configurar un mejor aspecto visual
par(mar = c(1, 1, 2, 1)) # Ajustar márgenes
# Crear la matriz de correlación
corrplot(corr_matrix,
method = "circle",
col = brewer.pal(11, "RdBu"),
order = "hclust",
addCoef.col = "black",
number.cex = 0.6,
type = "upper",
tl.col = "black",
tl.cex = 0.7,
tl.srt = 45,
title = "Matriz de Correlación de Variables",
mar = c(0, 0, 1, 0),
diag = FALSE)
# Añadir un borde al gráfico
box("outer", lwd = 0.5, col = "gray70")
})
}
# Ejecuta la aplicación
shinyApp(ui = ui, server = server)Georreferenciación del Precio Promedio del Gas Natural Comprimido Vehicular (GNCV) en Estaciones de Servicio de Colombia
# Ruta del shapefile
shapefile_path <- "/Users/elianafuentes/Documents/DATAVIZMAPASR/Copia de COLOMBIA/COLOMBIA.shp"
# Cargar el shapefile
geo_data <- st_read(shapefile_path)Reading layer `COLOMBIA' from data source
`/Users/elianafuentes/Documents/DATAVIZMAPASR/Copia de COLOMBIA/COLOMBIA.shp'
using driver `ESRI Shapefile'
Simple feature collection with 33 features and 11 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -81.73575 ymin: -4.227907 xmax: -66.84735 ymax: 13.39453
Geodetic CRS: WGS 84
# Crear el mapa usando ggplot2
mapa_colombia <- ggplot() +
# Añadir la capa geográfica con colores por departamento
geom_sf(data = geo_data, aes(fill = DPTO_CNMBR), color = "black", size = 0.5) +
# Usar una paleta de colores similar a "tab20" de matplotlib
scale_fill_viridis_d(option = "turbo", begin = 0, end = 0.9) +
# Añadir título
labs(
title = "División Departamental de Colombia",
fill = "Departamentos"
) +
# Tema personalizado para eliminar ejes y marco
theme_minimal() +
theme(
plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
axis.text = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank(),
legend.position = "right",
legend.title = element_text(face = "bold"),
plot.margin = margin(10, 10, 10, 10)
)
# Mostrar el mapa
print(mapa_colombia)# Definir las columnas correctas según la información proporcionada
departamento_col <- 'DEPARTAMENTO_EDS' # Columna de departamento en el CSV
precio_col <- 'PRECIO_PROMEDIO_PUBLICADO' # Columna de precio en el CSV
fecha_col <- 'FECHA_PRECIO' # Columna de fecha en el CSV
departamento_geo_col <- 'DPTO_CNMBR' # Columna de departamento en el shapefile
# Convertir la columna de fecha a formato fecha
df <- df %>%
mutate(!!fecha_col := as.Date(!!sym(fecha_col)))
# Normalizar nombres (convertir a mayúsculas y eliminar acentos)
df <- df %>%
mutate(!!departamento_col := toupper(stri_trans_general(!!sym(departamento_col), "Latin-ASCII")))
geo_data <- geo_data %>%
mutate(!!departamento_geo_col := toupper(stri_trans_general(!!sym(departamento_geo_col), "Latin-ASCII")))
# Obtener el último mes de datos disponibles
ultimo_mes <- max(df[[fecha_col]], na.rm = TRUE)
df_ultimo_mes <- df %>% filter(!!sym(fecha_col) == ultimo_mes)
# Calcular el precio promedio por departamento para el último mes
precio_por_dpto <- df_ultimo_mes %>%
group_by(!!sym(departamento_col)) %>%
summarise(precio_promedio = mean(!!sym(precio_col), na.rm = TRUE)) %>%
ungroup()
# Imprimir los valores únicos para verificar coincidencias
cat("\nDepartamentos en datos de precios:\n")
Departamentos en datos de precios:
print(sort(unique(df[[departamento_col]]))) [1] "ANTIOQUIA" "ATLANTICO" "BOGOTA D.C." "BOLIVAR"
[5] "BOYACA" "CALDAS" "CAQUETA" "CASANARE"
[9] "CAUCA" "CESAR" "CORDOBA" "CUNDINAMARCA"
[13] "HUILA" "MAGDALENA" "META" "QUINDIO"
[17] "RISARALDA" "SANTANDER" "SUCRE" "TOLIMA"
[21] "VALLE DEL CAUCA"
cat("\nDepartamentos en shapefile:\n")
Departamentos en shapefile:
print(sort(unique(geo_data[[departamento_geo_col]]))) [1] "AMAZONAS" "ANTIOQUIA"
[3] "ARAUCA" "ARCHIPIELAGO DE SAN ANDRES"
[5] "ATLANTICO" "BOGOTA D.C."
[7] "BOLIVAR" "BOYACA"
[9] "CALDAS" "CAQUETA"
[11] "CASANARE" "CAUCA"
[13] "CESAR" "CHOCO"
[15] "CORDOBA" "CUNDINAMARCA"
[17] "GUAINIA" "GUAVIARE"
[19] "HUILA" "LA GUAJIRA"
[21] "MAGDALENA" "META"
[23] "NARI?O" "NORTE DE SANTANDER"
[25] "PUTUMAYO" "QUINDIO"
[27] "RISARALDA" "SANTANDER"
[29] "SUCRE" "TOLIMA"
[31] "VALLE DEL CAUCA" "VAUPES"
[33] "VICHADA"
# Unir los datos de precios con el shapefile
geo_data_merged <- geo_data %>%
left_join(precio_por_dpto, by = setNames(departamento_col, departamento_geo_col))
# Verificar que la unión fue exitosa
cat("\nResumen de la unión:\n")
Resumen de la unión:
print(summary(geo_data_merged$precio_promedio)) Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
2350 2761 2970 3007 3343 3665 17
crear_mapa_precios <- function(geo_data, precio_columna, titulo, fecha = NULL) {
# Preparar título con fecha si está disponible
if (!is.null(fecha)) {
# Formatear fecha en español (mes y año)
mes <- format(fecha, "%B")
anio <- format(fecha, "%Y")
titulo_completo <- paste0(titulo, " - ", mes, " ", anio)
} else {
titulo_completo <- titulo
}
# Calcular centroides para las etiquetas
geo_data_centroids <- st_centroid(geo_data)
# Crear coordenadas para etiquetas
etiquetas <- geo_data_centroids %>%
st_coordinates() %>%
as.data.frame() %>%
rename(lon = X, lat = Y) %>%
bind_cols(geo_data) %>%
filter(!is.na(!!sym(precio_columna)))
# Crear el mapa con ggplot2
mapa <- ggplot() +
# Capa de departamentos con color basado en precio
geom_sf(data = geo_data, aes(fill = !!sym(precio_columna)),
color = "white", size = 0.2) +
# Paleta de colores similar a YlOrRd
scale_fill_viridis_c(
option = "magma",
direction = -1, # Invertir para que se parezca más a YlOrRd
na.value = "lightgrey",
name = "Precio promedio (COP)"
) +
# Agregar etiquetas con nombre de departamento y precio
geom_text(
data = etiquetas,
aes(
x = lon,
y = lat,
label = paste0(!!sym(departamento_geo_col), "\n$", round(!!sym(precio_columna), 0))
),
size = 2.5,
check_overlap = TRUE
) +
# Título y tema
labs(title = titulo_completo) +
theme_void() + # Equivalente a quitar ejes
theme(
plot.title = element_text(size = 15, hjust = 0.5, face = "bold"),
legend.position = "bottom",
legend.title = element_text(size = 10)
)
return(mapa)
}Distribución de Precios de Gas Natural Comprimido Vehicular en Colombia – Marzo 2025
# Crear el mapa de precios actuales
mapa_precios <- ggplot(geo_data_merged) +
geom_sf(aes(fill = precio_promedio), color = "white", size = 0.2) +
scale_fill_viridis(option = "magma", name = "Precio Promedio (COP)", na.value = "grey80") +
ggtitle("Distribución de Precios de Gas Natural Comprimido Vehicular en Colombia Marzo 2025") +
theme_minimal() +
theme(legend.position = "bottom")
# Guardar el gráfico
ggsave("mapa_precios_gncv_colombia.png", plot = mapa_precios, dpi = 300, width = 10, height = 8)
# Mostrar el mapa
print(mapa_precios)Interpretación de los colores
- Colores claros (amarillo): Indican precios más altos.
- Colores oscuros (morados): Representan precios más bajos.
Hallazgos clave
Departamentos con precios más altos
- Destacan zonas como Antioquia, Valle del Cauca y algunos sectores del Caribe con los precios más elevados (por encima de $3,400 COP).
- Esto podría deberse a factores como costos de distribución, impuestos locales o demanda del GNC.
Departamentos con precios más bajos - En Boyacá, Santander y partes de la región Andina, se observan precios más bajos (cerca de $2,400 - $2,600 COP).
- Es posible que estas zonas tengan mejor infraestructura de distribución de gas natural o incentivos para su uso.
Precios de GNCV por Municipio – Marzo 2025
# Convertir dataframe a objeto sf
df_ultimo_mes_sf <- st_as_sf(
df_ultimo_mes,
coords = c("LONGITUD_MUNICIPIO", "LATITUD_MUNICIPIO"),
crs = 4326 # Sistema de coordenadas WGS84
)
# Calcular rangos de precio
vmin <- min(df_ultimo_mes[[precio_col]], na.rm = TRUE)
vmax <- max(df_ultimo_mes[[precio_col]], na.rm = TRUE)
# Crear el mapa
mapa <- ggplot() +
# Dibujar el mapa base de Colombia
geom_sf(data = geo_data, fill = "lightgrey", color = "white") +
# Dibujar los puntos con colores según el precio
geom_sf(
data = df_ultimo_mes_sf,
aes(color = !!sym(precio_col)),
size = 3,
alpha = 0.7
) +
# Escala de color
scale_color_gradientn(
colors = rev(RColorBrewer::brewer.pal(7, "YlOrRd")),
limits = c(vmin, vmax),
name = "Precio Promedio GNCV (COP)"
) +
# Título
ggtitle(paste("Precios de GNCV por Municipio -", format(ultimo_mes, "%B %Y"))) +
# Tema gráfico
theme_minimal() +
theme(legend.position = "bottom")
# Mostrar el mapa
print(mapa)# Opcional: guardar el mapa
ggsave("mapa_precios_municipios.png", mapa, width = 10, height = 8, dpi = 300)Interpretación de los colores
- Tonos amarillos → Municipios con precios más altos.
- Tonos rojizos → Municipios con precios más bajos.
Hallazgos clave
Municipios con precios más altos
Los municipios con los costos más elevados de GNCV son:
1. Medellín (Antioquia) – $3,700 COP
2. Armenia (Quindío) – $3,699 COP
3. Armenia (Quindío) – $3,689 COP
4. Calarcá (Quindío) – $3,599 COP
5. Bello (Antioquia) – $3,599 COP
Se observa que el Quindío y Antioquia tienen los precios más altos, lo que podría estar influenciado por factores como costos de transporte, baja competencia o demanda alta en estas zonas.
Municipios con precios más bajos
Todos los valores mínimos corresponden a Bogotá D.C., con un precio estable de $1,899 COP.