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
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_CO (variable independiente) y EMIS_CO2 (variable dependiente). Ambos gases son productos directos de la oxidación del carbono del combustible: el CO se genera cuando la combustión es incompleta y el CO2 cuando es completa. A medida que mejora la eficiencia de la combustión, el CO2 crece de forma sostenida pero con una tasa marginal decreciente respecto al CO, lo que sugiere una relación de tipo potencial entre ambas variables.
co <- as.numeric(datos$EMIS_CO)
co2 <- as.numeric(datos$EMIS_CO2)
co[is.na(co)] <- median(co, na.rm = TRUE)
co2[is.na(co2)] <- median(co2, na.rm = TRUE)
TPV <- data.frame(co, co2)
dim(TPV)
## [1] 2997 2
colSums(is.na(TPV))
## co co2
## 0 0
# El modelo potencial requiere valores positivos
TPV <- TPV[TPV$co > 0 & TPV$co2 > 0, ]
# Eliminar outliers - EMIS_CO
Q1_co <- quantile(TPV$co, 0.25)
Q3_co <- quantile(TPV$co, 0.75)
IQR_co <- Q3_co - Q1_co
lim_inf_co <- Q1_co - 1.5 * IQR_co
lim_sup_co <- Q3_co + 1.5 * IQR_co
# Eliminar outliers - EMIS_CO2
Q1_co2 <- quantile(TPV$co2, 0.25)
Q3_co2 <- quantile(TPV$co2, 0.75)
IQR_co2 <- Q3_co2 - Q1_co2
lim_inf_co2 <- Q1_co2 - 1.5 * IQR_co2
lim_sup_co2 <- Q3_co2 + 1.5 * IQR_co2
# Tabla sin outliers
TPV_limpio <- TPV[
TPV$co >= lim_inf_co & TPV$co <= lim_sup_co &
TPV$co2 >= lim_inf_co2 & TPV$co2 <= lim_sup_co2,
]
cat("Tamaño muestral: n =", nrow(TPV_limpio))
## Tamaño muestral: n = 2834
TPV_tabla <- head(TPV_limpio, 10)
TPV_tabla %>%
gt() %>%
tab_header(title = "Tabla N°1: Pares de valores EMIS_CO - EMIS_CO2") %>%
cols_label(co = "EMIS_CO", co2 = "EMIS_CO2") %>%
tab_source_note(source_note = "Autor: Luis Cruz")
| Tabla N°1: Pares de valores EMIS_CO - EMIS_CO2 | |
| EMIS_CO | EMIS_CO2 |
|---|---|
| 36.246 | 130.080 |
| 161.005 | 318.677 |
| 260.735 | 446.328 |
| 5.171 | 71.436 |
| 128.056 | 301.645 |
| 102.359 | 258.165 |
| 14.041 | 62.459 |
| 307.286 | 493.452 |
| 171.676 | 301.545 |
| 160.687 | 333.784 |
| Autor: Luis Cruz | |
x <- as.numeric(TPV_limpio$co)
y <- as.numeric(TPV_limpio$co2)
validos <- complete.cases(x, y) &
is.finite(x) &
is.finite(y)
x <- x[validos]
y <- y[validos]
orden <- order(x)
x <- x[orden]
y <- y[orden]
plot(x, y,
pch = 16,
col = "blue",
xlim = c(0, max(x)),
ylim = c(0, max(y)),
main = "Gráfica N°1: Diagrama de dispersión entre EMIS_CO\ny EMIS_CO2 en emisiones registradas",
xlab = "EMIS_CO (unidades)",
ylab = "EMIS_CO2 (unidades)")
# El filtro de outliers por IQR ya se aplicó en la Tabla de Pares
# de Valores (TPV_limpio). Se verifica que no queden atípicos:
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_CO:", outliers_x, "\nOutliers en EMIS_CO2:", outliers_y)
## Outliers en EMIS_CO: 0
## Outliers en EMIS_CO2: 0
El filtro de outliers ya aplicado en la Tabla de Pares no eliminó observaciones adicionales relevantes: la dispersión observada corresponde a variabilidad genuina, no a datos anómalos. No es necesario un tratamiento adicional.
No aplica: el filtrado de outliers ya se realizó en la Tabla de Pares
de Valores original (Tabla N°1, con TPV_limpio).
No aplica: la gráfica de dispersión de la sección anterior (Gráfica N°1) ya refleja los datos tratados, por lo que no se requiere una nueva gráfica.
La nube de puntos muestra un crecimiento sostenido con curvatura suave, sin dispersión caótica, compatible con un modelo potencial. Se mantiene esta conjetura tras el tratamiento de datos.
ajuste_log <- lm(log(y) ~ log(x))
ajuste_log
##
## Call:
## lm(formula = log(y) ~ log(x))
##
## Coefficients:
## (Intercept) log(x)
## 2.8486 0.5702
a <- exp(coef(ajuste_log)[1]) # intercepto transformado
b <- coef(ajuste_log)[2] # exponente
a
## (Intercept)
## 17.26346
b
## log(x)
## 0.5701753
plot(1, type = "n", axes = FALSE, xlab = "", ylab = "")
texto_ecuacion <- paste0(
"Modelo potencial general\n",
"Y = a * x^b\n\n",
"Modelo ajustado:\n",
"Y = ", round(a, 4), " * x^", round(b, 4)
)
text(x = 1, y = 1, labels = texto_ecuacion, cex = 1.5, col = "blue", font = 2)
plot(x, y,
pch = 16,
col = "blue",
xlim = c(0, max(x)),
ylim = c(0, max(y)),
main = "Gráfica N°2: Comparación entre la realidad y el modelo potencial\nentre EMIS_CO y EMIS_CO2",
xlab = "EMIS_CO (unidades)",
ylab = "EMIS_CO2 (unidades)")
curve(a * x^b,
from = min(x),
to = max(x),
add = TRUE,
col = "red",
lwd = 3)
legend("topleft",
legend = c("Datos reales", "Modelo potencial"),
col = c("blue", "red"),
pch = c(16, NA),
lty = c(NA, 1),
lwd = c(NA, 3))
r <- cor(log(x), log(y))
r * 100
## [1] 87.40229
predicciones <- a * x^b
SSE <- sum((y - predicciones)^2)
SST <- sum((y - mean(y))^2)
r2 <- 1 - (SSE / SST)
r2 * 100
## [1] 90.78576
# El modelo potencial y = a * x^b, con dominio x > 0, no tiene raíz
# real dentro de ese dominio: x^b siempre es positivo para x > 0,
# sin importar el valor de b. El signo depende únicamente de "a"
ecuacion <- paste0("y = ", round(a, 4), " * x^", round(b, 4))
condicion_negativo <- ifelse(a > 0,
"Nunca (modelo siempre positivo)",
"Siempre (modelo siempre negativo)")
tabla_restricciones <- data.frame(
Modelo = c("Potencial", "Potencial"),
Ecuacion = c(ecuacion, ecuacion),
Condicion = c("y = 0 (raíz)", "y < 0 (no aplica)"),
Valor = c("No existe", condicion_negativo)
)
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(110),
Ecuacion ~ px(200),
Condicion ~ px(140),
Valor ~ px(200)
) %>%
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 |
|---|---|---|---|
| Potencial | y = 17.2635 * x^0.5702 | y = 0 (raíz) | No existe |
| Potencial | y = 17.2635 * x^0.5702 | y < 0 (no aplica) | Nunca (modelo siempre positivo) |
| Autor: Luis Cruz | |||
El modelo potencial no corta el eje x dentro de su dominio (x >
0), porque x^b siempre es positivo sin importar el valor de
b. El signo de toda la curva depende exclusivamente de
a. Como a es positivo, el modelo predice
siempre valores positivos de EMIS_CO2 en todo su dominio, por lo que no
existe un intervalo donde el modelo no aplique.
Nota: dominio matemático de x: x > 0 (exigido por la transformación logarítmica usada para ajustar el modelo). Dominio de y: en la realidad EMIS_CO2 solo puede tomar valores y ≥ 0.
CO_ejemplo <- 150
CO2_esp <- a * CO_ejemplo^b
CO2_esp
## (Intercept)
## 300.5255
plot(1, type = "n", axes = FALSE, xlab = "", ylab = "")
texto_pronostico <- paste0(
"¿Qué valor de EMIS_CO2 se espera\n",
"cuando EMIS_CO es de 150 unidades?\n\n",
"R = ", round(CO2_esp, 2), " unidades"
)
text(x = 1, y = 1, labels = texto_pronostico, cex = 1.5, col = "blue", font = 2)
Entre EMIS_CO2 (variable dependiente) y EMIS_CO (variable independiente) existe una relación de tipo no lineal (potencial) cuyo modelo matemático es:
\[Y = 17.2635\,X^{0.5702}\]
siendo Y = EMIS_CO2 y X = EMIS_CO, donde no existen
restricciones: dentro del dominio del modelo (X > 0),
X^b es siempre positivo y la constante a es
positiva, por lo que el modelo nunca produce valores negativos ni corta
el eje X.