0.- Librerías

library(readr)
library(dplyr)
library(knitr)
library(kableExtra)
library(ggplot2)
library(e1071)
library(tidyverse)
library(lubridate)
library(plotly)
library(scatterplot3d)

1.- leer datos

variables <- read_csv("C:/Users/CESAR/Downloads/proyecto x/GlobalWeatherRepository.csv", show_col_types = TRUE)

2.- Selección de variables (Causa y Efecto)

Causa y Efecto:

Cuando un motor quema combustible, no solo libera una cosa como el CO, libera una “mezcla” de estos contaminantes al mismo tiempo. Es decir, donde hay mucho tráfico, verás que los niveles de los tres suben simultáneamente.

y  <- as.numeric(variables$air_quality_Carbon_Monoxide)
x1 <- as.numeric(variables$air_quality_PM2.5)
x2 <- as.numeric(variables$air_quality_Nitrogen_dioxide)
TTP <- data.frame(y, x1, x2)
n <- nrow(TTP)
cat("Tamaño muestral del modelo = ", n)
## Tamaño muestral del modelo =  141703

3.- Tabla de tripreta de valores

Antes de realizar la tabla tripelta de valores, debemos comprobar que estas variables tengan el mismo tamaño muestral para no tener algún error a la hora de hacer la tabla y el gráfico

Depuracion de datos

limpiar_columna <- function(df, cols) {
  for (col in cols) {
    df[[col]] <- as.numeric(as.character(df[[col]]))
  }
  return(df)
}

# Aplicar la función a tus variables climáticas
datos <- limpiar_columna(variables, c("air_quality_Carbon_Monoxide", "air_quality_PM2.5", "air_quality_Nitrogen_dioxide"))

# Filtrar filas completas (eliminar los NA)
datos_limpios <- datos %>% filter(!is.na(air_quality_Carbon_Monoxide) & !is.na(air_quality_PM2.5) & !is.na(air_quality_Nitrogen_dioxide))

# Asignar variables para el análisis
y  <- datos_limpios$air_quality_Carbon_Monoxide
x1 <- datos_limpios$air_quality_PM2.5
x2 <- datos_limpios$air_quality_Nitrogen_dioxide

TTP <- data.frame(y, x1, x2)
n <- nrow(TTP)
cat("Tamaño muestral del modelo = ", n)
## Tamaño muestral del modelo =  141703
# 1. Preparar los datos redondeados a 8 dígitos
# Creamos el data frame con tus variables limpias
tabla_tripleta <- head(data.frame(
  CO = round(y, 8),
  `PM 2.5` = round(x1, 8),
  NO2 = round(x2, 8),
  check.names = FALSE
), 300)

# 2. Generar la tabla con tu estilo personalizado
kable(
  tabla_tripleta,   
  digits = 8,                 # Asegura que muestre los decimales
  align = "c",                
  booktabs = TRUE,
  caption = "Tabla N.1: Tripleta de valores: CO, PM 2.5 y NO2 para el análisis
  meteorológico en capitales del mundo
  Periodo: Mayo 2024 a Mayo 2026"
) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"), 
    full_width = FALSE,                                     
    position = "center"                                     
  ) %>%
  row_spec(
    0, 
    bold = TRUE, 
    color = "white",       
    background = "#1F4E79" 
  ) %>%
  footnote(
    general = "Fuente: Global Weather Repository.",
    general_title = "Nota: ", 
    footnote_as_chunk = TRUE
  ) %>%
  scroll_box(height = "400px", width = "100%")
