title: “ESTUDIO ESTADÍSTICO DE LA CALIDAD DEL AIRE EN INDIA” output: html_notebook — # UNIVERSIDAD CENTRAL DEL ECUADOR ### PROYECTO:ESTUDIO ESTADÍSTICO DE LA CALIDAD DEL AIRE EN INDIA ### FECHA: 21/11/2025

# ========================================================
# ESTADÍSTICA Inferencial
# Ariana Viteri
# 04/01/2025
# ========================================================
# 1. CARGA DE PAQUETES Y DATOS
library(gt)
library(dplyr)

# Carga de datos
# El archivo ya está cargado en el entorno
datos <- read.csv("~/ariana tercer semestre/Estadistica/city_day.csv", # ¡ATENCIÓN! Ruta cambiada para usar el archivo cargado.
                  header = TRUE,
                  sep = ",",
                  dec = ".")
# ==============================================================================
# 2. PREPARACIÓN Y LIMPIEZA DE DATOS DE MATERIA PARTICULADA PM2.5
# ==============================================================================

# Extracción de los "-" (valores inexistentes) de la variable PM2.5
# Usando la notación de corchetes con el nombre de la columna que contiene el punto
pm25 <- datos$PM2.5[datos$PM2.5 != "-"]

# Tamaño muestral después de la limpieza
cat("Tamaño muestral de la Materia Particulada PM2.5 (sin '-'):", length(pm25), "\n")
## Tamaño muestral de la Materia Particulada PM2.5 (sin '-'): 24933
# Conversión a numérico
pm25 <- as.numeric(pm25)

# ==============================================================================
# 3. CÁLCULOS PARA LA DISTRIBUCIÓN DE FRECUENCIAS DETALLADA (34 CLASES)
# ==============================================================================

N <- length(pm25)
min_pm25 <- min(pm25)
max_pm25 <- max(pm25)
R <- max_pm25 - min_pm25

# Número de clases (k): Se mantienen 34 clases para replicar la estructura original
k_detallado <- 34

# Amplitud de clase (A)
A <- R / k_detallado

# Generación de límites de intervalos
Li <- seq(from = min_pm25, to = max_pm25 - A, by = A)
Ls <- c(seq(from = min_pm25 + A, to = max_pm25 - A, by = A), max_pm25)

# Redondeo para cálculos de intervalos precisos
pm25 <- round(pm25, 3)
Li <- round(Li, 3)
Ls <- round(Ls, 3)

# Marcas de Clase (MC)
MC <- (Li + Ls) / 2

# Creación de frecuencias absolutas (ni)
ni <- numeric(length(Li))
for (i in 1:length(Li)) {
  if (i < length(Li)) {
    # Intervalo abierto por la derecha: [Li, Ls)
    ni[i] <- sum(pm25 >= Li[i] & pm25 < Ls[i])
  } else {
    # Último intervalo cerrado: [Li, Ls]
    ni[i] <- sum(pm25 >= Li[i] & pm25 <= Ls[i])
  }
}

# Frecuencias relativas y acumuladas
hi <- (ni / N) * 100
Ni_asc <- cumsum(ni)
Ni_desc <- rev(cumsum(rev(ni)))
Hi_asc <- cumsum(hi)
Hi_desc <- rev(cumsum(rev(hi)))

# Formatear la columna Intervalo
Intervalo <- paste0("[", round(Li, 2), " - ", round(Ls, 2), ")")
# Corregir el último intervalo para que sea cerrado
Intervalo[length(Intervalo)] <- paste0("[", round(Li[length(Li)], 2), " - ",
                                       round(Ls[length(Ls)], 2), "]")

# Crear el Data Frame (TDF)
TDF_pm25 <- data.frame(
  Intervalo = Intervalo,
  MC = round(MC, 2),
  ni = ni,
  hi = round(hi, 2),
  Ni_ascendente = Ni_asc,
  Ni_descendente = Ni_desc,
  Hi_ascendente = round(Hi_asc, 2),
  Hi_descendente = round(Hi_desc, 2)
)

# Agregar la fila de totales
totales <- data.frame(
  Intervalo = "Totales",
  MC = "-",
  ni = sum(ni),
  hi = sum(hi),
  Ni_ascendente = "-",
  Ni_descendente = "-",
  Hi_ascendente = "-",
  Hi_descendente = "-"
)
TDF_pm25_completa <- rbind(TDF_pm25, totales)

