Cargar datos

dir_base <- "C:/Users/s05e04/Downloads/Taller 1610" 

# Crear rutas completas automáticamente
file_carbon <- file.path(dir_base, "clean_precios_carbon.csv")
file_gas_natural <- file.path(dir_base, "clean_precios_gas_natural.csv")
file_gasolina <- file.path(dir_base, "clean_precios_gasolina.csv")
file_petroleo <- file.path(dir_base, "clean_precios_petroleo.csv")
file_ipc <- file.path(dir_base, "IPC.csv")

# Cargar archivos
library(readr)
carbon_raw <- read_csv(file_carbon)
## Rows: 8579 Columns: 2
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl  (1): precio_carbon
## date (1): fecha
## 
## ℹ 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.
gas_natural_raw <- read_csv(file_gas_natural)
## Rows: 8579 Columns: 2
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl  (1): precio_gas_natural
## date (1): fecha
## 
## ℹ 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.
gasolina_raw <- read_csv(file_gasolina)
## Rows: 8579 Columns: 2
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl  (1): precio_gasolina
## date (1): fecha
## 
## ℹ 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.
petroleo_raw <- read_csv(file_petroleo)
## Rows: 8579 Columns: 2
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl  (1): precio_petroleo
## date (1): fecha
## 
## ℹ 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.
ipc <- read_csv(file_ipc)
## Rows: 847 Columns: 2
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl  (1): ipc
## date (1): fecha
## 
## ℹ 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.

Leer archivos CSV

carbon_raw <- read_csv(file_carbon, show_col_types = FALSE)
gas_natural_raw <- read_csv(file_gas_natural, show_col_types = FALSE)
gasolina_raw <- read_csv(file_gasolina, show_col_types = FALSE)
petroleo_raw <- read_csv(file_petroleo, show_col_types = FALSE)
ipc_raw <- read_csv(file_ipc, show_col_types = FALSE)

Mostrar primeras filas para inspección

list(carbon = head(carbon_raw), gas_natural = head(gas_natural_raw), gasolina = head(gasolina_raw), petroleo = head(petroleo_raw), ipc = head(ipc_raw))
## $carbon
## # A tibble: 6 × 2
##   fecha      precio_carbon
##   <date>             <dbl>
## 1 2000-01-01          56.8
## 2 2000-01-02          84.1
## 3 2000-01-03          70.7
## 4 2000-01-05          79.7
## 5 2000-01-06          91.5
## 6 2000-01-07          69.8
## 
## $gas_natural
## # A tibble: 6 × 2
##   fecha      precio_gas_natural
##   <date>                  <dbl>
## 1 2000-01-01              134. 
## 2 2000-01-02              103. 
## 3 2000-01-03               72.7
## 4 2000-01-04              102. 
## 5 2000-01-05              134. 
## 6 2000-01-06               78.6
## 
## $gasolina
## # A tibble: 6 × 2
##   fecha      precio_gasolina
##   <date>               <dbl>
## 1 2000-01-01            85.2
## 2 2000-01-02            58.8
## 3 2000-01-03            62.4
## 4 2000-01-04            48.6
## 5 2000-01-05            43.8
## 6 2000-01-06            41.9
## 
## $petroleo
## # A tibble: 6 × 2
##   fecha      precio_petroleo
##   <date>               <dbl>
## 1 2000-01-01            77.7
## 2 2000-01-02           108. 
## 3 2000-01-03           119. 
## 4 2000-01-04           106. 
## 5 2000-01-05           115. 
## 6 2000-01-06           101. 
## 
## $ipc
## # A tibble: 6 × 2
##   fecha        ipc
##   <date>     <dbl>
## 1 1954-07-31  0.03
## 2 1954-08-31  0.03
## 3 1954-09-30  0.03
## 4 1954-10-31  0.03
## 5 1954-11-30  0.03
## 6 1954-12-31  0.03

1.1 Cálculo del Precio Nominal Promedio Mensual