Tabla N.1: Tripleta de valores: CO, PM 2.5 y NO2 para el análisis meteorológico en capitales del mundo Periodo: Mayo 2024 a Mayo 2026
CO PM 2.5 NO2
277.0 8.4 1.1
193.6 1.1 0.9
540.7 10.4 65.1
170.2 0.7 1.6
2964.0 183.4 72.7
220.3 1.2 0.2
270.4 4.0 8.3
186.9 0.8 1.0
277.0 3.7 15.1
220.3 3.7 5.1
227.0 1.9 7.1
330.5 12.2 1.2
397.2 39.0 18.5
520.7 49.7 8.7
257.0 1.9 1.0
201.9 1.6 1.4
277.0 14.7 22.3
307.1 7.7 0.3
587.5 8.2 4.5
280.4 9.3 0.2
212.0 4.6 2.1
178.6 2.7 1.1
433.9 16.4 7.3
168.6 0.5 0.2
323.8 2.2 1.8
233.7 3.5 4.5
474.0 5.4 1.7
687.6 33.3 2.1
212.0 0.5 0.0
181.9 6.1 0.6
1295.1 17.1 14.9
727.7 25.6 4.9
193.6 5.0 1.8
217.0 0.5 0.1
480.7 13.6 1.0
2723.7 211.1 41.8
1335.1 84.9 101.5
212.0 3.0 1.2
257.0 1.5 0.2
694.3 17.3 11.8
1161.6 21.7 10.9
227.0 6.6 8.8
317.1 4.7 5.9
195.3 7.7 0.4
205.3 3.4 2.9
694.3 17.3 11.8
230.3 5.8 4.8
267.0 9.5 2.0
203.6 0.9 0.5
387.2 7.0 14.4
2403.3 26.3 72.7
217.0 11.7 6.9
460.6 20.4 7.7
320.4 2.1 0.6
250.3 13.9 0.1
217.0 7.3 4.6
297.1 22.0 1.1
250.3 12.0 0.1
213.6 2.6 2.1
208.6 5.5 2.1
397.2 9.8 20.7
1094.8 41.0 15.6
195.3 12.9 0.9
208.6 2.0 1.7
223.6 6.6 4.0
407.2 19.2 4.5
230.3 8.7 12.5
243.7 2.4 0.8
2243.0 132.0 35.0
774.4 16.7 8.1
176.9 15.8 0.4
210.3 1.1 2.9
674.3 10.7 9.9
574.1 41.8 26.1
377.2 19.0 3.7
212.0 5.4 3.4
200.3 0.5 0.6
307.1 25.4 3.0
3471.4 196.1 52.1
1041.4 34.4 145.3
403.9 13.5 25.0
243.7 8.4 14.1
186.9 5.0 1.6
574.1 41.8 26.1
707.6 10.1 12.2
317.1 15.8 31.2
180.2 4.5 1.9
213.6 1.9 3.3
1682.3 58.0 4.4
217.0 2.5 0.0
547.4 31.9 76.1
203.6 3.1 0.5
397.2 10.0 2.2
260.4 6.7 4.7
198.6 5.8 0.9
487.3 29.8 4.5
300.4 1.7 0.7
487.3 2.8 0.7
203.6 4.9 10.0
208.6 1.6 1.4
188.6 2.1 17.8
327.1 2.6 0.8
243.7 1.1 0.4
2456.7 40.5 133.0
233.7 1.0 0.0
387.2 2.8 1.1
247.0 29.8 5.1
180.2 1.3 0.0
207.0 33.3 0.5
223.6 2.0 1.2
974.7 35.1 48.7
180.2 0.6 0.0
176.9 4.8 0.3
213.6 3.7 4.0
347.1 12.6 14.9
185.3 1.3 0.2
190.3 1.8 0.5
260.4 3.6 0.5
230.3 1.7 0.1
212.0 2.1 0.1
210.3 8.4 0.9
327.1 22.3 0.6
280.4 15.3 33.2
227.0 0.5 0.9
500.7 11.7 6.5
383.9 10.3 0.9
540.7 12.6 1.2
230.3 6.5 1.2
208.6 7.6 5.1
270.4 11.5 32.9
303.8 46.6 2.1
303.8 15.5 3.4
176.9 0.9 0.1
185.3 1.8 0.1
397.2 2.9 8.7
227.0 2.8 4.1
217.0 3.6 0.2
303.8 9.6 12.2
734.3 32.2 10.5
217.0 3.0 1.4
208.6 1.8 5.4
213.6 27.2 15.1
223.6 3.9 1.6
243.7 4.4 18.5
287.1 4.2 0.5
208.6 1.0 0.3
210.3 1.4 0.1
237.0 1.9 0.7
213.6 1.1 0.5
240.3 14.6 3.3
247.0 13.4 12.0
283.7 49.1 23.7
195.3 21.4 1.0
207.0 2.7 1.5
240.3 2.0 0.1
410.6 8.2 1.9
654.2 8.9 52.8
205.3 4.7 2.8
212.0 2.8 4.2
220.3 0.5 1.0
257.0 2.7 0.1
1134.9 78.1 49.4
360.5 18.7 32.6
170.2 38.7 0.2
186.9 0.5 2.4
667.6 4.0 20.1
263.7 28.0 1.6
188.6 1.1 0.1
253.7 4.2 10.9
213.6 2.4 4.9
183.6 5.1 4.0
233.7 5.5 0.4
233.7 1.9 0.2
3898.6 115.2 85.0
230.3 0.8 0.0
220.3 3.2 1.2
217.0 2.4 0.1
198.6 2.2 0.6
200.3 6.7 1.9
233.7 11.2 6.8
240.3 9.0 6.9
207.0 0.6 0.0
320.4 4.1 0.3
213.6 2.0 0.9
203.6 34.1 1.2
383.9 16.9 31.9
198.6 6.3 2.5
337.1 6.5 8.6
240.3 2.9 11.7
220.3 3.1 0.2
317.1 6.2 13.0
560.8 72.5 14.7
183.6 32.5 2.4
1108.2 10.7 2.7
747.7 67.2 8.3
1495.4 9.4 19.4
195.3 2.3 3.6
198.6 4.3 1.8
156.9 0.7 0.7
494.0 31.7 9.0
233.7 1.0 0.7
634.2 4.8 15.3
195.3 1.0 6.3
307.1 9.9 20.7
203.6 1.5 3.4
253.7 2.0 17.0
350.5 17.5 0.6
230.3 40.1 1.6
934.6 64.2 19.9
253.7 2.4 1.2
213.6 2.3 3.5
212.0 1.9 6.9
290.4 7.0 0.4
387.2 2.5 1.7
337.1 12.1 1.0
230.3 5.3 2.6
185.3 2.0 1.3
303.8 14.8 3.1
201.9 0.5 0.1
567.4 9.5 7.4
227.0 3.0 3.5
387.2 6.1 1.1
373.8 6.4 0.7
212.0 0.5 0.1
193.6 4.3 0.1
1762.4 64.0 43.2
360.5 3.8 0.4
195.3 0.5 0.6
303.8 0.5 0.0
320.4 34.5 0.5
9719.9 714.1 181.0
2697.0 228.2 128.9
208.6 2.8 0.7
247.0 1.4 0.3
627.5 15.0 2.2
1308.4 20.8 14.6
200.3 2.1 3.2
353.8 4.3 5.5
191.9 4.1 0.4
196.9 1.7 3.1
627.5 15.0 2.2
210.3 4.2 2.8
260.4 8.0 1.1
240.3 0.9 0.8
440.6 15.2 19.2
3845.2 59.3 98.7
195.3 13.6 3.6
567.4 29.2 6.7
287.1 1.3 0.0
183.6 14.6 0.2
208.6 8.0 2.4
283.7 17.9 1.3
1335.1 24.0 1.5
205.3 1.7 1.6
203.6 4.9 3.0
213.6 1.6 5.2
540.7 19.4 5.6
217.0 21.8 0.2
186.9 0.7 1.1
198.6 4.5 2.7
317.1 3.4 2.0
203.6 7.7 5.0
240.3 2.4 1.1
1976.0 152.7 21.4
280.4 0.5 0.2
205.3 13.1 0.1
220.3 1.1 4.6
827.8 19.0 5.4
227.0 63.0 2.8
554.1 19.0 6.9
195.3 2.1 2.4
205.3 0.5 0.2
741.0 44.0 22.6
19653.3 492.5 224.8
433.9 5.1 59.0
250.3 14.5 8.0
198.6 3.1 8.7
190.3 6.5 4.4
227.0 63.0 2.8
467.3 2.9 3.8
277.0 9.5 25.0
181.9 6.7 3.9
223.6 5.0 6.5
881.2 18.2 7.1
217.0 1.3 0.0
440.6 19.6 63.1
223.6 1.3 5.4
988.0 22.7 14.6
270.4 13.2 8.2
205.3 8.3 0.9
240.3 9.8 1.1
320.4 0.8 0.2
527.4 8.0 5.7
185.3 1.4 1.5
201.9 2.3 1.8
195.3 1.7 7.2
377.2 3.5 1.6
227.0 0.7 0.3
8972.2 131.5 131.6
212.0 1.2 0.0
Nota: Fuente: Global Weather Repository.