# ==============================================================================
# 4. TABLA DE FRECUENCIAS DETALLADA (Tabla Nro. 1)
# ==============================================================================

TDF_pm25_completa %>%
  gt() %>%
  tab_header(
    title = "Tabla Nro. 1",
    subtitle = "Distribución de frecuencia de concentración de Materia Particulada (PM2.5), estudio calidad del aire en India entre 2015-2020"
  ) %>%
  tab_source_note(
    source_note = "Autor: Grupo 2\n Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india"
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    table.border.top.style = "solid",
    table.border.bottom.style = "solid",
    column_labels.border.top.color = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    row.striping.include_table_body = TRUE,
    heading.border.bottom.color = "black",
    heading.border.bottom.width = px(2),
    table_body.hlines.color = "gray",
    table_body.border.bottom.color = "black"
  )
Tabla Nro. 1
Distribución de frecuencia de concentración de Materia Particulada (PM2.5), estudio calidad del aire en India entre 2015-2020
Intervalo MC ni hi Ni_ascendente Ni_descendente Hi_ascendente Hi_descendente
[0.04 - 27.98) 14.01 5946 23.85 5946 24933 23.85 100
[27.98 - 55.92) 41.95 8318 33.36 14264 18987 57.21 76.15
[55.92 - 83.86) 69.89 4831 19.38 19095 10669 76.59 42.79
[83.86 - 111.8) 97.83 2178 8.74 21273 5838 85.32 23.41
[111.8 - 139.74) 125.77 1159 4.65 22432 3660 89.97 14.68
[139.74 - 167.68) 153.71 753 3.02 23185 2501 92.99 10.03
[167.68 - 195.62) 181.65 533 2.14 23718 1748 95.13 7.01
[195.62 - 223.56) 209.59 370 1.48 24088 1215 96.61 4.87
[223.56 - 251.5) 237.53 284 1.14 24372 845 97.75 3.39
[251.5 - 279.44) 265.47 177 0.71 24549 561 98.46 2.25
[279.44 - 307.38) 293.41 122 0.49 24671 384 98.95 1.54
[307.38 - 335.32) 321.35 55 0.22 24726 262 99.17 1.05
[335.32 - 363.26) 349.29 59 0.24 24785 207 99.41 0.83
[363.26 - 391.2) 377.23 38 0.15 24823 148 99.56 0.59
[391.2 - 419.14) 405.17 25 0.10 24848 110 99.66 0.44
[419.14 - 447.08) 433.11 21 0.08 24869 85 99.74 0.34
[447.08 - 475.02) 461.04 17 0.07 24886 64 99.81 0.26
[475.02 - 502.96) 488.98 10 0.04 24896 47 99.85 0.19
[502.96 - 530.89) 516.92 6 0.02 24902 37 99.88 0.15
[530.89 - 558.83) 544.86 6 0.02 24908 31 99.9 0.12
[558.83 - 586.77) 572.8 4 0.02 24912 25 99.92 0.1
[586.77 - 614.71) 600.74 2 0.01 24914 21 99.92 0.08
[614.71 - 642.65) 628.68 2 0.01 24916 19 99.93 0.08
[642.65 - 670.59) 656.62 2 0.01 24918 17 99.94 0.07
[670.59 - 698.53) 684.56 2 0.01 24920 15 99.95 0.06
[698.53 - 726.47) 712.5 1 0.00 24921 13 99.95 0.05
[726.47 - 754.41) 740.44 1 0.00 24922 12 99.96 0.05
[754.41 - 782.35) 768.38 0 0.00 24922 11 99.96 0.04
[782.35 - 810.29) 796.32 0 0.00 24922 11 99.96 0.04
[810.29 - 838.23) 824.26 3 0.01 24925 11 99.97 0.04
[838.23 - 866.17) 852.2 1 0.00 24926 8 99.97 0.03
[866.17 - 894.11) 880.14 1 0.00 24927 7 99.98 0.03
[894.11 - 922.05) 908.08 5 0.02 24932 6 100 0.02
[922.05 - 949.99] 936.02 1 0.00 24933 1 100 0
Totales - 24933 100.00 - - - -
Autor: Grupo 2 Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india
# 1. CARGA DE PAQUETES Y DATOS (Replicado para integridad)
# ==============================================================================

# Cargar librerías necesarias
library(gt)
library(dplyr)

