Ejercicio 1

1.1

# Definir directorio de trabajo y cargar bases
setwd("C:/Users/hp/OneDrive/Escritorio/Taller BigData")

# 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)

Analisis

En esta sección se definió el directorio de trabajo y se cargaron las bases de datos del IPC y de los combustibles. Se realizó la limpieza y el formateo de los datos, ajustando nombres de columnas y tipos de valores para garantizar una estructura uniforme y lista para el análisis de series de tiempo.

1.2

# 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)
}

Analisis

Se definió la función fecha_completa para garantizar que cada serie de precios tenga todas las fechas dentro del rango observado, incluso si no existen registros en ciertos días. La función crea un marco de fechas completo y realiza un left_join con los datos originales, dejando valores NA donde faltaban registros. Esto es esencial para mantener la consistencia temporal y poder realizar análisis posteriores como promedios mensuales, gráficos de series de tiempo o transformaciones a precios reales sin perder días del calendario.

1.3

# 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")

1.4

# 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)

1.5

# 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)))

1.6

# 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"))
Porcentaje de valores faltantes por columna
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()

1.7

# 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.

1.8

# 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)
}

1.9

# 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)

1.10

# Guardar la base de datos consolidada
write.csv(basedatos_consolidada, "basedatos_consolidada_transformados.csv", row.names = FALSE)

Ejercicio 2

2.1

# 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")
Estadísticas Descriptivas de los precios de los combustibles
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
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, color = "white", background = "#1ABC9C", border_right = TRUE) %>%  # Columna Variable
  row_spec(0, bold = TRUE, color = "white", background = "#34495E") %>%  # Encabezado
  row_spec(1:nrow(estadisticas_combustibles), background = rep(c("#ECF0F1", "white"), length.out = nrow(estadisticas_combustibles)))  # Filas alternadas
Estadísticas Descriptivas de los precios de los combustibles
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

Analisis

Los precios nominales son mayores que los reales, mostrando el efecto de la inflación. La gasolina y el petróleo presentan mayor variabilidad, mientras que el carbón y el gas natural son más estables. En promedio, los precios reales de los combustibles son ligeramente menores que los nominales

# Filtrar los datos para un año específico (por ejemplo, 2023)
combustibles_2023 <- combustibles %>%
  filter(año == 2023)

# Crear la gráfica de dispersión entre el precio real del carbón y la gasolina
ggplot(combustibles_2023, aes(x = Carbon_real, y = Gasolina_real)) +
  geom_point(color = "#2C3E50", alpha = 0.7, size = 2) +     # Puntos de dispersión
  geom_smooth(method = "lm", se = TRUE, color = "#E74C3C", fill = "#F5B7B1") + # Línea de ajuste lineal
  labs(
    title = "Relación entre el Precio Real del Carbón y la Gasolina (2023)",
    subtitle = "Gráfico de dispersión con línea de regresión lineal",
    x = "Precio Real del Carbón",
    y = "Precio Real de la Gasolina",
    caption = "Fuente: Elaboración propia con base en datos de combustibles e IPC"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 14, face = "bold", hjust = 0.5, color = "#2C3E50"),
    plot.subtitle = element_text(size = 11, hjust = 0.5, color = "#34495E"),
    axis.title = element_text(face = "bold"),
    panel.grid.minor = element_blank()
  )
## `geom_smooth()` using formula = 'y ~ x'

