setwd("C:/Users/s05e17/Downloads")
file_carbon <- "clean_precios_carbon.csv"
file_gas_natural <- "clean_precios_gas_natural.csv"
file_gasolina <- "clean_precios_gasolina.csv"
file_petroleo <- "clean_precios_petroleo.csv"
file_ipc <- "IPC.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)
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 Exploración inicial
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…
En relación con las variables que utilizaremosara el ejercicio, se observa que las bases correspondientes a carbón, gas natural, gasolina y petróleo cuentan con el mismo número de registros (8579), comparten el mismo rango temporal —desde el 1 de enero de 2000 hasta el 1 de enero de 2024— y presentan las mismas variables: fecha y precio de cada producto. Por otro lado, la base de datos del IPC contiene 847 observaciones, con un rango de fechas diferente, que abarca desde el 31 de julio de 1954 hasta el 31 de enero de 2025. Sus variables son fecha e ipc. Finalmente, todas las bases comparten el mismo tipo de datos: una variable en formato fecha y las demás de tipo numérico.
# Función que recibe dataframe, nombre columna fecha y precio
fill_dates <- function(df, date_col = NULL, price_col = NULL){
# Acepta dataframes donde la primera columna es fecha si no se especifica
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")
# Renombrar de vuelta a original
out <- out %>% rename(!!date_col := .date, !!price_col := .price)
return(out)
}
# Aplicar a cada dataset (ajustar nombres de columnas si es necesario)
carbon <- fill_dates(carbon_raw)
gas_natural <- fill_dates(gas_natural_raw)
gasolina <- fill_dates(gasolina_raw)
petroleo <- fill_dates(petroleo_raw)
# Asegurar que IPC tenga fecha tipo Date. Intentamos detectar columna fecha.
ipc <- ipc_raw %>%
rename_with(~tolower(.))
# intentar detectar columna fecha en IPC
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
}
# Mostrar rangos después de completar
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
# Normalizar nombres: asumimos columnas [fecha, precio]
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")
# Hacer full join por date
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)
# Inspección
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…
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>
# Porcentaje de NA por columna
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
# Sustituir NAs por promedio del mes-año (group_by year, month)
monthly_means <- daily_all %>%
group_by(year, month) %>%
summarize(across(starts_with("precio"), ~mean(., na.rm = TRUE)), .groups = "drop")
# Unir los promedios y rellenar NAs
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"))
# Verificar que no queden NAs en precios (salvo IPC o filas fuera de rango)
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
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)
# Filtrar periodo entre 2000-01 y 2024-01 inclusive
monthly_all_filtered <- monthly_all %>% filter(date >= as.Date("2000-01-01") & date <= as.Date("2024-01-31"))
nrow(monthly_all_filtered)
## [1] 289
# Preparar IPC: convertir a year-month y unir con monthly_all_filtered
# Intentaremos detectar nombre de la columna con índice y fecha
# Asumimos que ipc_raw tiene una columna de fecha y otra con el índice (llamada IPC o similar)
ipc <- ipc_raw %>% rename_with(~str_to_lower(.))
# buscar columna fecha y columna indice
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)){
# buscar columna que contenga la palabra 'date' o 'fecha' o parezca año
date_col_ipc <- names(ipc)[grepl("fecha|date|anno|año|ano|mes", names(ipc), ignore.case = TRUE)][1]
}
# Elegir columna IPC (cualquier columna numérica)
ipc_value_col <- names(ipc)[sapply(ipc, is.numeric)][1]
# Crear columnas year & month en ipc
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
# Unir
monthly_all_ipc <- monthly_all_filtered %>% left_join(ipc2, by = c("year","month"))
# Verificar NAs en ipc
sum(is.na(monthly_all_ipc$ipc))
## [1] 0
# precio_nominal: vector numérico
# year_base, month_base: integers
# ipc_col: name of ipc column in monthly data (numeric)
transform_to_real <- function(df_monthly, price_col, year_base, month_base, ipc_col = "ipc"){
# Build base ipc value
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 column name
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))))
}
# Ejemplo de aplicación para todos los bienes con base en Enero 2015 (por ejemplo)
year_base_example <- 2015
month_base_example <- 1
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")
}
# Ver primeras filas
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_2015_01 <dbl>,
## # precio_gas_natural_real_base_2015_01 <dbl>,
## # precio_gasolina_real_base_2015_01 <dbl>,
## # precio_petroleo_real_base_2015_01 <dbl>
# Crear la misma transformación con otra base, p.ej. 2023-12
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")
}
# Comprobar relación entre columnas reales con distintas bases (deberían ser escala multiplicativa entre sí)
# Tomar un bien p.ej precio_petroleo_real_base_2015_01 y precio_petroleo_real_base_2023_12 si existen
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))]
# Mostrar razón promedio entre las series reales según base (para un bien arbitrario si existe)
if(length(real_cols_2015) > 0 && length(real_cols_2023) > 0){
# elegir primer bien
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
## mean_ratio
## <dbl>
## 1 0.603
write_csv(monthly_real, "consolidado_ejercicio_1610.csv")
library(dplyr)
library(tidyr)
library(stringr)
# Función para generar tabla de estadísticas descriptivas
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_2015_01",
"precio_gas_natural_real_base_2015_01",
"precio_gasolina_real_base_2015_01",
"precio_petroleo_real_base_2015_01")
stats_nominal <- stats_table(monthly_real, nominal_cols)
stats_real <- stats_table(monthly_real, real_cols)
stats_nominal
## # A tibble: 4 × 6
## combustible n_obs media minimo maximo desv_est
## <chr> <int> <dbl> <dbl> <dbl> <dbl>
## 1 carbon 289 97.0 74.2 123. 12.7
## 2 gas_natural 289 118. 98.6 138. 8.37
## 3 gasolina 289 109. 61.6 166. 25.8
## 4 petroleo 289 108. 91.2 130. 7.98
stats_real
## # A tibble: 4 × 6
## combustible n_obs media minimo maximo desv_est
## <chr> <int> <dbl> <dbl> <dbl> <dbl>
## 1 carbon_real_base_2015_01 289 107. 60.8 163. 19.8
## 2 gas_natural_real_base_2015_01 289 134. 59.0 221. 33.6
## 3 gasolina_real_base_2015_01 289 117. 90.8 144. 8.55
## 4 petroleo_real_base_2015_01 289 122. 63.2 198. 29.7
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)
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_2015_01 289 107. 60.8 163. 19.8
## 6 Real gas_natural_real_base_2015_01 289 134. 59.0 221. 33.6
## 7 Real gasolina_real_base_2015_01 289 117. 90.8 144. 8.55
## 8 Real petroleo_real_base_2015_01 289 122. 63.2 198. 29.7
# --- Gráfico de dispersión de precios reales de carbón vs gasolina ---
# Año que deseas graficar
plot_year <- 2023
# Encontrar los nombres de las columnas de precios reales
carbon_real_col <- names(monthly_real_alt)[grepl("precio_carbon.*_real_base_", names(monthly_real_alt))][1]
gasolina_real_col <- names(monthly_real_alt)[grepl("precio_gasolina.*_real_base_", names(monthly_real_alt))][1]
# Filtrar los datos del año seleccionado
plot_df <- monthly_real_alt %>%
filter(year == plot_year) %>%
select(all_of(c(carbon_real_col, gasolina_real_col))) %>%
drop_na()
# Cargar la librería ggplot2
library(ggplot2)
if (!exists("plot_df")) stop("plot_df no existe. Ejecuta el bloque que crea plot_df antes.")
plot_df2 <- plot_df %>%
select(1:2) %>%
rename(x = 1, y = 2)
plot_df2 <- plot_df2 %>%
mutate(
x = as.numeric(as.character(x)),
y = as.numeric(as.character(y))
)
cat("nrow(plot_df2) =", nrow(plot_df2), " ---- clases: x =", class(plot_df2$x), " y =", class(plot_df2$y), "\n")
## nrow(plot_df2) = 12 ---- clases: x = numeric y = numeric
p <- ggplot(plot_df2, aes(x = x, y = y)) +
geom_point(color = "blue") +
geom_smooth(method = "lm", se = TRUE, color = "gold") +
labs(
title = paste("Relacion entre precios reales de carbon y gasolina -", plot_year),
x = "Precio real carbon",
y = "Precio real gasolina"
) +
theme_minimal()
print(p)
## `geom_smooth()` using formula = 'y ~ x'
if (!exists(“plot_df2”)) stop(“Debes ejecutar el bloque 2.2 antes de correr el 2.3”)
modelo_23 <- lm(y ~ x, data = plot_df2)
summary(modelo_23)
library(broom) library(kableExtra)
coeficientes_23 <- tidy(modelo_23)
coeficientes_23 %>% kable(format = “html”, digits = 5, caption = “Coeficientes del modelo lineal (Precio real gasolina ~ Precio real carbón)”) %>% kable_styling(full_width = FALSE, bootstrap_options = c(“striped”, “hover”, “condensed”))
r2 <- summary(modelo_23)\(r.squared p_value <- coeficientes_23\)p.value[2] pendiente <- coeficientes_23$estimate[2]
cat(“*Interpretación:**“) cat(”La pendiente estimada es de”, round(pendiente, 5), “, lo que indica que por cada unidad que aumenta el precio real del carbón,”, “el precio real de la gasolina cambia en promedio en esa magnitud.”) cat(“El coeficiente de determinación R² es de”, round(r2, 3), “, lo que indica que el modelo explica aproximadamente el”, round(r2 * 100, 1), “% de la variabilidad del precio real de la gasolina.”) cat(“El valor-p asociado a la pendiente es de”, signif(p_value, 4), ifelse(p_value < 0.05, “, por lo tanto existe una relación estadísticamente significativa entre ambas variables.”, “, lo que sugiere que la relación no es significativa a un nivel del 5%.”), “”)
p + geom_smooth(method = “lm”, se = TRUE, color = “red”) + labs( title = paste(“Relación y regresión entre precios reales de carbón y gasolina -”, plot_year), subtitle = paste(“Pendiente:”, round(pendiente, 4), ” | R²:“, round(r2, 3)) )