4.- Gráfica de dispersión

# 3. Gráfico original en Plotly
plot_ly(
  data = datos_limpios, 
  x = ~air_quality_PM2.5, 
  y = ~air_quality_Nitrogen_dioxide, 
  z = ~air_quality_Carbon_Monoxide, 
  type = "scatter3d", 
  mode = "markers",
  marker = list(
    size = 2,                    
    color = ~air_quality_Carbon_Monoxide,    
    colorscale = "Viridis", 
    opacity = 0.5                  
  )
) %>%
  layout(
        title = "Gráfico N°1: Nube de puntos, Relación de PM2.5, NO2 y CO 
para el análisis meteorológico en capitales del mundo
  Periodo: Mayo 2024 a Mayo 2026",
    scene = list(
      xaxis = list(title = "PM 2.5 (µg/m³)"),
      yaxis = list(title = "NO2 (µg/m³)"),
      zaxis = list(title = "CO (µg/m³)")
    )
  )

5.- Conjetura

Debido a que los puntos presentados en la gráfica estan musy dispersos procedemos a tratar estos datos

Tratamiento de datos

Estrategia Eliminamos los valores atipicos, trabajamos con los cuatiles del diagrama de caja para una mayor visualisacion de etos puntos y agregamos un color en escalas (Viridis) que conforme baya subienendo los puntos ver si cambio o no de color estas variables para ver su comportamiento

