library(readxl)
library(dplyr)
library(gt)
library(plotly)
library(DT)
datos <- read_excel("dataset_mundial_petro.xlsx")
cat("Número de registros:", nrow(datos), "\n")
## Número de registros: 8334
cat("Número de variables:", ncol(datos), "\n")
## Número de variables: 23
Y = PRODUCTION_START_YEAR (efecto) X1 = DISCOVERY_YEAR, X2 = FID_YEAR (causas)
Un yacimiento comienza a producir después de haber sido descubierto (X1) y después de que se tome la Decisión Final de Inversión / FID (X2). Por eso X1 y X2 son las causas, y el año de inicio de producción (Y) es el efecto.
FID Year y Production start year vienen
como texto porque incluyen valores como “2025 (expected)”; se extrae el
año numérico de esos casos.
extraer_anio <- function(v) as.numeric(sub("^(\\d{4}).*", "\\1", as.character(v)))
X1 <- as.numeric(datos$`Discovery year`)
X2 <- extraer_anio(datos$`FID Year`)
Y <- extraer_anio(datos$`Production start year`)
tabla_original <- data.frame(DISCOVERY_YEAR = X1, FID_YEAR = X2, PRODUCTION_START_YEAR = Y)
nrow(tabla_original)
## [1] 8334
datatable(head(tabla_original, 50),
options = list(pageLength = 10),
colnames = c("Año de Descubrimiento (X1)", "Año de FID (X2)", "Año de Inicio de Producción (Y)"))
Se conservan únicamente los registros donde X1, X2 y Y están presentes y son positivos, ya que faltantes o valores inventados distorsionarían la relación real entre las variables.
tabla <- tabla_original %>%
filter(!is.na(DISCOVERY_YEAR), !is.na(FID_YEAR), !is.na(PRODUCTION_START_YEAR)) %>%
filter(DISCOVERY_YEAR > 0, FID_YEAR > 0, PRODUCTION_START_YEAR > 0)
cat("Tripletas completas y válidas:", nrow(tabla), "\n")
## Tripletas completas y válidas: 259
datatable(tabla,
options = list(pageLength = 10),
colnames = c("Año de Descubrimiento (X1)", "Año de FID (X2)", "Año de Inicio de Producción (Y)"))
plot_ly(tabla, x = ~DISCOVERY_YEAR, y = ~FID_YEAR, z = ~PRODUCTION_START_YEAR,
type = "scatter3d", mode = "markers",
marker = list(size = 4, color = "#2E86C1")) %>%
layout(scene = list(
xaxis = list(title = "X1 DISCOVERY_YEAR"),
yaxis = list(title = "X2 FID_YEAR"),
zaxis = list(title = "Y PRODUCTION_START_YEAR")
))
Los puntos se ven creciendo de forma conjunta con X1 y X2, formando una nube más o menos plana (no caótica). Se prueba con regresión lineal múltiple (un plano):
\[y = b_0 + b_1 x_1 + b_2 x_2\]
modelo <- lm(PRODUCTION_START_YEAR ~ DISCOVERY_YEAR + FID_YEAR, data = tabla)
summary(modelo)
##
## Call:
## lm(formula = PRODUCTION_START_YEAR ~ DISCOVERY_YEAR + FID_YEAR,
## data = tabla)
##
## Residuals:
## Min 1Q Median 3Q Max
## -25.9703 -1.5127 0.1503 1.3026 8.2334
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 11.13115 26.98415 0.413 0.680
## DISCOVERY_YEAR -0.01555 0.01302 -1.195 0.233
## FID_YEAR 1.01132 0.01680 60.211 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.885 on 256 degrees of freedom
## Multiple R-squared: 0.9574, Adjusted R-squared: 0.9571
## F-statistic: 2876 on 2 and 256 DF, p-value: < 2.2e-16
b0 <- coef(modelo)[1]
b1 <- coef(modelo)[2]
b2 <- coef(modelo)[3]
data.frame(
Parámetro = c("b0 (intercepto)", "b1 (pendiente X1)", "b2 (pendiente X2)"),
Valor = c(round(b0, 4), round(b1, 4), round(b2, 4))
) %>%
gt() %>%
tab_header(title = md("**Parámetros del Modelo**"))
| Parámetros del Modelo | |
| Parámetro | Valor |
|---|---|
| b0 (intercepto) | 11.1311 |
| b1 (pendiente X1) | -0.0156 |
| b2 (pendiente X2) | 1.0113 |
x1_seq <- seq(min(tabla$DISCOVERY_YEAR), max(tabla$DISCOVERY_YEAR), length.out = 25)
x2_seq <- seq(min(tabla$FID_YEAR), max(tabla$FID_YEAR), length.out = 25)
malla <- outer(x1_seq, x2_seq, function(a, b) b0 + b1 * a + b2 * b)
plot_ly() %>%
add_markers(data = tabla, x = ~DISCOVERY_YEAR, y = ~FID_YEAR, z = ~PRODUCTION_START_YEAR,
marker = list(size = 4, color = "#2E86C1"), name = "Datos reales") %>%
add_surface(x = x1_seq, y = x2_seq, z = t(malla), opacity = 0.6,
showscale = FALSE, name = "Plano ajustado") %>%
layout(scene = list(
xaxis = list(title = "X1 DISCOVERY_YEAR"),
yaxis = list(title = "X2 FID_YEAR"),
zaxis = list(title = "Y PRODUCTION_START_YEAR")
))
Los puntos quedan cerca del plano; se evalúa el ajuste formalmente en la sección siguiente.
pearson_x1 <- cor(tabla$DISCOVERY_YEAR, tabla$PRODUCTION_START_YEAR)
pearson_x2 <- cor(tabla$FID_YEAR, tabla$PRODUCTION_START_YEAR)
f_pvalue <- pf(summary(modelo)$fstatistic[1],
summary(modelo)$fstatistic[2],
summary(modelo)$fstatistic[3], lower.tail = FALSE)
r2 <- summary(modelo)$r.squared
data.frame(
Test = c("Pearson X1 (DISCOVERY_YEAR)", "Pearson X2 (FID_YEAR)", "F-test modelo"),
Valor = c(round(pearson_x1, 4), round(pearson_x2, 4), format(f_pvalue, scientific = TRUE, digits = 4)),
Resultado = c(ifelse(abs(pearson_x1) > 0.7, "Aceptado", "No supera 0.7"),
ifelse(abs(pearson_x2) > 0.7, "Aceptado", "No supera 0.7"),
ifelse(f_pvalue < 0.05, "Significativo", "No significativo"))
) %>%
gt() %>%
tab_header(title = md("**Resumen del Test**"))
| Resumen del Test | ||
| Test | Valor | Resultado |
|---|---|---|
| Pearson X1 (DISCOVERY_YEAR) | 0.595 | No supera 0.7 |
| Pearson X2 (FID_YEAR) | 0.9783 | Aceptado |
| F-test modelo | 3.726e-176 | Significativo |
cat("R² del modelo:", round(r2, 4), "\n")
## R² del modelo: 0.9574
Nota honesta: X2 (FID_YEAR) pasa ampliamente el test de Pearson (0.9783), pero X1 (DISCOVERY_YEAR) individualmente no supera 0.7 (da 0.595). Aun así, el modelo conjunto explica 95.7% de la variabilidad de Y (R² = 0.9574), porque X2 aporta la mayor parte de la explicación y X1 suma información adicional. Si tu profesor exige que ambas variables superen 0.7 individualmente, este par no cumple esa condición estricta — avisame y probamos otra combinación.
escenarios <- expand.grid(
DISCOVERY_YEAR = c(min(tabla$DISCOVERY_YEAR), 2000, 2015),
FID_YEAR = c(min(tabla$FID_YEAR), 2005, 2020)
)
escenarios$PRODUCTION_START_YEAR_ESTIMADA <- predict(modelo, newdata = escenarios)
escenarios %>%
mutate(PRODUCTION_START_YEAR_ESTIMADA = round(PRODUCTION_START_YEAR_ESTIMADA, 2)) %>%
gt() %>%
tab_header(title = md("**Estimaciones del Modelo**"))
| Estimaciones del Modelo | ||
| DISCOVERY_YEAR | FID_YEAR | PRODUCTION_START_YEAR_ESTIMADA |
|---|---|---|
| 1938 | 1975 | 1978.34 |
| 2000 | 1975 | 1977.38 |
| 2015 | 1975 | 1977.14 |
| 1938 | 2005 | 2008.68 |
| 2000 | 2005 | 2007.72 |
| 2015 | 2005 | 2007.48 |
| 1938 | 2020 | 2023.85 |
| 2000 | 2020 | 2022.89 |
| 2015 | 2020 | 2022.65 |
Con DISCOVERY_YEAR y FID_YEAR se obtiene el mejor ajuste con regresión lineal múltiple (un plano en 3D):
\[y = 11.13 + -0.0156x_1 + 1.0113x_2\]
Por cada unidad que aumenta el año de descubrimiento, Y cambia en -0.0156 (con FID_YEAR constante); por cada unidad que aumenta el año de FID, Y cambia en 1.0113 (con DISCOVERY_YEAR constante).
El modelo explica 95.7% de la variabilidad de Y (R²). Pearson: r = 0.595 para X1 (no supera 0.7), r = 0.978 para X2 (aceptado). F-test: significativo (p = 3.73e-176).