# Carga de datos
datos <- read.csv("~/ariana tercer semestre/Estadistica/city_day.csv",
                  header = TRUE,
                  sep = ",",
                  dec = ".")

# ==============================================================================
# 2. PREPARACIÓN Y LIMPIEZA DE DATOS DE MATERIA PARTICULADA PM2.5 (Replicado para integridad)
# ==============================================================================

# Extracción de los "-" (valores inexistentes) de la variable PM2.5
pm25 <- datos$PM2.5[datos$PM2.5 != "-"]
# Conversión a numérico
pm25 <- as.numeric(pm25)
# Redondeo para cálculos de intervalos precisos
pm25 <- round(pm25, 3)

# Definir N (Tamaño muestral)
N <- length(pm25)
min_pm25 <- min(pm25)
max_pm25 <- max(pm25)

# ==============================================================================
# 5. CÁLCULOS PARA LA DISTRIBUCIÓN SIMPLIFICADA (13 CLASES)
# ==============================================================================

# Se utiliza la función hist() para obtener los intervalos simplificados
Histograma_pm25 <- hist(pm25, breaks = 13, plot = FALSE) # No mostrar la gráfica aún

# Extraer elementos simplificados
Lis <- Histograma_pm25$breaks[1:(length(Histograma_pm25$breaks) - 1)]
Lss <- Histograma_pm25$breaks[2:length(Histograma_pm25$breaks)]
MCs <- (Lis + Lss) / 2
nis <- Histograma_pm25$counts

# Frecuencias relativas y acumuladas simplificadas
his <- (nis / N) * 100
Nis_asc <- cumsum(nis)
His_asc <- cumsum(his)
Nis_desc <- rev(cumsum(rev(nis)))
His_desc <- rev(cumsum(rev(his)))

# Crear el Data Frame Simplificado
TDF_pm25simplificado <- data.frame(
  Intervalo = paste0("[", round(Lis, 2), " - ", round(Lss, 2), ")"),
  MC = round(MCs, 2),
  ni = nis,
  hi = round(his, 2),
  Ni_asc = Nis_asc,
  Hi_asc = round(His_asc, 2),
  Ni_desc = Nis_desc,
  Hi_desc = round(His_desc, 2)
)

# Renombrar columnas con los nombres finales (usando comillas invertidas para % en R)
colnames(TDF_pm25simplificado) <- c("Intervalo", "MC", "ni", "hi(%)",
                                    "Ni_asc", "Hi_asc (%)", "Ni_desc", "Hi_desc (%)")

# Agregar la fila de totales (Usando nombres temporales para compatibilidad)
totaless <- data.frame(
  Intervalo = "Totales",
  MC = "-",
  ni = sum(nis),
  hi = sum(his),
  Ni_asc = "-",
  Hi_asc = "-",
  Ni_desc = "-",
  Hi_desc = "-"
)

# Asegurar que las columnas de totaless coincidan con los nombres finales
colnames(totaless) <- colnames(TDF_pm25simplificado)

# Unir los data frames
TDF_pm25simplificado_completa <- rbind(TDF_pm25simplificado, totaless)

# ==============================================================================
# 6. TABLA DE FRECUENCIAS SIMPLIFICADA (Tabla Nro. 2)
# ==============================================================================

TDF_pm25simplificado_completa %>%
  gt() %>%
  tab_header(
    title = "Tabla Nro. 2",
    # *** Título actualizado a PM2.5 ***
    subtitle = "Distribución de frecuencia simplificada de concentración de Materia Particulada (PM2.5), estudio calidad del aire en India entre 2015-2020"
  ) %>%
  tab_source_note(
    source_note = "Autor: Grupo 2\n Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india"
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    table.border.top.style = "solid",
    table.border.bottom.style = "solid",
    column_labels.border.top.color = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    row.striping.include_table_body = TRUE,
    heading.border.bottom.color = "black",
    heading.border.bottom.width = px(2),
    table_body.hlines.color = "gray",
    table_body.border.bottom.color = "black"
  )