explore_df <- function(df){
df %>%
summarize(n_obs = n(),
first_date = min(.[[1]], na.rm = TRUE),
last_date = max(.[[1]], na.rm = TRUE),
vars = paste(names(.), collapse = ", "),
types = paste(sapply(., class), collapse = ", "))
}


explore_list <- list(
carbon = explore_df(carbon_raw),
gas_natural = explore_df(gas_natural_raw),
gasolina = explore_df(gasolina_raw),
petroleo = explore_df(petroleo_raw),
ipc = explore_df(ipc_raw)
)


bind_rows(explore_list, .id = "dataset")
## # A tibble: 5 × 6
##   dataset     n_obs first_date last_date  vars                      types       
##   <chr>       <int> <date>     <date>     <chr>                     <chr>       
## 1 carbon       8579 2000-01-01 2024-01-01 fecha, precio_carbon      Date, numer…
## 2 gas_natural  8579 2000-01-01 2024-01-01 fecha, precio_gas_natural Date, numer…
## 3 gasolina     8579 2000-01-01 2024-01-01 fecha, precio_gasolina    Date, numer…
## 4 petroleo     8579 2000-01-01 2024-01-01 fecha, precio_petroleo    Date, numer…
## 5 ipc           847 1954-07-31 2025-01-31 fecha, ipc                Date, numer…

Interpetación:

Sobre las variables que vamos a usar para el ejercicio podemos observar que las bases de carbón, gas natural, gasolina y petroleo tienen el mismo número de observaciones (8579), también tienen la misma fecha inicial y final (01/01/2000 al 01/01/2024 respectivamente). y por último, tienen las mismas variables que son la fecha y el precio de cada uno de ellos. Por otro lado, la base de datos ipc tiene 847 observaciones en total, además las fechas también son diferentes, van desde el 31/07/1954 hasta 31/01/2025, y sus variables son fecha e ipc. Lo que si es igual en todas las bases es el tipo de datos, en donde tenemos datos en formato fecha y los demás son numéricos.

1.2 y 1.3 Deflactación del Precio Nominal para Obtener el Precio Real

fill_dates <- function(df, date_col = NULL, price_col = NULL){
if(is.null(date_col)) date_col <- names(df)[1]
if(is.null(price_col)) price_col <- names(df)[2]


df2 <- df %>%
rename(.date = all_of(date_col), .price = all_of(price_col)) %>%
mutate(.date = as_date(.date))

full_dates <- tibble(.date = seq.Date(min(df2$.date, na.rm=TRUE), max(df2$.date, na.rm=TRUE), by = "day"))
out <- full_dates %>% left_join(df2, by = ".date")

out <- out %>% rename(!!date_col := .date, !!price_col := .price)
return(out)
}

carbon <- fill_dates(carbon_raw)
gas_natural <- fill_dates(gas_natural_raw)
gasolina <- fill_dates(gasolina_raw)
petroleo <- fill_dates(petroleo_raw)

ipc <- ipc_raw %>%
rename_with(~tolower(.))

possible_date_ipc <- names(ipc)[sapply(ipc, function(x) any(grepl("\\d{4}-\\d{2}|/", as.character(x))))][1]

if (!is.null(possible_date_ipc)) {
  ipc <- ipc %>%
    rename(.date = all_of(possible_date_ipc)) %>%
    mutate(.date = as_date(.date))
  names(ipc)[names(ipc) == '.date'] <- possible_date_ipc
}

tibble(dataset = c('carbon','gas_natural','gasolina','petroleo'),
n_obs = c(nrow(carbon), nrow(gas_natural), nrow(gasolina), nrow(petroleo)),
start = c(min(carbon[[1]], na.rm=TRUE), min(gas_natural[[1]], na.rm=TRUE), min(gasolina[[1]], na.rm=TRUE), min(petroleo[[1]], na.rm=TRUE)),
end = c(max(carbon[[1]], na.rm=TRUE), max(gas_natural[[1]], na.rm=TRUE), max(gasolina[[1]], na.rm=TRUE), max(petroleo[[1]], na.rm=TRUE)))
## # A tibble: 4 × 4
##   dataset     n_obs start      end       
##   <chr>       <int> <date>     <date>    
## 1 carbon       8767 2000-01-01 2024-01-01
## 2 gas_natural  8767 2000-01-01 2024-01-01
## 3 gasolina     8767 2000-01-01 2024-01-01
## 4 petroleo     8767 2000-01-01 2024-01-01

