# Estadística Inferencial - Preparación de Datos
# Variable Cuantitativa Discreta (AQI)
# Autor: Ariel Chiluisa
# 0. CARGA DE LIBRERÍAS
library(gt)
## Warning: package 'gt' was built under R version 4.5.3
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.5.3
##
## 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(dplyr)
# 1. CARGA DE DATOS
datos <- read.csv(
"MAPA QGIS/Datos Cambiados.csv",
header = TRUE,
sep = ",",
dec = "."
)
# 2. SELECCIÓN Y LIMPIEZA DE LA VARIABLE AQI
AQI <- datos$AQI
AQI <- AQI[AQI != "-"]
AQI <- as.numeric(AQI)
AQI <- AQI[!is.na(AQI)]
# 3. EXTRACCIÓN DE FRECUENCIAS Y PROBABILIDAD
# Definición de límites numéricos
Li <- c(0, 100, 200, 300, 400, 500)
Ls <- c(100, 200, 300, 400, 500, max(AQI))
# Conteo de frecuencia absoluta (ni) usando tu lógica original
ni <- numeric(length(Li))
for(i in 1:length(Li)){
if(i < length(Li)){
ni[i] <- sum(AQI >= Li[i] & AQI < Ls[i])
} else {
ni[i] <- sum(AQI >= Li[i] & AQI <= Ls[i]) # El último intervalo se cierra
}
}
N <- sum(ni)
# Cálculo de frecuencia relativa porcentual (hi) y probabilidad p(s)
hi <- (ni / N) * 100
p_s <- ni / N # Esto es equivalente a hi/100
# Etiquetas de los intervalos en formato texto
Intervalo <- c(
"[0 - 100)",
"[100 - 200)",
"[200 - 300)",
"[300 - 400)",
"[400 - 500)",
paste0("[500 - ", max(AQI), "]")
)
# 4. CREACIÓN DE LA TABLA DE DISTRIBUCIÓN DE FRECUENCIAS (TDF)
# Ensamblamos el data frame solo con las 4 columnas requeridas
TDF_AQI_simplificada <- data.frame(
Intervalo = Intervalo,
ni = ni,
hi = round(hi, 2),
p_s = round(p_s, 2)
)
# Renombramos las columnas para que queden exactas a tu formato
colnames(TDF_AQI_simplificada) <- c("Intervalo", "ni", "hi(%)", "p(s)")
# Fila de totales corregida
totales <- data.frame(
Intervalo = "Totales",
ni = sum(ni),
hi = 100, # El total teórico siempre es 100%
p_s = 1 # El total teórico siempre es 1
)
colnames(totales) <- c("Intervalo", "ni", "hi(%)", "p(s)")
# Unimos los datos con la fila de totales
TDF_AQI_simplificada <- rbind(TDF_AQI_simplificada, totales)
# 5. APLICACIÓN DEL DISEÑO
TDF_AQI_simplificada %>%
gt() %>%
# --- ESTA ES LA LÍNEA NUEVA ---
fmt_number(
columns = c("hi(%)", "p(s)"),
decimals = 2
) %>%
# ------------------------------
tab_header(
title = md("*Tabla Nro. 1*"),
subtitle = md("**Distribución de frecuencia simplificada del Índice de Calidad del Aire (AQI), estudio calidad del aire en India entre 2015-2020**")
) %>%
tab_source_note(
source_note = md("Autor: Ariel Chiluisa\nFuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india")
) %>%
tab_options(
# Bordes horizontales superiores e inferiores
table.border.top.color = "black",
table.border.bottom.color = "black",
table.border.top.style = "solid",
table.border.bottom.style = "solid",
# Bordes de las cabeceras
column_labels.border.top.color = "black",
column_labels.border.bottom.color = "black",
column_labels.border.bottom.width = px(2),
heading.border.bottom.color = "black",
heading.border.bottom.width = px(2),
# Líneas internas horizontales
row.striping.include_table_body = TRUE,
table_body.hlines.color = "gray",
table_body.border.bottom.color = "black",
# Líneas verticales para los márgenes exteriores (Estilo SO2)
table.border.left.color = "black",
table.border.left.style = "solid",
table.border.left.width = px(1),
table.border.right.color = "black",
table.border.right.style = "solid",
table.border.right.width = px(1),
# Líneas verticales para separar las columnas internamente (Estilo SO2)
column_labels.vlines.color = "black",
column_labels.vlines.style = "solid",
column_labels.vlines.width = px(1),
table_body.vlines.color = "black",
table_body.vlines.style = "solid",
table_body.vlines.width = px(1)
)
| Tabla Nro. 1 |
| Distribución de frecuencia simplificada del Índice de Calidad del Aire (AQI), estudio calidad del aire en India entre 2015-2020 |
| Intervalo |
ni |
hi(%) |
p(s) |
| [0 - 100) |
9343 |
37.60 |
0.38 |
| [100 - 200) |
9009 |
36.25 |
0.36 |
| [200 - 300) |
2790 |
11.23 |
0.11 |
| [300 - 400) |
2359 |
9.49 |
0.09 |
| [400 - 500) |
804 |
3.24 |
0.03 |
| [500 - 2049] |
545 |
2.19 |
0.02 |
| Totales |
24850 |
100.00 |
1.00 |
| Autor: Ariel Chiluisa
Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india |
# 4. GRÁFICA DE DISTRIBUCIÓN DE FRECUENCIAS (GDF)
# Ajuste de márgenes para que los títulos y etiquetas largas no se corten
par(mar = c(5.1, 5.1, 4.1, 2.1))
# Usamos los vectores originales 'hi' e 'Intervalo' que calculamos en el Paso 3
# (antes de que se les añadiera la fila de "Totales")
porcentajes_plot <- hi
nombres_plot <- Intervalo
# Creamos el lienzo base y guardamos las posiciones X de las barras en la variable 'barras'
# (Esta variable 'barras' te servirá en el siguiente paso para centrar el modelo geométrico)
barras <- barplot(
height = porcentajes_plot,
names.arg = nombres_plot,
space = 0.4, # Espacio entre barras, crucial para variables discretas
col = "skyblue", # Color distinto al naranja del SO2 para diferenciar variables
border = "black",
main = "Gráfica N°1: Distribución porcentual del Índice de Calidad del Aire (AQI)\nen estudio calidad del aire en India, 2015-2020",
xlab = "Índice de Calidad del Aire (AQI)",
ylab = "Porcentaje (%)",
las = 1, # Valores del eje Y horizontales para fácil lectura
ylim = c(0, max(porcentajes_plot) * 1.15), # Espacio extra en el tope
cex.names = 0.85 # Ajusta el tamaño de los nombres de los intervalos
)
# Añadimos la cuadrícula horizontal (líneas guía)
abline(h = pretty(c(0, max(porcentajes_plot))), col = "gray70", lty = 2, lwd = 0.8)
# Truco estético: Volvemos a dibujar las barras encima usando add = TRUE
# Esto hace que las líneas grises de la cuadrícula queden por debajo del color, viéndose más profesional
barplot(
height = porcentajes_plot,
space = 0.4,
col = "skyblue",
border = "black",
add = TRUE, # Superpone sobre la cuadrícula
axes = FALSE, # Evita que se repinten los ejes y se vean borrosos
names.arg = rep("", length(nombres_plot)) # No repinta los nombres
)
# Borde exterior de la gráfica
box()