# Definir una función para detectar y limpiar atípicos por el método IQR
limpiar_atipicos <- function(x) {
  Q1 <- quantile(x, 0.25, na.rm = TRUE)
  Q3 <- quantile(x, 0.75, na.rm = TRUE)
  IQR_val <- Q3 - Q1
  limite_inf <- Q1 - 1.5 * IQR_val
  limite_sup <- Q3 + 1.5 * IQR_val
  return(x >= limite_inf & x <= limite_sup)
}

# Aplicar el filtro a las tres variables principales
datos_finales_limpios <- datos_limpios %>%
  filter(
    limpiar_atipicos(air_quality_Carbon_Monoxide),
    limpiar_atipicos(air_quality_PM2.5),
    limpiar_atipicos(air_quality_Nitrogen_dioxide)
  )

plot_ly(
  data = datos_finales_limpios, 
  x = ~air_quality_PM2.5, 
  y = ~air_quality_Nitrogen_dioxide, 
  z = ~air_quality_Carbon_Monoxide, 
  type = "scatter3d", 
  mode = "markers",
  marker = list(
    size = 2,                    
    color = ~air_quality_Carbon_Monoxide,    
    colorscale = "Viridis", 
    opacity = 0.5                  
  )
) %>%
  layout(
    title = "Gráfico N°2: Nube de puntos, Relación de PM2.5, NO2 y CO (Sin valores atípicos)
para el análisis meteorológico en capitales del mundo
  Periodo: Mayo 2024 a Mayo 2026",
    scene = list(
      xaxis = list(title = "PM 2.5 (µg/m³)"),
      yaxis = list(title = "NO2 (µg/m³)"),
      zaxis = list(title = "CO (µg/m³)")
    )
  )

Dado que que los valores de las variables independientes crecen conforme a la variable dependiente podemos conjeurar ya en un modelo de regresión multiple.

Modelo Multiple:

\[Y = a + bX_1 + cX_2\]

6.- Cálculo de parámetros

regresionmultiple<- lm(y~x1+x2, data = TTP)
a <- round(regresionmultiple$coefficients[1], 2)
a
## (Intercept) 
##       66.03
b <- round(regresionmultiple$coefficients[2], 2)
b
##   x1 
## 8.38
c <- round(regresionmultiple$coefficients[3], 2)
c
##   x2 
## 12.5
ecuacion_texto <- paste0("Y = ", a, " + ", b, "X1 + ", c, "X2")

# Imprimir el resultado
cat("La ecuación del modelo es:\n", ecuacion_texto)
## La ecuación del modelo es:
##  Y = 66.03 + 8.38X1 + 12.5X2

7.- Sobreponer la realidad con el modelo

# 1. Definimos los rangos de tus variables para crear la malla del plano
x_range <- seq(min(datos_finales_limpios$air_quality_PM2.5), max(datos_finales_limpios$air_quality_PM2.5), length.out = 30)
y_range <- seq(min(datos_finales_limpios$air_quality_Nitrogen_dioxide), max(datos_finales_limpios$air_quality_Nitrogen_dioxide), length.out = 30)

# 2. Creamos la matriz de Z basada en tu ecuación: Y = 66.03 + 8.38*X1 + 12.5*X2
# Usamos outer para calcular Z para cada combinación de x e y
z_matrix <- outer(x_range, y_range, function(x1, x2) 66.03 + 8.38 * x1 + 12.5 * x2)