1.4 Unión de las series diarias en una base consolidada

rename_to_standard <- function(df, new_price_name){
df %>% rename(date = 1, !!new_price_name := 2)
}

carbon_s <- rename_to_standard(carbon, "precio_carbon")
gas_natural_s <- rename_to_standard(gas_natural, "precio_gas_natural")
gasolina_s <- rename_to_standard(gasolina, "precio_gasolina")
petroleo_s <- rename_to_standard(petroleo, "precio_petroleo")

daily_all <- carbon_s %>%
full_join(gas_natural_s, by = "date") %>%
full_join(gasolina_s, by = "date") %>%
full_join(petroleo_s, by = "date") %>%
arrange(date)

glimpse(daily_all)
## Rows: 8,767
## Columns: 5
## $ date               <date> 2000-01-01, 2000-01-02, 2000-01-03, 2000-01-04, 20…
## $ precio_carbon      <dbl> 56.80856, 84.06858, 70.66739, NA, 79.72284, 91.5099…
## $ precio_gas_natural <dbl> 134.10288, 102.80182, 72.73675, 101.51064, 133.7802…
## $ precio_gasolina    <dbl> 85.22463, 58.80204, 62.35808, 48.59105, 43.80961, 4…
## $ precio_petroleo    <dbl> 77.70500, 108.36269, 118.78963, 105.69747, 115.3072…

1.5 Creación de columnas de año y mes

daily_all <- daily_all %>%
mutate(year = year(date), month = month(date), ym = as.yearmon(date))

head(daily_all)
## # A tibble: 6 × 8
##   date       precio_carbon precio_gas_natural precio_gasolina precio_petroleo
##   <date>             <dbl>              <dbl>           <dbl>           <dbl>
## 1 2000-01-01          56.8              134.             85.2            77.7
## 2 2000-01-02          84.1              103.             58.8           108. 
## 3 2000-01-03          70.7               72.7            62.4           119. 
## 4 2000-01-04          NA                102.             48.6           106. 
## 5 2000-01-05          79.7              134.             43.8           115. 
## 6 2000-01-06          91.5               78.6            41.9           101. 
## # ℹ 3 more variables: year <dbl>, month <dbl>, ym <yearmon>

1.6 Detección de valores faltantes y sustitución por promedio mes-año

na_summary <- daily_all %>%
summarize(across(starts_with("precio"), ~mean(is.na(.))*100)) %>%
pivot_longer(everything(), names_to = "variable", values_to = "pct_na")
na_summary
## # A tibble: 4 × 2
##   variable           pct_na
##   <chr>               <dbl>
## 1 precio_carbon        2.14
## 2 precio_gas_natural   2.14
## 3 precio_gasolina      2.14
## 4 precio_petroleo      2.14
monthly_means <- daily_all %>%
group_by(year, month) %>%
summarize(across(starts_with("precio"), ~mean(., na.rm = TRUE)), .groups = "drop")

daily_all <- daily_all %>%
  left_join(monthly_means, by = c("year","month"), suffix = c("", "_monthly_mean")) %>%
  mutate(
    precio_carbon   = coalesce(precio_carbon, precio_carbon_monthly_mean),
    precio_gas_natural = coalesce(precio_gas_natural, precio_gas_natural_monthly_mean),
    precio_gasolina = coalesce(precio_gasolina, precio_gasolina_monthly_mean),
    precio_petroleo = coalesce(precio_petroleo, precio_petroleo_monthly_mean)
  ) %>%
  select(-ends_with("_monthly_mean"))
  
daily_all %>%
  summarise(across(starts_with("precio"), ~sum(is.na(.))))