# 5. Conjetura
# Se conjetura que el Índice de Calidad del Aire (AQI), tratado aquí como una
# variable discreta, se ajusta a un modelo de probabilidad geométrica. Esto se
# justifica porque su diagrama de barras muestra que la mayor cantidad de datos
# se concentra en el extremo izquierdo (intervalos de menor contaminación, [0-200)),
# y la frecuencia decae drásticamente a medida que los valores del índice aumentan.
# Visualmente, representa el equivalente discreto de un decaimiento exponencial.
# 6. COMPARACIÓN DEL MODELO VS LA REALIDAD (Modelo Geométrico)
# A. Cálculo del parámetro del modelo geométrico (p)
# Mapeamos los 6 intervalos a valores discretos (0, 1, 2, 3, 4, 5)
x_mapped <- 0:5
# Usamos la probabilidad real en decimales (p_s original sin la fila de totales)
p_s_data <- hi / 100
# Calculamos la esperanza matemática (media) multiplicando x por su probabilidad
media_x <- sum(x_mapped * p_s_data)
# Calculamos el parámetro de probabilidad (p) del modelo geométrico
prob_geom <- 1 / (1 + media_x)
# B. Cálculo de las probabilidades esperadas (Teóricas)
# Usamos dgeom() para los primeros 5 intervalos (x = 0 a 4)
esperada_normal <- dgeom(0:4, prob = prob_geom)
# Para el último intervalo [500 - max], al ser la "cola" derecha, sumamos todo lo que falta
esperada_cola <- 1 - pgeom(4, prob = prob_geom)
# Unimos las probabilidades teóricas y las pasamos a porcentaje
hi_modelo <- c(esperada_normal, esperada_cola) * 100
# C. Creación de la matriz para la gráfica agrupada
# Unimos la realidad (hi) y el modelo (hi_modelo) en una tabla de 2 filas
datos_comparacion <- rbind(Realidad = hi, Modelo = hi_modelo)
# D. Generación de la Gráfica
par(mar = c(6.1, 4.1, 4.1, 2.1)) # Márgenes para acomodar los títulos
# Creamos el barplot agrupado
grafica_comp <- barplot(
datos_comparacion,
beside = TRUE, # ¡Esta es la clave para que salgan lado a lado!
names.arg = Intervalo[1:6], # Etiquetas del Eje X
col = c("blue", "red"), # Colores según la imagen de referencia
main = "Gráfica N° 2: Comparación de la Realidad vs el Modelo Geométrico\ndel Índice de Calidad del Aire (AQI) en India",
xlab = "Índice de Calidad del Aire (AQI)",
ylab = "Probabilidad (%)",
ylim = c(0, max(datos_comparacion) * 1.35), # Damos bastante espacio arriba para la leyenda
las = 1,
cex.names = 0.85
)
# Añadimos cuadrícula de fondo para mejor lectura
abline(h = pretty(c(0, max(datos_comparacion))), col = "gray80", lty = 2)
# Repintamos las barras para que queden sobre las líneas de la cuadrícula
barplot(
datos_comparacion,
beside = TRUE,
col = c("blue", "red"),
add = TRUE,
axes = FALSE,
names.arg = rep("", 6)
)
# E. Añadimos la leyenda horizontal en la parte superior (como en la foto)
legend(
"top",
legend = c("Realidad", "Modelo geométrico"),
fill = c("blue", "red"),
bty = "n", # "n" quita el borde de la caja
horiz = TRUE, # Hace que la leyenda sea horizontal
inset = c(0, 0),
cex = 0.9
)
# Cerramos con el borde exterior
box()