Tabla Nro. 2
Distribución de frecuencia simplificada de concentración de Materia Particulada (PM2.5), estudio calidad del aire en India entre 2015-2020
Intervalo MC ni hi(%) Ni_asc Hi_asc (%) Ni_desc Hi_desc (%)
[0 - 100) 50 20516 82.28 20516 82.28 24933 100
[100 - 200) 150 3281 13.16 23797 95.44 4417 17.72
[200 - 300) 250 843 3.38 24640 98.82 1136 4.56
[300 - 400) 350 193 0.77 24833 99.6 293 1.18
[400 - 500) 450 63 0.25 24896 99.85 100 0.4
[500 - 600) 550 18 0.07 24914 99.92 37 0.15
[600 - 700) 650 6 0.02 24920 99.95 19 0.08
[700 - 800) 750 2 0.01 24922 99.96 13 0.05
[800 - 900) 850 6 0.02 24928 99.98 11 0.04
[900 - 1000) 950 5 0.02 24933 100 5 0.02
Totales - 24933 100.00 - - - -
Autor: Grupo 2 Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india
# Gráfica N°1
# ------------------------------------------------------------------------------

# Para esta gráfica, usaremos el 'hi(%)' de la tabla simplificada.
n <- as.numeric(nrow(TDF_pm25simplificado))
porcentajes <- TDF_pm25simplificado$`hi(%)`[1:(n-1)]
marcas_clase <- TDF_pm25simplificado$MC[1:(n-1)]

post <- barplot(porcentajes,
                space = 0,
                col = "skyblue",
                # *** Título actualizado a PM2.5 ***
                main = "Gr\u00E1fica N\u00B03: Distribuci\u00F3n Porcentual Global de PM2.5
                Estudio Calidad del Aire en India, 2015-2020",
                # *** Etiqueta del eje X actualizada a PM2.5 ***
                xlab = "PM2.5 (\u00B5g/m\u00B3)",
                ylab = "Porcentaje (%)",
                # Fijamos el límite Y entre 0 y 100
                ylim = c(0, 100), 
                cex.main = 0.9,
                cex.lab = 1,
                xaxt = "n",
                yaxt = "n") 

# Dibujamos las etiquetas del Eje X (Marca de Clase)
axis(side = 1,
     at = post,
     labels = marcas_clase,
     tck = -0.02, 
     las = 2,     
     cex.axis = 0.6) 

# Dibujamos las marcas del Eje Y
axis(side = 2,
     at = seq(0, 100, by = 20),
     las = 1,
     cex.axis = 0.9)

# 4. CONJETURA
# Se conjetura que la concentración de PM2.5 sigue un modelo de probabilidad exponencial, 
# ya que la variable en su histograma muestra que la mayor parte de los datos está concentrada 
# en el extremo izquierdo (bajos valores de PM2.5) y la frecuencia disminuye rápidamente 
# conforme aumentan los valores de PM2.5.

# 5. CÁLCULO DE PARÁMETROS DISTRIBUCIÓN EXPONENCIAL
# Media 
media <- mean(pm25)
media
## [1] 67.45058
# Lambda
lambda <- 1/media
lambda
## [1] 0.01482567
# 6. HISTOGRAMA densidad de probabilidad
breaks <- Histograma_pm25$breaks   # usamos los intervalos que ya calculaste antes

Histograma_pm25_exp <- hist(pm25,
                            breaks = breaks,
                            freq = FALSE,          
                            main = "Gráfica Nº2: Comparación modelo exponencial realidad concentración\n de PM2.5 en estudio calidad de aire India 2015-2020", 
                            xlab = "PM2.5 (µg/m3)",
                            ylab = "Densidad probabilidad ",
                            col = "grey", ylim = c(0,0.01), xaxt = "n"
)  

axis(1, at = breaks)

# Curva exponencial
curve(dexp(x, rate = lambda),
      from = 0, to = max(pm25),
      col = "orange", lwd = 2, add = TRUE)

# ========================================================
# 7. TEST DE BONDAD
# Test de Pearson
# ========================================================

# Frecuencias observadas por intervalo
fo <- hist(pm25, breaks = breaks, plot = FALSE)$counts
fo
##  [1] 20516  3281   843   193    63    18     6     2     6     5
n <- length(pm25)

# Probabilidades teóricas por intervalo (modelo exponencial)
p <- diff(pexp(breaks, rate = lambda))
p
##  [1] 7.729459e-01 1.755005e-01 3.984811e-02 9.047678e-03 2.054312e-03
##  [6] 4.664400e-04 1.059071e-04 2.404664e-05 5.459889e-06 1.239690e-06
# Frecuencias esperadas (Fe)
fe <- p * n
fe
##  [1] 1.927186e+04 4.375755e+03 9.935330e+02 2.255857e+02 5.122017e+01
##  [6] 1.162975e+01 2.640582e+00 5.995550e-01 1.361314e-01 3.090919e-02
# Correlación
Correlación <- cor(fo, fe) * 100
Correlación
## [1] 99.77409
# ========================================================
# Test Chi-cuadrado
# ========================================================

