Se analizaron cinco bases de datos individuales: clean_precios_carbon.csv, clean_precios_gas_natural.csv, clean_precios_petroleo.csv, clean_precios_gasolina.csv, y IPC.csv. Cada base contiene dos columnas: fecha (formato Date) y el precio correspondiente (numérico). Las bases de combustibles abarcan 8,579 observaciones desde el 1 de enero de 2000 hasta el 1 de enero de 2024, mientras que el IPC cubre desde julio de 1954 hasta enero de 2025, con 8,297 valores faltantes, sugiriendo diferencias en frecuencia
# Definir directorio de trabajo y cargar bases
setwd("C:/Users/s05e25/Documents/ejerciciofsjr")
# Cargar la base de IPC con el separador correcto y cambiar el formato decimal
ipc_df <- read_delim("IPC.csv", delim = ",", col_types = cols()) %>%
rename(fecha = 1, ipc = 2) %>% # Renombrar columnas
mutate(ipc = as.numeric(gsub(",", ".", ipc))) # Convertir IPC a numérico
# Guardar el archivo con el nuevo formato
write_csv(ipc_df, "IPC_formateado.csv")
# Cargar archivos
gasolina <- read.csv("clean_precios_gasolina.csv", stringsAsFactors = FALSE) %>%
rename(fecha = 1, Gasolina = 2)
petroleo <- read.csv("clean_precios_petroleo.csv", stringsAsFactors = FALSE) %>%
rename(fecha = 1, Petroleo = 2)
ipc <- read.csv("IPC_formateado.csv", stringsAsFactors = FALSE) %>%
rename(fecha = 1, IPC = 2)
carbon <- read.csv("clean_precios_carbon.csv", stringsAsFactors = FALSE) %>%
rename(fecha = 1, Carbon = 2)
gasnatural <- read.csv("clean_precios_gas_natural.csv", stringsAsFactors = FALSE) %>%
rename(fecha = 1, GasNatural = 2)
Se crea una función robusta para completar fechas faltantes con valores NA.
# Función para completar fechas faltantes
fecha_completa <- function(df, date_col, price_col) {
df[[date_col]] <- as.Date(df[[date_col]])
full_dates <- data.frame(seq(min(df[[date_col]], na.rm = TRUE),
max(df[[date_col]], na.rm = TRUE), by = "day"))
colnames(full_dates) <- date_col
df_complete <- full_dates %>%
left_join(df, by = date_col) %>%
arrange(.data[[date_col]])
return(df_complete)
}
Se unen las bases completas en una sola estructura.
# Se aplica la función a cada base
gasolina_completa <- fecha_completa(gasolina, "fecha", "Gasolina")
petroleo_completa <- fecha_completa(petroleo, "fecha", "Petroleo")
ipc_completa <- fecha_completa(ipc, "fecha", "IPC")
carbon_completa <- fecha_completa(carbon, "fecha", "Carbon")
gasnatural_completa <- fecha_completa(gasnatural, "fecha", "GasNatural")
Se extraen anio y mes usando lubridate.
# Unir bases con formato de columnas separadas por combustible
base_unida <- reduce(list(gasolina_completa, petroleo_completa, ipc_completa, carbon_completa, gasnatural_completa),
full_join, by = "fecha") %>%
arrange(fecha)
Se calculan porcentajes de NA y se reemplazan por promedios mensuales-anuales.
# Crear columnas de mes y año
base_unida <- base_unida %>%
mutate(mes = month(fecha),
año = year(fecha))
# Teniendo en cuenta que la base IPC contiene datos desde 1954, debemos filtrar la base
# para tener solo datos desde enero de 2000 hasta enero de 2024
base_unida <- base_unida %>%
filter(año >= 2000 & año < 2024 | (año == 2024 & mes == 1))
Se agrupa por mes y se asegura el rango 2000-2024.
# Identificar valores faltantes en el precio de algún combustible (se deja por fuera
# el año, mes y el IPC ya que este es mensual y mostraría un porcentaje alto)
valores_faltantes <- base_unida %>%
summarise(across(where(is.numeric) & !all_of(c("año", "mes", "IPC")), ~mean(is.na(.)) * 100)) %>%
pivot_longer(cols = everything(), names_to = "Variable", values_to = "% faltante")
# Tabla Valores Faltantes
valores_faltantes %>%
kable("html", caption = "Porcentaje de valores faltantes por columna") %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover", "condensed"))
| Variable | % faltante |
|---|---|
| Gasolina | 2.478118 |
| Petroleo | 2.478118 |
| Carbon | 2.478118 |
| GasNatural | 2.478118 |
# Agregar valores faltantes con el promedio mensual por combustible
base_unida <- base_unida %>%
group_by(año, mes) %>%
mutate(across(where(is.numeric), ~ifelse(is.na(.), mean(., na.rm = TRUE), .))) %>%
ungroup()
Se implementa la transformación nominal a real.
# Agregar información a valores promedios por mes y año
base_final_meses <- base_unida %>%
group_by(año, mes) %>%
summarise(across(where(is.numeric), mean, na.rm = TRUE)) %>%
ungroup()
## Warning: There was 1 warning in `summarise()`.
## i In argument: `across(where(is.numeric), mean, na.rm = TRUE)`.
## i In group 1: `año = 2000` `mes = 1`.
## Caused by warning:
## ! The `...` argument of `across()` is deprecated as of dplyr 1.1.0.
## Supply arguments directly to `.fns` through an anonymous function instead.
##
## # Previously
## across(a:b, mean, na.rm = TRUE)
##
## # Now
## across(a:b, \(x) mean(x, na.rm = TRUE))
## `summarise()` has grouped output by 'año'. You can override using the `.groups`
## argument.
Se exporta la base consolidada.
# Función para convertir precios nominales a precios reales
convert_to_real <- function(price_col, year_base, month_base, ipc_col, df) {
ipc_base <- df %>% filter(año == year_base & mes == month_base) %>% pull({{ipc_col}})
if (length(ipc_base) == 0 || is.na(ipc_base)) {
stop("No se encontró un valor válido de IPC para el año-mes base especificado.")
}
real_price_col <- paste0(deparse(substitute(price_col)), "_", year_base, "_", month_base, "_transformada")
df <- df %>% mutate({{real_price_col}} := {{price_col}} * ipc_base / {{ipc_col}})
return(df)
}
Se aplican las funciones que se desarrollaron en el literal anterior.
# Aplicar función para convertir a precios reales con base en cualquier mes y año (definido)
año_base <- 2023
mes_base <- 12
basedatos_consolidada <- convert_to_real(Gasolina, año_base, mes_base, IPC, base_final_meses)
basedatos_consolidada <- convert_to_real(Petroleo, año_base, mes_base, IPC, basedatos_consolidada)
basedatos_consolidada <- convert_to_real(Carbon, año_base, mes_base, IPC, basedatos_consolidada)
basedatos_consolidada <- convert_to_real(GasNatural, año_base, mes_base, IPC, basedatos_consolidada)
Se exportan los datos.
# Guardar la base de datos consolidada
write.csv(basedatos_consolidada, "basedatos_consolidada_transformados.csv", row.names = FALSE)
Se calculan estadísticas para precios nominales y reales de los combustibles, con 5 columnas (Variable, Observaciones, Promedio, Mínimo, Máximo, Desviación Estándar) y 8 filas (4 combustibles x 2 tipos de precio). Se explican los valores más importantes.
# Inicialmente se filtran solo precios nominales y reales de combustibles
combustibles <- basedatos_consolidada %>%
select(año, mes, starts_with("Gasolina"), starts_with("Petroleo"), starts_with("Carbon"), starts_with("GasNatural"))
# Renombramos las variables con el sufijo "real y nominal"
colnames(combustibles) <- colnames(combustibles) %>%
str_replace("\\d{4}_\\d{2}_transformada", "") # Eliminar cualquier "AAAA_MM_transformada"
colnames(combustibles) <- ifelse(colnames(combustibles) %in% c("año", "mes"),
colnames(combustibles), # Mantener "Año" y "Mes" sin cambios
ifelse(str_detect(colnames(combustibles), "_"),
paste0(colnames(combustibles), "real"),
paste0(colnames(combustibles), "_nominal")))
# Se crea una base de estadísticas "Observaciones, Promedio, min, max y desviación"
estadisticas_combustibles <- combustibles %>%
summarise(across(c(starts_with("Gasolina"), starts_with("Petroleo"), starts_with("Carbon"), starts_with("GasNatural")), list(
"Observaciones" = ~sum(!is.na(.)),
"Promedio" = ~round(mean(., na.rm = TRUE),2),
"Mínimo" = ~round(min(., na.rm = TRUE),2),
"Máximo" = ~round(max(., na.rm = TRUE),2),
"Desviación estándar" = ~round(sd(., na.rm = TRUE),2)
), .names = "{.col},{.fn}"))
# Se ajusta el formato para crear la Tabla
estadisticas_combustibles <- estadisticas_combustibles %>%
pivot_longer(cols = everything(), names_to = c("Variable", "Estadística"), names_sep = ",") %>%
pivot_wider(names_from = Estadística, values_from = value)
# Se crea la Tabla
estadisticas_combustibles %>%
kable("html", caption = "Estadísticas Descriptivas de los precios de los combustibles") %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover", "condensed")) %>%
column_spec(1, bold = TRUE, border_right = TRUE) %>%
row_spec(0, bold = TRUE, background = "#D3D3D3") %>%
scroll_box(height = "500px")
| Variable | Observaciones | Promedio | Mínimo | Máximo | Desviación estándar |
|---|---|---|---|---|---|
| Gasolina_nominal | 289 | 109.17 | 61.65 | 166.10 | 25.77 |
| Gasolina_real | 289 | 193.81 | 150.71 | 238.32 | 14.19 |
| Petroleo_nominal | 289 | 108.08 | 91.25 | 129.80 | 7.98 |
| Petroleo_real | 289 | 202.28 | 104.86 | 327.85 | 49.29 |
| Carbon_nominal | 289 | 96.98 | 74.21 | 123.16 | 12.68 |
| Carbon_real | 289 | 178.23 | 100.96 | 270.05 | 32.82 |
| GasNatural_nominal | 289 | 118.27 | 98.65 | 137.71 | 8.37 |
| GasNatural_real | 289 | 221.86 | 97.82 | 366.96 | 55.75 |
Se grafica la relación entre carbón y gasolina en 2023.
# 2.2 Gráfica de dispersión para 2023
año_seleccionado <- 2023
datos_2023 <- basedatos_consolidada %>% filter(año == año_seleccionado)
p1 <- ggplot(datos_2023, aes(x = Carbon_2023_12_transformada, y = Gasolina_2023_12_transformada)) +
geom_point(color = "#1F77B4", size = 2, alpha = 0.6) + # Puntos azules profesionales
geom_smooth(method = "lm", color = "#FF4040", se = TRUE, fill = "#FF9999", size = 1) + # Línea roja con intervalo
labs(title = "Figura 1. Dispersión de Precios Reales: Carbón vs. Gasolina (2023)",
x = "Precio Real del Carbón (base dic-2023, USD)",
y = "Precio Real de la Gasolina (base dic-2023, USD)") +
scale_x_continuous(labels = comma) +
scale_y_continuous(labels = comma) +
theme_minimal() +
theme(plot.title = element_text(face = "bold", size = 14),
axis.title = element_text(face = "bold", size = 12),
axis.text = element_text(size = 10),
legend.position = "none",
panel.grid.minor = element_blank())
print(p1)
## `geom_smooth()` using formula = 'y ~ x'
La Figura 1 muestra la relación entre los precios reales del carbón y la gasolina en 2023, ajustados por inflación con base en diciembre de 2023, donde la línea de ajuste lineal roja indica una correlación positiva moderada, sugiriendo que subidas en el precio del carbón se asocian con incrementos en la gasolina, posiblemente por interdependencias en los mercados energéticos globales. El intervalo de confianza en rosa claro revela incertidumbre, especialmente en precios altos, y la dispersión de puntos sugiere influencias como conflictos geopolíticos, cambios en subsidios en Colombia o variaciones estacionales, con mayor estabilidad en precios bajos. Aunque la correlación existe, no implica causalidad directa, destacando la necesidad de considerar factores externos, como políticas energéticas o precios del crudo Brent, para un análisis más completo del mercado energético de 2023.
Se compara la evolución de los precios reales de carbón, gas natural, petróleo y gasolina en 2023, con título, etiquetas, colores y elementos autocontenidos. Se interpreta en el documento.
# 2.3 Gráfica de serie de tiempo para 2023
año_seleccionado <- 2023
# Depuración: Verificar la estructura de basedatos_consolidada
#cat("Columnas disponibles en basedatos_consolidada:\n")
#print(colnames(basedatos_consolidada))
# Filtrar datos para 2023
datos_2023 <- basedatos_consolidada %>%
filter(año == año_seleccionado)
# Depuración: Verificar si hay datos y columnas esperadas
#cat("Número de filas en datos_2023:", nrow(datos_2023), "\n")
#cat("Columnas en datos_2023:\n")
#print(colnames(datos_2023))
# Seleccionar y transformar datos para la gráfica usando año y mes
datos_ts <- datos_2023 %>%
select(año, mes, Carbon = Carbon_2023_12_transformada,
`Gas Natural` = GasNatural_2023_12_transformada,
Petroleo = Petroleo_2023_12_transformada,
Gasolina = Gasolina_2023_12_transformada) %>%
pivot_longer(cols = -c(año, mes), names_to = "Combustible", values_to = "Precio") %>%
mutate(Periodo = factor(paste(año, mes), levels = unique(paste(año, mes)))) %>% # Crear factor para orden
filter(!is.na(Precio)) # Excluir valores NA en precio
# Depuración: Verificar datos transformados
#cat("Número de filas en datos_ts:", nrow(datos_ts), "\n")
#cat("Primeras filas de datos_ts:\n")
#print(head(datos_ts))
# Gráfica profesional (solo si hay datos)
if (nrow(datos_ts) > 0) {
p2 <- ggplot(datos_ts, aes(x = Periodo, y = Precio, color = Combustible, group = Combustible)) +
geom_line(size = 1) +
geom_point(size = 2) + # Añadir puntos para mayor claridad
scale_color_manual(values = c("Carbon" = "#2C3E50", "Gas Natural" = "#3498DB",
"Petroleo" = "#E74C3C", "Gasolina" = "#2ECC71")) + # Colores profesionales
labs(title = "Figura 2. Evolución de Precios Reales de Combustibles (2023)",
x = "Mes del Año 2023",
y = "Precio Real (base dic-2023, USD)",
color = "Combustible") +
scale_y_continuous(labels = comma) +
theme_minimal() +
theme(plot.title = element_text(face = "bold", size = 14),
axis.title = element_text(face = "bold", size = 12),
axis.text.x = element_text(angle = 45, hjust = 1, size = 10),
axis.text.y = element_text(size = 10),
legend.title = element_text(face = "bold", size = 12),
legend.text = element_text(size = 10),
panel.grid.minor = element_blank(),
panel.grid.major = element_line(color = "#E0E0E0")) +
guides(color = guide_legend(nrow = 2)) # Ajustar leyenda para mejor visualización
print(p2)
} else {
#cat("Error: No hay datos suficientes para generar la gráfica. Verifica los pasos anteriores.\n")
}
# Interpretación
La Figura 2 muestra mayor volatilidad en los precios reales de petróleo (rojo) y gasolina (verde) a lo largo de 2023, posiblemente influenciada por factores globales como conflictos o variaciones en la demanda. En contraste, carbón (gris oscuro) y gas natural (azul) presentan tendencias más estables, sugiriendo una oferta más predecible.