1. Librerías

Cargamos los paquetes necesarios para la manipulación de datos, visualización y análisis estadístico.

# Instalar paquetes si no están instalados
# install.packages("tidyverse")
# install.packages("ggplot2")
# install.packages("nortest")

library(tidyverse)
library(ggplot2)
library(knitr)

2. Carga de datos

Cargamos el dataset mediante una ventana interactiva para garantizar que RStudio encuentre el archivo sin errores de ruta.

# Se abrirá una ventana para seleccionar el archivo CSV descargado
ruta_archivo <- file.choose()

datos <- read.csv(ruta_archivo, 
                  sep = ";", 
                  fileEncoding = "latin1", 
                  stringsAsFactors = FALSE)

# Verificamos las dimensiones iniciales
dim(datos)
## [1] 47407    55

3. Selección de variables y Causa-Efecto

Seleccionamos las variables cuantitativas de estudio mediante su posición en el dataset:

  • Variable Independiente (\(X\)): Columna 34 (Proposed Depth, ft - Profundidad propuesta del pozo en pies).
  • Variable Dependiente (\(Y\)): Columna 45 (Permit Fee - Tarifa de permiso pagada en USD).

Justificación Causa-Efecto: Existe una relación de causalidad técnica y administrativa: a mayor profundidad propuesta para la perforación de un pozo, mayores son los requerimientos técnicos, de seguridad y de supervisión ambiental por parte de los organismos reguladores, lo cual incrementa directamente los costos administrativos y la tarifa del permiso (Permit Fee).

# Seleccionamos por índice numérico para evitar errores con caracteres especiales en los nombres
df_reg <- datos %>%
  select(34, 45) %>%
  rename(X = 1, Y = 2) %>%
  mutate(
    X = as.numeric(gsub(",", "", as.character(X))),
    Y = as.numeric(gsub(",", "", as.character(Y)))
  ) %>%
  drop_na()

# Comprobación de que no queden valores nulos
summary(df_reg)
##        X                 Y          
##  Min.   :    0.0   Min.   :    0.0  
##  1st Qu.:    0.0   1st Qu.:    0.0  
##  Median :    0.0   Median :    0.0  
##  Mean   :  998.1   Mean   :  266.6  
##  3rd Qu.: 1720.0   3rd Qu.:  350.0  
##  Max.   :13450.0   Max.   :11000.0

4. Tabla de pares de valores

Se indica el tamaño muestral total y se despliegan las primeras filas de la tabla de pares \((X, Y)\) como muestra representativa.

# Tamaño muestral
n <- nrow(df_reg)
cat("Tamaño muestral (n):", n, "\n\n")
## Tamaño muestral (n): 43819
# Mostrar las primeras filas de la tabla de pares de valores
kable(head(df_reg, 10), caption = "Primeras 10 filas de pares de valores (X, Y)")
Primeras 10 filas de pares de valores (X, Y)
X Y
0 0
0 0
0 0
1800 860
1500 475
2025 0
2067 725
0 0
0 0
0 0

5. Gráfica de dispersión inicial

Visualizamos la distribución conjunta de los datos para observar la tendencia inicial entre la profundidad propuesta y la tarifa de permiso.

ggplot(df_reg, aes(x = X, y = Y)) +
  geom_point(color = "steelblue", alpha = 0.5) +
  labs(title = "Gráfica de Dispersión Inicial",
       subtitle = "Relación entre Profundidad Propuesta y Tarifa de Permiso",
       x = "Profundidad Propuesta (X - ft)",
       y = "Tarifa de Permiso (Y - USD)") +
  theme_minimal()


6. Conjetura y Tratamiento de Datos

6.1 Tratamiento de los datos

Debido a la presencia de valores extremos (outliers) y una alta concentración en cero, aplicamos un filtrado para aislar pozos con valores positivos significativos y eliminar valores atípicos extremos que distorsionen la tendencia lineal clásica.

# Filtrar valores positivos lógicos para limpiar la nube de puntos caótica inicial
df_clean <- df_reg %>%
  filter(X > 0, Y > 0, X <= 12000, Y <= 6000)

cat("Tamaño muestral después del filtrado:", nrow(df_clean))
## Tamaño muestral después del filtrado: 12393

