Ejercicio 1

1.1

La base de datos utilizada en el ejercicio coreesponde a precios de energeticos y a una serie del indice de precios al consumidor (IPC)

Carbon: La base de datos de carbón tiene 8.579 observaciones y 2 variables: fecha y precio del carbón. Permite ver cómo ha cambiado su precio entre 2000 y 2024.

Gas Natural: La base de datos de gas natural tiene 8.579 observaciones y 2 variables: fecha y precio del gas natural. Muestra la evolución diaria de su precio entre 2000 y 2024.

Gaolina: La base de datos de gasolina tiene 8.579 observaciones y 2 variables: fecha y precio de la gasolina. Permite analizar sus variaciones de precio entre 2000 y 2024.

IPC: La base de datos del IPC tiene 847 observaciones y 2 variables. Contiene información sobre la inflación en Colombia desde 1954 hasta 2025.

Petroleo: La base de datos de petróleo tiene 8.579 observaciones y 2 variables: fecha y precio del petróleo Brent. Permite estudiar el comportamiento de su precio entre 2000 y 2024. ## 1.1

setwd("C:/Users/s12e09/Desktop/ESCRITORIO DE TRABAJO")
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

#Funcion 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)
}
  • Aqui usamos la funcion para completar las fechas faltantes

1.3

#se aplica la funcion 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")
  • Aplicamos funcion del 1.2

1.4

#unir bases con formato de columna separadas por combustible
base_unida <- reduce(list(gasolina_completa, petroleo_completa, carbon_completa, gasnatural_completa, ipc_completa), full_join, by = "fecha") %>%
  arrange (fecha)
  • En este apartado unimos las bases completas, ya que antes las bases completas estaban separadas, ahora las listamos con formato de columna separadas por combustible todas.

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, vamos a filtrar
# para tener solo datos desde enero del 2000 hasta enero de 2024
base_unida <- base_unida %>%
  filter(año >= 2000 & (año < 2024 | (año == 2024 & mes == 1)))
  • Aqui creamos columnas que corresponden a los meses y años de las observaciones, ahora se ve un poco mas organizada, ademas como la ipc tiene datos desde 1954 filtramos para que quedaran datos solo desde enero del 2000 hasta enero de 2024.

1.6

# Identificar valores faltantes en el precio de algun energetico
valores_faltantes <- base_unida %>%
  summarize(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
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 el promedio mensual energetico
base_unida <- base_unida %>%
  group_by(año, mes) %>%
  mutate(across(where(is.numeric), ~ifelse(is.na(.), mean(., na.rm = TRUE), .))) %>%
  ungroup()

1.7

# Agregat informacion 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 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

# Funcion 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 valido 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)
}
  • Creamos una funcion para convertir precios nominales a precios reales

1.9

# Aplicar la funcion para convertir a precios reales con base en cualquier año y mes especificado
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)
  • Aqui aplicamos la funcion que creamos en 1.8 y quedaron todos los precios bien en la base datos consolidada

1.10

# Guardar base consolidada
write.csv(basedatos_consolidada, "basedatos_consolidada_transformados.csv", row.names = FALSE)
  • Creamos un documento y quedo guardado en nuestra carpeta inicial con nombre basedatos_consolidada_transformados

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
  • Ejercicio 2

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 = "green", 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'

  • Aqui en este lo que hicimos fue presentar la grafica de dispersion de puntos con carbon eje x y gasolina eje y, ambos reales

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.