## # A tibble: 1 × 4
##   precio_carbon precio_gas_natural precio_gasolina precio_petroleo
##           <int>              <int>           <int>           <int>
## 1             0                  0               0               0

1.7 Agregado a promedios mensuales y filtrado

monthly_all <- daily_all %>%
  mutate(date = as.Date(as.yearmon(paste(year, month, sep = "-")))) %>%
  group_by(year, month, date) %>%
  summarise(across(starts_with("precio"), ~mean(., na.rm = TRUE)), .groups = "drop") %>%
  arrange(date)

monthly_all_filtered <- monthly_all %>% filter(date >= as.Date("2000-01-01") & date <= as.Date("2024-01-31"))

nrow(monthly_all_filtered)
## [1] 289
ipc <- ipc_raw %>% rename_with(~str_to_lower(.))

date_col_ipc <- names(ipc)[sapply(ipc, function(x) any(!is.na(as.Date(as.character(x), format = "%Y-%m-%d")), na.rm = TRUE))][1]
if(is.null(date_col_ipc) || is.na(date_col_ipc)){

date_col_ipc <- names(ipc)[grepl("fecha|date|anno|año|ano|mes", names(ipc), ignore.case = TRUE)][1]
}

ipc_value_col <- names(ipc)[sapply(ipc, is.numeric)][1]

ipc2 <- ipc %>%
mutate(across(all_of(date_col_ipc), ~ as_date(.))) %>%
rename(ipc_date = all_of(date_col_ipc), ipc = all_of(ipc_value_col)) %>%
mutate(year = year(ipc_date), month = month(ipc_date)) %>%
select(year, month, ipc)

head(ipc2)
## # A tibble: 6 × 3
##    year month   ipc
##   <dbl> <dbl> <dbl>
## 1  1954     7  0.03
## 2  1954     8  0.03
## 3  1954     9  0.03
## 4  1954    10  0.03
## 5  1954    11  0.03
## 6  1954    12  0.03
monthly_all_ipc <- monthly_all_filtered %>% left_join(ipc2, by = c("year","month"))

sum(is.na(monthly_all_ipc$ipc))
## [1] 0

1.8 Función para transformar precios nominales a precios reales

transform_to_real <- function(df_monthly, price_col, year_base, month_base, ipc_col = "ipc"){

base_ipc <- df_monthly %>% filter(year == year_base, month == month_base) %>% pull(!!sym(ipc_col))
if(length(base_ipc) == 0 || is.na(base_ipc)) stop("IPC base no encontrado para el año-mes base especificado")

new_name <- paste0(price_col, "_real_base_", year_base, sprintf("_%02d", month_base))

df_monthly %>% mutate(!!new_name := (!!sym(price_col)) * (base_ipc / (!!sym(ipc_col))))
}

year_base_example <- 2023
month_base_example <- 12

monthly_real <- monthly_all_ipc
for(col in names(monthly_real)[grepl("^precio", names(monthly_real))]){
monthly_real <- transform_to_real(monthly_real, col, year_base_example, month_base_example, ipc_col = "ipc")
}

head(monthly_real)
## # A tibble: 6 × 12
##    year month date       precio_carbon precio_gas_natural precio_gasolina
##   <dbl> <dbl> <date>             <dbl>              <dbl>           <dbl>
## 1  2000     1 2000-01-01          77.1               101.            61.6
## 2  2000     2 2000-02-01          80.8               104.            71.3
## 3  2000     3 2000-03-01          76.2               112.            66.9
## 4  2000     4 2000-04-01          74.7               106.            64.7
## 5  2000     5 2000-05-01          77.6               111.            65.2
## 6  2000     6 2000-06-01          78.3               107.            66.2
## # ℹ 6 more variables: precio_petroleo <dbl>, ipc <dbl>,
## #   precio_carbon_real_base_2023_12 <dbl>,
## #   precio_gas_natural_real_base_2023_12 <dbl>,
## #   precio_gasolina_real_base_2023_12 <dbl>,
## #   precio_petroleo_real_base_2023_12 <dbl>