6.2 Nueva gráfica de dispersión

ggplot(df_clean, aes(x = X, y = Y)) +
  geom_point(color = "darkorange", alpha = 0.6) +
  geom_smooth(method = "lm", color = "darkred", se = TRUE) +
  labs(title = "Nueva Gráfica de Dispersión (Datos Depurados)",
       x = "Profundidad Propuesta (X - ft)",
       y = "Tarifa de Permiso (Y - USD)") +
  theme_minimal()

6.3 Nueva conjetura

Tras el filtrado de valores atípicos y ceros administrativos, la nube de puntos muestra una tendencia lineal positiva más clara y acotada, permitiendo aplicar el modelo de regresión lineal simple con mayor fiabilidad.


7. Cálculo de parámetros

Calculamos la pendiente (\(\beta_1\)), el intercepto (\(\beta_0\)) y el coeficiente de correlación de Pearson (\(r\)).

# Ajuste del modelo de regresión lineal
modelo <- lm(Y ~ X, data = df_clean)

# Resumen de parámetros
summary(modelo)
## 
## Call:
## lm(formula = Y ~ X, data = df_clean)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2781.7  -112.4   -30.2   212.6  3813.4 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 1.486e+02  8.926e+00   16.65   <2e-16 ***
## X           2.771e-01  2.697e-03  102.74   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 511.2 on 12391 degrees of freedom
## Multiple R-squared:   0.46,  Adjusted R-squared:   0.46 
## F-statistic: 1.056e+04 on 1 and 12391 DF,  p-value: < 2.2e-16
# Coeficiente de correlación
r_val <- cor(df_clean$X, df_clean$Y)
cat("Coeficiente de correlación (r):", round(r_val, 4), "\n")
## Coeficiente de correlación (r): 0.6782

8. Realidad y modelo

Evaluamos la ecuación de la recta obtenida y su representación sobre los datos reales.

coefs <- coef(modelo)
beta_0 <- coefs[1]
beta_1 <- coefs[2]

cat(sprintf("Ecuación del modelo ajustado: Y = %.4f + %.4f * X\n", beta_0, beta_1))
## Ecuación del modelo ajustado: Y = 148.5987 + 0.2771 * X

9. Test (Pruebas de Hipótesis y Residuales)

Evaluamos la significancia del modelo mediante el análisis de varianza (ANOVA) y la normalidad de los residuos.

# ANOVA del modelo
anova(modelo)
## Analysis of Variance Table
## 
## Response: Y
##              Df     Sum Sq    Mean Sq F value    Pr(>F)    
## X             1 2758796303 2758796303   10556 < 2.2e-16 ***
## Residuals 12391 3238327781     261345                      
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Normalidad de los residuos (Shapiro-Wilk en muestra reducida por eficiencia)
set.seed(123)
residuos <- residuals(modelo)
shapiro_test <- shapiro.test(sample(residuos, min(5000, length(residuos))))
print(shapiro_test)
## 
##  Shapiro-Wilk normality test
## 
## data:  sample(residuos, min(5000, length(residuos)))
## W = 0.82343, p-value < 2.2e-16

10. Restricciones

Se establecen las restricciones operativas del modelo:

  • Dominio de aplicación (\(X\)): El modelo es válido únicamente para profundidades propuestas entre el valor mínimo y máximo de los datos depurados (200 ft hasta 1.19^{4} ft).
  • Naturaleza física: No se admiten profundidades negativas ni tarifas de permisos negativas.

11. Estimación (Predicción)

Realizamos una estimación puntual utilizando un valor de profundidad de prueba dentro del rango analizado (por ejemplo, \(X = 5000\) pies).

# Valor nuevo para estimar
X_nuevo <- data.frame(X = 5000)

# Predicción con intervalo de confianza
prediccion <- predict(modelo, newdata = X_nuevo, interval = "confidence")

print(prediccion)
##        fit      lwr      upr
## 1 1534.187 1519.637 1548.737

12. Conclusión

Se concluye que existe una relación estadísticamente significativa entre la profundidad propuesta del pozo y la tarifa de permiso requerida. El modelo lineal permite estimar de forma razonable los costos administrativos regulatorios en función de la magnitud del diseño de perforación proyectado.