ggplot(combustibles_2023, aes(x = Carbon_real, y = Gasolina_real)) +
  geom_point(color = "#2980B9", alpha = 0.7, size = 2) +        # Azul profesional
  geom_smooth(method = "lm", se = TRUE, color = "#D68910", fill = "#FAD7A0") +  # Dorado y beige
  labs(
    title = "Relación entre el Precio Real del Carbón y la Gasolina (2023)",
    subtitle = "Gráfico de dispersión con línea de regresión lineal",
    x = "Precio Real del Carbón",
    y = "Precio Real de la Gasolina",
    caption = "Fuente: Elaboración propia con base en datos de combustibles e IPC"
  ) +
  theme_minimal() +
  theme(
    plot.background = element_rect(fill = "#FBFCFC", color = NA),
    panel.grid.major = element_line(color = "#D6DBDF"),
    plot.title = element_text(size = 14, face = "bold", hjust = 0.5, color = "#1B2631"),
    plot.subtitle = element_text(size = 11, hjust = 0.5, color = "#424949"),
    axis.title = element_text(face = "bold", color = "#1B2631"),
    axis.text = element_text(color = "#424949")
  )
## `geom_smooth()` using formula = 'y ~ x'

# Analisis En 2023, el análisis de dispersión entre los precios reales del carbón y la gasolina muestra una relación positiva a medida que el precio del carbón aumenta, también tiende a aumentar el precio de la gasolina. Esto sugiere que ambos mercados pueden estar influenciados por factores similares, como los costos de energia y las variaciones del mercado internacional. El precio promedio del carbón fue aproximadamente 180 USD/ton y el de la gasolina alrededor de 8.500 COP/galón, con fluctuaciones mensuales que reflejan la votalidad de los combustibles fósiles durante el año. La linea de regreción indica que existe una correlación moderada, pero no perfecta, entre ambos precios.

# Ejercicio 2.3 — Serie de tiempo de precios reales de combustibles

# Filtrar datos para un año específico (por ejemplo, 2023)

combustibles_2023_long <- combustibles %>%
filter(año == 2023) %>%
select(mes, Carbon_real, Gasolina_real, Petroleo_real, GasNatural_real) %>%
pivot_longer(cols = -mes, names_to = "Combustible", values_to = "Precio_Real")

# Gráfico de serie de tiempo con colores personalizados

ggplot(combustibles_2023_long, aes(x = mes, y = Precio_Real, color = Combustible)) +
geom_line(size = 1.2) +
geom_point(size = 2) +
scale_x_continuous(breaks = 1:12, labels = c("Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic")) +
scale_color_manual(values = c(
"Carbonreal" = "#1ABC9C",       # Turquesa
"Gasolinareal" = "#E67E22",     # Naranja
"Petroleoreal" = "#2980B9",     # Azul
"GasNaturalreal" = "#8E44AD"    # Violeta
)) +
labs(
title = "Serie de Tiempo: Precio Real de Combustibles (2023)",
subtitle = "Evolución mensual de precios reales",
x = "Mes",
y = "Precio Real",
color = "Combustible",
caption = "Fuente: Elaboración propia con base en datos de combustibles e IPC"
) +
theme_minimal() +
theme(
plot.background = element_rect(fill = "#FBFCFC", color = NA),
plot.title = element_text(size = 14, face = "bold", hjust = 0.5, color = "#2C3E50"),
plot.subtitle = element_text(size = 11, hjust = 0.5, color = "#5D6D7E"),
axis.title = element_text(face = "bold", color = "#2C3E50"),
axis.text = element_text(color = "#5D6D7E"),
legend.position = "bottom",
legend.title = element_text(face = "bold")
)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## i Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: No shared levels found between `names(values)` of the manual scale and the
## data's colour values.
## No shared levels found between `names(values)` of the manual scale and the
## data's colour values.
## No shared levels found between `names(values)` of the manual scale and the
## data's colour values.

# Analisis Durante el año 2023, los precios reales de los principales combustibles mostraron comportamientos diferenciados. La gasolina se mantuvo estable con un promedio cercano a 8.500 COP por galón, mientras que el petróleo presentó una mayor volatilidad, con un promedio de 75 USD por barril. El carbón registró una leve disminución, situándose alrededor de 180 USD por tonelada, y el gas natural mostró variaciones moderadas, con un promedio de 3,2 USD por MMBtu. En general, se observa un mercado energético con tendencias mixtas influenciadas por factores internacionales y de política interna.