# 3. Graficamos la nube y el plano
fig <- plot_ly(datos_finales_limpios, x = ~air_quality_PM2.5, y = ~air_quality_Nitrogen_dioxide, z = ~air_quality_Carbon_Monoxide) %>%
  # Nube de puntos depurada
  add_markers(marker = list(size = 2, color = ~air_quality_Carbon_Monoxide, colorscale = "Viridis", opacity = 0.5)) %>%
  # El plano definido por tu ecuación
  add_surface(x = x_range, y = y_range, z = z_matrix, 
              colorscale = list(c(0, 1), c("red", "red")), 
              opacity = 0.6, 
              showscale = FALSE) %>%
  layout(
    title = "Gráfico N°3: Modelo multiple, Relación de PM2.5, NO2 y CO 
para el análisis meteorológico en capitales del mundo
  Periodo: Mayo 2024 a Mayo 2026",
    scene = list(
      xaxis = list(title = "PM 2.5 (µg/m³)"),
      yaxis = list(title = "NO2 (µg/m³)"),
      zaxis = list(title = "CO (µg/m³)")
    )
  )

fig

8.- Test de Bondad

Correlación de pearson

r <- round(cor(y, x1 + x2), 1) 
r
## [1] 0.7

Coeficiente de determinación

r2 <- (r^2) * 100
r2
## [1] 49

9.- Restricciones

NO2:D = {x ∈ ℝ | x ≥ 0}

PM2.5:D = {x ∈ ℝ | x ≥ 0}

CO:D = {y ∈ ℝ | y ≥ 0}

Error del modelo: ¿Existe un valor de No2 y de PM 2.5 que reemplazado en la ecuación del modelo genere un valor fuera del dominio de CO ?

el modelo no presenta restricciones que generen resultados negativos o fuera del dominio de la variable dependiente. La estructura del modelo garantiza que, para cualquier entrada dentro del dominio de \(NO_2\) y \(PM_{2.5}\) (\(x \geq 0\)), la salida se mantenga siempre dentro del rango de concentración esperado para el \(CO\).

10.- Estimaciones

¿Que valor de CO se espera cuando tengamos una concentración de 30 µg/m³ de PM 2.5 y de 15 µg/m³ de NO2?

PM2.5 <- 30
NO2 <- 15

# Aplicar la ecuación del modelo: Y = 66.03 + 8.38*X1 + 12.5*X2
CO_esperado <- a + (b * PM2.5) + (c * NO2)
CO_esperado
## (Intercept) 
##      504.93

Estimación en la gráfica

# 1. Definimos los rangos del plano (igual que antes)
x_range <- seq(min(datos_finales_limpios$air_quality_PM2.5), max(datos_finales_limpios$air_quality_PM2.5), length.out = 30)
y_range <- seq(min(datos_finales_limpios$air_quality_Nitrogen_dioxide), max(datos_finales_limpios$air_quality_Nitrogen_dioxide), length.out = 30)
z_matrix <- outer(x_range, y_range, function(x1, x2) 66.03 + 8.38 * x1 + 12.5 * x2)

# 2. Definimos los puntos de tu estimación
x_val <- 30
y_val <- 15
z_val <- 66.03 + (8.38 * x_val) + (12.5 * y_val) # Esto da 504.93

# 3. Graficamos
fig <- plot_ly() %>%
  # El plano del modelo
  add_surface(x = x_range, y = y_range, z = z_matrix, 
              colorscale = list(c(0, 1), c("blue", "blue")), opacity = 0.5, showscale = FALSE) %>%
  # El punto de estimación resaltado
  add_markers(x = x_val, y = y_val, z = z_val, 
              marker = list(size = 10, color = "red", symbol = "diamond")) %>%
  layout(
    title = "Gráfico N°4: Modelo multiple, Observacion de la estimación 
para el análisis meteorológico en capitales del mundo
  Periodo: Mayo 2024 a Mayo 2026Estimación",
    scene = list(
      xaxis = list(title = "PM 2.5"),
      yaxis = list(title = "NO2"),
      zaxis = list(title = "CO")
    )
  )

fig

11.- Conclusiones

Entre el \(CO\), el \(PM_{2.5}\) y el \(NO_2\) (medidos en µg/m³), existe una relación de tipo lineal definida por la ecuación del plano \(Y = 66.03 + 8.38X_1 + 12.5X_2\).Esta relación presenta una correlación de Pearson de 0.7, lo que indica una correlación positiva moderada-fuerte. Asimismo, el coeficiente de determinación (\(R^2\)) es de 49% de la variabilidad del \(CO\), mientras que el 51% restante responde a factores externos