# Fo y Fe en porcentual
Fo_porcentual <- fo / n * 100
Fo_porcentual
##  [1] 82.284522520 13.159266835  3.381061244  0.774074520  0.252677175
##  [6]  0.072193479  0.024064493  0.008021498  0.024064493  0.020053744
Fe_porcentual <- p * 100
Fe_porcentual
##  [1] 7.729459e+01 1.755005e+01 3.984811e+00 9.047678e-01 2.054312e-01
##  [6] 4.664400e-02 1.059071e-02 2.404664e-03 5.459889e-04 1.239690e-04
x2 <- sum((Fo_porcentual - Fe_porcentual)^2 / Fe_porcentual)
x2
## [1] 5.803183
k <- length(Fo_porcentual)
grados_libertad <- k - 1
grados_libertad
## [1] 9
umbral_aceptacion <- qchisq(0.95, df = grados_libertad)
umbral_aceptacion
## [1] 16.91898
x2 < umbral_aceptacion
## [1] TRUE
# ========================================================
# 8. CÁLCULO DE PROBABILIDAD
# ¿Cuál es la probabilidad de que la concentración de PM2.5 supere 40 µg/m³?
# ========================================================

1 - pexp(40, rate = lambda)
## [1] 0.552652
# ========================================================
# DEMOSTRACIÓN GRÁFICA DE LA PROBABILIDAD
# ========================================================

# Rango de x para la curva
x <- seq(0, max(pm25), by = 0.001)
y <- dexp(x, rate = lambda)

# Calcular máximo para ajustar ylim
ylim_max <- max(y) * 1.1

# Graficar curva principal
plot(x, y, type = "l", col = "orange", lwd = 2, 
     xlim = c(0, max(pm25)), ylim = c(0, ylim_max),
     main = "Gráfica N°3: Cálculo de probabilidad",
     ylab = "Densidad de probabilidad", 
     xlab = "PM2.5 (µg/m3)", xaxt = "n")

# Área a sombrear (x >= 40)
x_section <- seq(40, max(pm25), by = 0.001)
y_section <- dexp(x_section, rate = lambda)

# Sombrear el área
polygon(c(x_section, rev(x_section)), 
        c(y_section, rep(0, length(y_section))),
        col = rgb(0, 1, 0, 0.5), border = NA)

# Dibujar línea verde sobre el área
lines(x_section, y_section, col = "green", lwd = 2)

# Leyenda
legend("topright", legend = c("Modelo", "Área de Probabilidad"), 
       col = c("orange", "green"), lwd = 2, lty = c(1, 1))

# Eje x
axis(1, at = seq(0, max(pm25), by = 50))

# ========================================================
# 9. INTERVALO DE CONFIANZA
# ========================================================

media <- mean(pm25)
sigma <- sd(pm25)
n <- length(pm25)

error <- 2 * (sigma / sqrt(n))

# Límites del intervalo de confianza
limite_inferior <- round(media - error, 2)
limite_superior <- round(media + error, 2)

# Crear tabla con intervalo (usando tus valores calculados)
tabla_intervalo <- data.frame(
  Intervalo = paste0("P [", limite_inferior, " < µ < ", limite_superior, "] = 95%")
)

tabla_intervalo %>%
  gt() %>%
  tab_header(
    title = md("*Tabla Nro. 3*"),
    subtitle = md("**Intervalo de confianza de la concentración de PM2.5, estudio calidad del aire en India entre 2015-2020**")
  ) %>%
  tab_source_note(
    source_note = md("Autor: Grupo 2\n Fuente:https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india")
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    table.border.top.style = "solid",
    table.border.bottom.style = "solid",
    column_labels.border.top.color = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    row.striping.include_table_body = TRUE,
    heading.border.bottom.color = "black",
    heading.border.bottom.width = px(2),
    table_body.hlines.color = "gray",
    table_body.border.bottom.color = "black"
  )
Tabla Nro. 3
Intervalo de confianza de la concentración de PM2.5, estudio calidad del aire en India entre 2015-2020
Intervalo
P [66.63 < µ < 68.27] = 95%
Autor: Grupo 2 Fuente:https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india