Ejercicio 1

1.1

La base de datos presentada a continuación contiene cada una 2 variables numéricas de 8579 observaciones diarias para los precios del carbon, el gas natural, la gasolina y el petróleo en un periodo comprendido entre enero del 2000 hasta enero del 2024, y 847 observaciones para el IPC mensual desde 1957 hasta 2025

# Definir el directorio de trabajo y cargar la bases
setwd("C:/Users/s12e03/Downloads/Clase 03-09")

# 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)
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)
IPC <- read.csv("IPC.csv", stringsAsFactors = FALSE) %>%
  rename(fecha = 1, IPC = 2)

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

1.3

# Se aplica la función definida en 1.2
Gasolina_completa <- fecha_completa(Gasolina, "fecha", "Gasolina")
Petroleo_completa <- fecha_completa(Petroleo, "fecha", "Petroleo")
Carbon_completa <- fecha_completa(Carbon, "fecha", "Carbon")
GasNatural_completa <- fecha_completa(GasNatural, "fecha", "GasNatural")
IPC_completa <- fecha_completa(IPC, "fecha", "IPC")

1.4

# Unir las bases con formato de columnas separadas por energético
base_unida <- reduce(list(
  Gasolina_completa, Petroleo_completa, Carbon_completa, GasNatural_completa, IPC_completa),
  full_join, 
  by = "fecha") %>%
  arrange(fecha)

1.5

# Crear columna 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, vamos a filtrar
# para tener solo datos desde 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 algun energético
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 de valores faltantes
if (knitr::is_html_output()) {
  
  valores_faltantes %>%
  kable(
    "html", 
    caption = "porcentaje de valores faltantes por columna") %>%
  kable_styling(
    full_width =  FALSE, bootstrap_options = c("striped", "hover", "condensed")
    )
} else {
  
  valores_faltantes %>%
  kable(
    "latex",
    caption = "porcentaje de valores faltantes por columna", 
    booktabs = TRUE
  ) %>%
  kable_styling(
    latex_options = c("striped", "hold_position")
  )
}
porcentaje de valores faltantes por columna
Variable % faltante
Gasolina 2.478118
Petroleo 2.478118
Carbon 2.478118
GasNatural 2.478118
# Agregar valores faltantes con ek promedio mensual por enegético
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 promedio 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 regrouped the output.
## i Summaries were computed grouped by año and mes.
## i Output is grouped by año.
## i Use `summarise(.groups = "drop_last")` to silence this message.
## i Use `summarise(.by = c(año, mes))` for per-operation grouping
##   (`?dplyr::dplyr_by`) instead.

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 sea pendejo, no se encontro 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 la función para convertir a precios reales con base en cualquier año y mes
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 base consolidada
write.csv(basedatos_consolidada, "basedatos_consolidada_transformado.csv", row.names = FALSE)

Ejercicio 2

2.1

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

# Renombrar variables con el sufijo real y nominal
colnames(combustibles) <- colnames(combustibles) %>%
  str_replace("\\d{4}_\\d{2}_transformada", "")

colnames(combustibles) <- ifelse(colnames(combustibles) %in% c("año", "mes"),
                                 colnames(combustibles),
                                 ifelse(str_detect(colnames(combustibles), "_"),
                                        paste0(colnames(combustibles), "real"),
                                        paste0(colnames(combustibles), "_nominal")))

# Base de datos de estadisticas 
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),
    "Minimo" = ~round(min(., na.rm = TRUE), 2),
    "Maximo" = ~round(max(., na.rm = TRUE), 2),
    "Desviacion Estandar" = ~round(sd(., na.rm = TRUE), 2)
    ), .names = "{.col}, {.fn}"))
    
    
# Formato para Tabla
estadisticas_combustibles <- estadisticas_combustibles %>%
  pivot_longer(cols = everything(), names_to = c("Variable", "Estadistica"), names_sep = "_") %>%
  pivot_wider(names_from = Estadistica, values_from = value)

# Tabla
estadisticas_combustibles %>%
  kable("html", caption = "<b>Estadisticas Descriptivas de los Precios de los Combustibles<b>", escape = FALSE) %>%
  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 ="#E0EEEE") %>%
  scroll_box(height ="500px")
Estadisticas Descriptivas de los Precios de los Combustibles
Variable nominal, Observaciones nominal, Promedio nominal, Minimo nominal, Maximo nominal, Desviacion Estandar real, Observaciones real, Promedio real, Minimo real, Maximo real, Desviacion Estandar
Gasolina 289 109.17 61.65 166.10 25.77 289 193.81 150.71 238.32 14.19
Petroleo 289 108.08 91.25 129.80 7.98 289 202.28 104.86 327.85 49.29
Carbon 289 96.98 74.21 123.16 12.68 289 178.23 100.96 270.05 32.82
GasNatural 289 118.27 98.65 137.71 8.37 289 221.86 97.82 366.96 55.75

2.2

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

# Crear el gráfico de dispersión con línea de ajuste
ggplot(base_filtrada, aes(x = Carbon_real, y = Gasolina_real)) +
  geom_point(color = "blue", alpha = 0.6, size = 3) +  # Puntos en color azul
  geom_smooth(method = "lm", color = "red", se = FALSE) +  # Línea de ajuste en rojo
  labs(
    title = "Relación entre el Precio del Carbón y la Gasolina (Reales) en 2023",
    x = "Precio del Carbón Real",
    y = "Precio de la Gasolina Real",
    caption = "Fuente: Datos de combustibles"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),  # Centrar título
    axis.title = element_text(face = "bold")
  )
## `geom_smooth()` using formula = 'y ~ x'

2.3

# Convertir el mes en formato de fecha (para que ggplot lo maneje bien en la serie de tiempo)
# Aquí es mejor dejar solo el mes, dado que es un solo año
base_filtrada <- base_filtrada %>%
#  mutate(Fecha = as.yearmon(paste(año, mes), "%m"))
  mutate(Fecha = factor(month.abb[mes], levels = month.abb, ordered = TRUE))

# Transformar los datos a formato largo, para graficar las series de tiempo
base_garfica_ts <- base_filtrada %>%
  pivot_longer(cols = c(Carbon_real, GasNatural_real, Petroleo_real, Gasolina_real), 
               names_to = "Combustible", values_to = "Precio")

# Crear la gráfica de las series de tiempo
ggplot(base_garfica_ts, aes(x = Fecha, y = Precio, color = Combustible, group = Combustible)) +
  geom_line(size = 1) +  # Línea de serie de tiempo
  geom_point(size = 2) +  # Puntos para resaltar valores individuales
  labs(
    title = "Evolución del Precio Real de los Combustibles en 2023",
    x = "Mes",
    y = "Precio Real",
    color = "Combustible",
    caption = "Fuente: Datos de combustibles"
  )
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## i Please use `linewidth` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.