library(dplyr)
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(gt)
datos <- read.csv("~/Estudio/TERCER SEMESTRE/Estadistica/proyecto/Dataset.csv",
sep = ";", stringsAsFactors = FALSE)
str(datos)
## 'data.frame': 2997 obs. of 6 variables:
## $ EMIS_CO2 : num 130.1 318.7 446.3 71.4 301.6 ...
## $ EMIS_NOX : num 66 151.7 369.6 30.5 262.8 ...
## $ EMIS_SO2 : num 9.73 16.2 21.18 3.94 16.89 ...
## $ EMIS_CO : num 36.25 161 260.74 5.17 128.06 ...
## $ EMIS_PM10: num 39.8 76.1 78.9 20.4 61.1 ...
## $ EMIS_PM25: num 24.5 27.8 28.3 22.2 26.5 ...
summary(datos)
## EMIS_CO2 EMIS_NOX EMIS_SO2 EMIS_CO
## Min. : 20.0 Min. : 0.00 Min. : 0.000 Min. : 0.00
## 1st Qu.:140.0 1st Qu.: 99.94 1st Qu.: 9.772 1st Qu.: 42.48
## Median :259.0 Median :187.00 Median :15.128 Median :107.51
## Mean :260.4 Mean :188.33 Mean :13.613 Mean :125.81
## 3rd Qu.:380.6 3rd Qu.:275.27 3rd Qu.:18.349 3rd Qu.:199.96
## Max. :499.8 Max. :439.54 Max. :25.148 Max. :376.00
## EMIS_PM10 EMIS_PM25
## Min. : 7.679 Min. :14.45
## 1st Qu.: 38.407 1st Qu.:24.41
## Median : 56.428 Median :26.94
## Mean : 54.282 Mean :26.32
## 3rd Qu.: 70.536 3rd Qu.:28.60
## Max. :104.859 Max. :35.50
# Verificación de valores NA en el dataset original
colSums(is.na(datos))
## EMIS_CO2 EMIS_NOX EMIS_SO2 EMIS_CO EMIS_PM10 EMIS_PM25
## 0 0 0 0 0 0
Se seleccionan EMIS_NOX (variable independiente) y EMIS_CO2 (variable dependiente). Ambas emisiones provienen del mismo proceso de combustión en la actividad minera: a mayor intensidad de la quema de combustibles fósiles, se generan simultáneamente mayores cantidades de NOx (por oxidación del nitrógeno del aire a altas temperaturas) y de CO2 (producto directo de la combustión del carbono). Esta relación causa-efecto (intensidad de combustión → NOx y CO2) justifica evaluar si el comportamiento del CO2 puede explicarse en función del NOx.
# Extraer variables numéricas
nox <- as.numeric(datos$EMIS_NOX)
co2 <- as.numeric(datos$EMIS_CO2)
# Imputación de NA con la mediana (en vez de omitir filas)
nox[is.na(nox)] <- median(nox, na.rm = TRUE)
co2[is.na(co2)] <- median(co2, na.rm = TRUE)
TPV <- data.frame(nox, co2)
dim(TPV)
## [1] 2997 2
colSums(is.na(TPV))
## nox co2
## 0 0
# Tamaño muestral
cat("Tamaño muestral: n =", nrow(TPV))
## Tamaño muestral: n = 2997
TPV_tabla <- head(TPV, 10)
TPV_tabla %>%
gt() %>%
tab_header(title = "Tabla N°1: Pares de valores EMIS_NOX - EMIS_CO2") %>%
cols_label(nox = "EMIS_NOX", co2 = "EMIS_CO2") %>%
tab_source_note(source_note = "Autor: Luis Cruz")
| Tabla N°1: Pares de valores EMIS_NOX - EMIS_CO2 | |
| EMIS_NOX | EMIS_CO2 |
|---|---|
| 66.010 | 130.080 |
| 151.677 | 318.677 |
| 369.579 | 446.328 |
| 30.482 | 71.436 |
| 262.797 | 301.645 |
| 178.235 | 258.165 |
| 76.423 | 62.459 |
| 297.944 | 493.452 |
| 214.639 | 301.545 |
| 193.373 | 333.784 |
| Autor: Luis Cruz | |
x <- TPV$nox # Variable independiente
y <- TPV$co2 # Variable dependiente
plot(x, y,
pch = 16,
col = "blue",
xlim = c(min(x), max(x)),
ylim = c(0, max(y)),
main = "Gráfica N°1: Diagrama de dispersión entre EMIS_NOX\ny EMIS_CO2 en emisiones registradas",
xlab = "EMIS_NOX (unidades)",
ylab = "EMIS_CO2 (unidades)")
# Verificación de outliers por rango intercuartílico (IQR)
Q1_x <- quantile(x, 0.25); Q3_x <- quantile(x, 0.75); IQR_x <- Q3_x - Q1_x
Q1_y <- quantile(y, 0.25); Q3_y <- quantile(y, 0.75); IQR_y <- Q3_y - Q1_y
outliers_x <- sum(x < (Q1_x - 1.5*IQR_x) | x > (Q3_x + 1.5*IQR_x))
outliers_y <- sum(y < (Q1_y - 1.5*IQR_y) | y > (Q3_y + 1.5*IQR_y))
cat("Outliers en EMIS_NOX:", outliers_x, "\nOutliers en EMIS_CO2:", outliers_y)
## Outliers en EMIS_NOX: 0
## Outliers en EMIS_CO2: 0
No se identifican valores atípicos relevantes ni una nube caótica,
por lo que no es necesario aplicar segmentación ni
omitir observaciones. Se continúa con los datos originales
(TPV).
No aplica: no se eliminó ninguna observación, por lo que la tabla de pares de valores (Tabla N°1) ya representa los datos finales usados en el modelo.
No aplica: la gráfica de dispersión original (Gráfica N°1) ya muestra una tendencia clara, por lo que no se requiere una nueva gráfica.
La nube de puntos muestra una tendencia clara, creciente y sin dispersión caótica, compatible con un modelo lineal simple. Se mantiene esta conjetura tras el tratamiento de datos.
regresion_lineal <- lm(y ~ x)
regresion_lineal
##
## Call:
## lm(formula = y ~ x)
##
## Coefficients:
## (Intercept) x
## 23.930 1.256
a <- coef(regresion_lineal)[2] # pendiente
b <- coef(regresion_lineal)[1] # intercepto
a
## x
## 1.255555
b
## (Intercept)
## 23.92991
plot(1, type = "n", axes = FALSE, xlab = "", ylab = "")
texto_ecuacion <- paste0(
"Ecuación lineal general\n",
"Y = ax + b\n",
"Modelo ajustado:\n",
"Y = ", round(a, 4), "x + ", round(b, 4)
)
text(x = 1, y = 1, labels = texto_ecuacion, cex = 1.8, col = "blue", font = 2)
plot(x, y,
pch = 16,
col = "blue",
xlim = c(min(x), max(x)),
ylim = c(0, max(y)),
main = "Gráfica N°2: Comparación de la realidad con el modelo lineal\nentre EMIS_NOX y EMIS_CO2",
xlab = "EMIS_NOX (unidades)",
ylab = "EMIS_CO2 (unidades)")
abline(regresion_lineal, col = "red", lwd = 2)
# Test de Pearson
r <- cor(x, y)
r * 100
## [1] 94.99882
# Coeficiente de determinación
r2 <- r^2
r2 * 100
## [1] 90.24777
# Raíz del modelo: valor de x donde y = 0
x0 <- unname(-b / a)
x0
## [1] -19.05923
intervalo <- ifelse(a > 0,
paste0("x < ", round(x0, 2)),
paste0("x > ", round(x0, 2)))
ecuacion <- paste0("y = ", round(a, 4), "x + ", round(b, 4))
tabla_restricciones <- data.frame(
Modelo = c("Lineal", "Lineal"),
Ecuacion = c(ecuacion, ecuacion),
Condicion = c("y = 0 (raíz)", "y < 0 (no aplica)"),
Valor = c(paste0("x = ", round(x0, 2)), intervalo)
)
tabla_restricciones %>%
gt() %>%
tab_header(title = "Tabla N°2: Valores donde el modelo es 0 o negativo") %>%
cols_label(Modelo = "Modelo",
Ecuacion = "Ecuación",
Condicion = "Condición",
Valor = "Valor / Intervalo de x") %>%
cols_width(
Modelo ~ px(100),
Ecuacion ~ px(180),
Condicion ~ px(140),
Valor ~ px(160)
) %>%
tab_style(
style = cell_text(align = "center"),
locations = cells_body()
) %>%
tab_style(
style = cell_text(align = "center"),
locations = cells_column_labels()
) %>%
tab_source_note(source_note = "Autor: Luis Cruz")
| Tabla N°2: Valores donde el modelo es 0 o negativo | |||
| Modelo | Ecuación | Condición | Valor / Intervalo de x |
|---|---|---|---|
| Lineal | y = 1.2556x + 23.9299 | y = 0 (raíz) | x = -19.06 |
| Lineal | y = 1.2556x + 23.9299 | y < 0 (no aplica) | x < -19.06 |
| Autor: Luis Cruz | |||
El modelo corta el eje x (y = 0) en x = -19.06. Dado que la pendiente
a es positiva, el modelo produce valores negativos de
EMIS_CO2 cuando x < -19.06.
Como EMIS_NOX no puede ser negativo en la realidad, ese intervalo queda fuera del rango de valores físicamente posibles, por lo que no afecta las predicciones dentro del dominio real de la variable.
Nota: dominio matemático de x: todos los reales (el modelo lineal no exige ninguna restricción sobre x). Dominio de y: en la realidad EMIS_CO2 solo puede tomar valores y ≥ 0.
co2_esp <- predict(regresion_lineal, newdata = data.frame(x = 200))
co2_esp
## 1
## 275.041
plot(1, type = "n", axes = FALSE, xlab = "", ylab = "")
text(x = 1, y = 1,
labels = "¿Qué valor de EMIS_CO2 se espera\ncuando EMIS_NOX es de 200 unidades?
R = 257.07",
cex = 1.8, col = "blue", font = 2)
Entre EMIS_CO2 (variable dependiente) y EMIS_NOX (variable independiente) existe una relación de tipo lineal cuyo modelo matemático es:
\[Y = 23.9299 + 1.2556\,X\]
siendo Y = EMIS_CO2 y X = EMIS_NOX, donde sí existen restricciones: el modelo produce valores negativos de EMIS_CO2 cuando x < -19.06 (raíz en x = -19.06), aunque ese intervalo queda fuera del dominio físico real de EMIS_NOX (x ≥ 0).
EMIS_CO2 está influenciada en un 90.25% por EMIS_NOX, y el 9.75% restante se debe a otros factores.