# 7. TEST DE BONDAD
# Rescatamos las probabilidades teóricas calculadas en el Paso 6
P_teorica <- c(esperada_normal, esperada_cola)
# --- TEST DE PEARSON ---
# Para Pearson mantenemos la estructura original del SO2 que usaba frecuencias absolutas
fo_pearson <- ni
fe_pearson <- N * P_teorica
Coef_Pearson <- cor(fo_pearson, fe_pearson) * 100
# Resultado de Pearson
cat("Coeficiente de Pearson (%):", round(Coef_Pearson, 2), "\n")
## Coeficiente de Pearson (%): 91.48
# --- TEST CHI-CUADRADO ---
# Total de datos
N_chi <- sum(ni)
# Frecuencia relativa observada (Aplicando la estructura de tu código SO2)
fo <- ni / N_chi
# Número de intervalos
k <- length(fo)
# Probabilidades teóricas esperadas (ya calculadas en el Paso 6)
fe <- P_teorica
# Chi-cuadrado calculado con frecuencias relativas
Chi_Calculado <- sum((fo - fe)^2 / fe)
# Grados de libertad
gl <- k - 1
# Valor crítico (α = 0.05)
Chi_Critico <- qchisq(0.95, df = gl)
# Resultados
cat("\nChi Calculado:", round(Chi_Calculado, 4), "\n")
##
## Chi Calculado: 0.0929
cat("Chi Crítico:", round(Chi_Critico, 4), "\n")
## Chi Crítico: 11.0705
# Decisión
if (Chi_Calculado < Chi_Critico) {
print("Evalua H0: El modelo geométrico es adecuado.")
} else {
print("Se rechaza H0: El modelo geométrico no es adecuado.")
}
## [1] "Evalua H0: El modelo geométrico es adecuado."
# 8. CÁLCULO DE PROBABILIDAD E INTERVALO DE CONFIANZA
# A. Cálculo de la probabilidad (AQI > 100 puntos)
# Un AQI > 100 suele indicar que el aire empieza a ser perjudicial.
prob_supera_100 <- 1 - dgeom(0, prob = prob_geom)
cat("Probabilidad de registrar un AQI mayor a 100:", round(prob_supera_100 * 100, 2), "%\n")
## Probabilidad de registrar un AQI mayor a 100: 52.63 %
# B. Intervalo de Confianza (Tabla)
# Calculamos la media real usando los datos originales limpios de AQI
media_aqi <- mean(AQI)
desviacion_aqi <- sd(AQI)
n_aqi <- length(AQI)
# Nivel de confianza del 95% (Z = 1.96)
error_aqi <- 1.96 * (desviacion_aqi / sqrt(n_aqi))
# ¡CORRECCIÓN ESTADÍSTICA!
# Redondeamos a 0 decimales porque el AQI es una variable DISCRETA
limite_inferior_aqi <- round(media_aqi - error_aqi, 0)
limite_superior_aqi <- round(media_aqi + error_aqi, 0)
tabla_intervalo_aqi <- data.frame(
Intervalo = paste0("P [", limite_inferior_aqi, " < µ < ", limite_superior_aqi, "] = 95%")
)
# Aplicamos el formato estético de tu plantilla gt()
tabla_intervalo_aqi %>%
gt() %>%
tab_header(
title = md("*Tabla Nro. 2*"),
subtitle = md("**Intervalo de confianza del Índice de Calidad del Aire (AQI)**")
) %>%
tab_source_note(
source_note = md("Autor: Ariel Chiluisa\nFuente: 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",
table.border.left.color = "black", table.border.left.style = "solid", table.border.left.width = px(1),
table.border.right.color = "black", table.border.right.style = "solid", table.border.right.width = px(1)
)
# 9. CONCLUSIÓN DEL ANÁLISIS
# Definimos el texto integrando automáticamente los valores generados enteros
texto_conclusion_aqi <- paste0(
"El análisis del Índice de Calidad del Aire (AQI) revela que la distribución de los datos se ajusta ",
"a un modelo geométrico (p = ", round(prob_geom, 3), "), validado matemáticamente mediante la prueba de Pearson (",
round(Coef_Pearson, 2), "%). Con un nivel de confianza del 95%, se estima que el promedio real de ",
"la calidad del aire en la región se sitúa entre los [", limite_inferior_aqi, " y ", limite_superior_aqi, "] puntos. ",
"Aunque existe una probabilidad del ", round(prob_supera_100 * 100, 2), "% de registrar un AQI perjudicial (>100), ",
"la gráfica demuestra una fuerte concentración de valores en los intervalos iniciales, indicando que ",
"la calidad del aire se mantiene en rangos aceptables la mayor parte del periodo estudiado (2015-2020)."
)
df_conclusion_aqi <- data.frame(Texto = texto_conclusion_aqi)
# Recuadro visual final de conclusión
df_conclusion_aqi %>%
gt() %>%
tab_header(
title = md("## **CONCLUSIÓN DEL ANÁLISIS**")
) %>%
tab_options(
column_labels.hidden = TRUE,
table.border.top.color = "black",
table.border.bottom.color = "black",
table.border.top.width = px(3),
table.border.bottom.width = px(3),
table.background.color = "#FDFEFE",
table.width = pct(90)
) %>%
tab_style(
style = list(
cell_text(align = "justify", size = px(15), font = "Arial"),
cell_borders(sides = c("left", "right", "top", "bottom"), color = "#A6ACAF", weight = px(1.5))
),
locations = cells_body()
)
CONCLUSIÓN DEL ANÁLISIS
|
| El análisis del Índice de Calidad del Aire (AQI) revela que la distribución de los datos se ajusta a un modelo geométrico (p = 0.474), validado matemáticamente mediante la prueba de Pearson (91.48%). Con un nivel de confianza del 95%, se estima que el promedio real de la calidad del aire en la región se sitúa entre los [165 y 168] puntos. Aunque existe una probabilidad del 52.63% de registrar un AQI perjudicial (>100), la gráfica demuestra una fuerte concentración de valores en los intervalos iniciales, indicando que la calidad del aire se mantiene en rangos aceptables la mayor parte del periodo estudiado (2015-2020). |