1.9 Aplicación de la función de deflactación a todos los bienes

monthly_real_alt <- monthly_all_ipc
for(col in names(monthly_real_alt)[grepl("^precio", names(monthly_real_alt))]){
monthly_real_alt <- transform_to_real(monthly_real_alt, col, 2023, 12, ipc_col = "ipc")
}

real_cols_2015 <- names(monthly_real)[grepl("_real_base_2015_01", names(monthly_real))]
real_cols_2023 <- names(monthly_real_alt)[grepl("_real_base_2023_12", names(monthly_real_alt))]

if(length(real_cols_2015) > 0 && length(real_cols_2023) > 0){

b1_2015 <- monthly_real[[real_cols_2015[1]]]
b1_2023 <- monthly_real_alt[[real_cols_2023[1]]]
tibble(mean_ratio = mean(b1_2015 / b1_2023, na.rm = TRUE))
} else {
tibble(info = "No se encontraron columnas reales con los sufijos esperados")
}
## # A tibble: 1 × 1
##   info                                                       
##   <chr>                                                      
## 1 No se encontraron columnas reales con los sufijos esperados

1.10 Exportación de la base consolidada a CSV

output_file <- file.path(dir_base, "consolidado_ejercicio_1610.csv")
write_csv(monthly_real, output_file)

2.1 Visualización de la serie de tiempo de precios reales

library(dplyr)
library(tidyr)
library(stringr)

stats_table <- function(data, cols) {
  data %>%
    select(all_of(cols)) %>%
    pivot_longer(everything(), names_to = "variable", values_to = "valor") %>%
    separate(variable, into = c("tipo", "combustible"), sep = "_", extra = "merge") %>%
    group_by(combustible) %>%
    summarise(
      n_obs = sum(!is.na(valor)),
      media = mean(valor, na.rm = TRUE),
      minimo = min(valor, na.rm = TRUE),
      maximo = max(valor, na.rm = TRUE),
      desv_est = sd(valor, na.rm = TRUE),
      .groups = "drop"
    ) %>%
    arrange(combustible)
}

nominal_cols <- c("precio_carbon", "precio_gas_natural", "precio_gasolina", "precio_petroleo")

real_cols <- c("precio_carbon_real_base_2023_12",
               "precio_gas_natural_real_base_2023_12",
               "precio_gasolina_real_base_2023_12",
               "precio_petroleo_real_base_2023_12")

stats_nominal <- stats_table(monthly_real, nominal_cols)
stats_real <- stats_table(monthly_real, real_cols)

stats_nominal <- stats_nominal %>% mutate(tipo = "Nominal")
stats_real <- stats_real %>% mutate(tipo = "Real")

tabla_final <- bind_rows(stats_nominal, stats_real) %>%
  relocate(tipo, .before = combustible)


print(tabla_final)
## # A tibble: 8 × 7
##   tipo    combustible                   n_obs media minimo maximo desv_est
##   <chr>   <chr>                         <int> <dbl>  <dbl>  <dbl>    <dbl>
## 1 Nominal carbon                          289  97.0   74.2   123.    12.7 
## 2 Nominal gas_natural                     289 118.    98.6   138.     8.37
## 3 Nominal gasolina                        289 109.    61.6   166.    25.8 
## 4 Nominal petroleo                        289 108.    91.2   130.     7.98
## 5 Real    carbon_real_base_2023_12        289 178.   101.    270.    32.8 
## 6 Real    gas_natural_real_base_2023_12   289 222.    97.8   367.    55.8 
## 7 Real    gasolina_real_base_2023_12      289 194.   151.    238.    14.2 
## 8 Real    petroleo_real_base_2023_12      289 202.   105.    328.    49.3

Interpretación:

En promedio, el gas natural presenta los precios más altos tanto en valores nominales (118,27) como reales (221,86), mientras que el carbón muestra los más bajos. Los precios reales son mayores que los nominales, lo que refleja el efecto de la inflación al expresarlos en términos del poder adquisitivo de diciembre de 2023. Además, los combustibles más volátiles son el gas natural y el petróleo, mostrando sus mayores desviaciones estándar, lo que indica una mayor variación en sus precios a lo largo del tiempo.

2.2 Interpretación de la serie de tiempo

Sys.setlocale("LC_ALL", "es_ES.UTF-8")
## [1] "LC_COLLATE=es_ES.UTF-8;LC_CTYPE=es_ES.UTF-8;LC_MONETARY=es_ES.UTF-8;LC_NUMERIC=C;LC_TIME=es_ES.UTF-8"
plot_year <- 2023

carbon_real_col <- names(monthly_real)[grepl("precio_carbon_real_base_2023_12", names(monthly_real))][1]
gasolina_real_col <- names(monthly_real)[grepl("precio_gasolina_real_base_2023_12", names(monthly_real))][1]

plot_df <- monthly_real %>%
  filter(year == plot_year) %>%
  select(all_of(c(carbon_real_col, gasolina_real_col))) %>%
  drop_na()

plot_df2 <- plot_df %>%
  select(1:2) %>%
  rename(x = 1, y = 2) %>%
  mutate(
    x = as.numeric(as.character(x)),
    y = as.numeric(as.character(y))
  )

if (nrow(plot_df2) > 0) {
  ggplot(plot_df2, aes(x = x, y = y)) +
    geom_point(color = "blue") +
    geom_smooth(method = "lm", se = TRUE, color = "purple", linewidth = 1.3) +
    labs(
      title = paste("Relacion entre precios reales de Carbon y Gasolina -", plot_year, "(base dic 2023)"),
      x = "Precio real del Carbon (base dic 2023)",
      y = "Precio real de la Gasolina (base dic 2023)"
    ) +
    theme_minimal()
} else {
  message(paste("No hay datos disponibles para el anio", plot_year, "con ambas series reales base dic 2023"))
}
## `geom_smooth()` using formula = 'y ~ x'

Interpretación:

Se observa una tendencia ligeramente positiva, representada por la línea de ajuste lineal en color púrpura, lo que indica que a medida que el precio real del carbón aumenta, el precio real de la gasolina tiende también a incrementarse, aunque de forma moderada. Sin embargo, los puntos están algo dispersos alrededor de la línea, lo que sugiere que la correlación entre ambos precios es débil. La gráfica refleja que los movimientos en los precios del carbón no explican completamente las variaciones en los precios de la gasolina durante el año base.

2.3

real_cols_2023 <- c("precio_carbon_real_base_2023_12",
                    "precio_gas_natural_real_base_2023_12",
                    "precio_gasolina_real_base_2023_12",
                    "precio_petroleo_real_base_2023_12")

plot_year <- 2023

ts_df <- monthly_real_alt %>%
  filter(year == plot_year) %>%
  select(date, all_of(real_cols_2023)) %>%
  pivot_longer(
    cols = starts_with("precio_"),
    names_to = "combustible",
    values_to = "precio_real"
  ) %>%
  mutate(
    combustible = gsub("precio_|_real_base_2023_12", "", combustible)
  )

library(ggplot2)

ggplot(ts_df, aes(x = date, y = precio_real, color = combustible)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  labs(
    title = paste("Serie de tiempo del precio real por combustible (base dic 2023) -", plot_year),
    x = "Mes",
    y = "Precio real (base dic 2023)",
    color = "Combustible"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", size = 14),
    axis.text.x = element_text(angle = 45, hjust = 1)
  )
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Interpretación:

Se observa que el petróleo presenta los valores más altos durante todo el año, manteniéndose relativamente estable con ligeras fluctuaciones. El gas natural sigue una tendencia intermedia, con variaciones más marcadas a lo largo de los meses, mientras que la gasolina muestra una disminución progresiva hacia finales del año. En conjunto, la gráfica permite identificar que, aunque los precios reales de los combustibles varían mes a mes, existe una diferencia constante en los niveles de precio entre ellos, siendo el petróleo el de mayor valor y el carbón el de menor.