UNIVERSIDAD CENTRAL DEL ECUADOR

PROYECTO:ESTUDIO ESTADÍSTICO DE LA CALIDAD DEL AIRE EN LA INDIA

FECHA: 27/11/2025

# ==============================================================================
# CONFIGURACIÓN Y PREPARACIÓN DE DATOS
# ==============================================================================

# Carga de Datos (Tu ruta de archivo)
# ¡ADVERTENCIA!: Cambia esta ruta si estás en otro equipo o entorno
TDFAQI<-read.csv("C:/Users/JOSELYN/Desktop/kangle/Datos Cambiados.csv", header = TRUE)

# 1. Preparación de Datos: Convertir a numérico y limpiar NAs
AQI_limpio <- as.numeric(TDFAQI$AQI)
AQI_limpio <- AQI_limpio[!is.na(AQI_limpio)]

# 2. Agrupación: CREACIÓN DE LOS INTERVALOS DE CLASE
numero_intervalos <- 6
breaks_limpios <- pretty(AQI_limpio, n = numero_intervalos)
grupos_AQI <- cut(AQI_limpio,
                  breaks = breaks_limpios,
                  include.lowest = TRUE,
                  right = FALSE)

# *** MODIFICACIÓN CLAVE PARA ELIMINAR NOTACIÓN CIENTÍFICA ***
etiquetas_de_intervalos <- levels(grupos_AQI)
options(scipen = 999) # Desactiva la notación científica

etiquetas_modificadas <- sapply(etiquetas_de_intervalos, function(etiqueta) {
  limites <- regmatches(etiqueta, gregexpr("-?\\d+\\.?\\d*(?:[Ee][+-]?\\d+)?", etiqueta))[[1]]
  
  if (length(limites) > 0) {
    limites_formateados <- format(as.numeric(limites), scientific = FALSE, trim = TRUE)
    nueva_etiqueta <- etiqueta
    for (i in 1:length(limites)) {
      nueva_etiqueta <- sub(limites[i], limites_formateados[i], nueva_etiqueta, fixed = TRUE)
    }
    return(nueva_etiqueta)
  } else {
    return(etiqueta)
  }
})

levels(grupos_AQI) <- as.character(etiquetas_modificadas)
options(scipen = 0)
# ***************************************************************

# 3. Cálculo de Frecuencias (ni)
tabla_frecuencia <- as.data.frame(table(grupos_AQI))

# 4. Asignación de Variables
AQI <- tabla_frecuencia$grupos_AQI
ni <- tabla_frecuencia$Freq

# 5. Cálculos Derivados
hi <- ni / sum(ni) * 100
Ni_asc <- cumsum(ni)
Ni_dsc <- rev(cumsum(rev(ni)))
Hi_asc <- round(cumsum(hi), 2)
Hi_dsc <- round(rev(cumsum(rev(hi))), 2)

# 6. Crear la Tabla de Distribución de Frecuencias Agrupadas
TDFAQIFin_Agrupada <- data.frame(AQI, ni, hi, Ni_asc, Ni_dsc, Hi_asc, Hi_dsc)

# 1. Calcular los totales
total_ni <- sum(ni)
total_hi <- sum(hi)

# 2. Agregar la fila 'Total'
TDFAQICompleto <- rbind(TDFAQIFin_Agrupada,
                        data.frame(AQI = "Total",
                                   ni = total_ni,
                                   hi = total_hi,
                                   Ni_asc = NA,
                                   Ni_dsc = NA,
                                   Hi_asc = NA,
                                   Hi_dsc = NA))

print(TDFAQICompleto)
##           AQI    ni           hi Ni_asc Ni_dsc Hi_asc Hi_dsc
## 1     [0,500) 24305 9.780684e+01  24305  24850  97.81 100.00
## 2  [500,1000)   452 1.818913e+00  24757    545  99.63   2.19
## 3 [1000,1500)    77 3.098592e-01  24834     93  99.94   0.37
## 4 [1500,2000)    15 6.036217e-02  24849     16 100.00   0.06
## 5 [2000,2500]     1 4.024145e-03  24850      1 100.00   0.00
## 6       Total 24850 1.000000e+02     NA     NA     NA     NA
# ==============================================================================
# GENERACIÓN DE TABLA GT (Tabla Nro. 1: TDF)
# ==============================================================================

if(!require(gt)) install.packages("gt"); library(gt)
if(!require(dplyr)) install.packages("dplyr"); library(dplyr)

TDFAQICompleto %>%
  gt() %>%
  
  # Etiquetas de columna explícitas para evitar errores de caracteres
  cols_label(
    AQI = "AQI (Intervalos)",
    ni = "ni (Frec. Absoluta)",
    hi = "hi (%)",
    Ni_asc = "Ni (Frec. Acumulada Asc.)",
    Ni_dsc = "Ni (Frec. Acumulada Desc.)",
    Hi_asc = "Hi (Frec. Acumulada % Asc.)",
    Hi_dsc = "Hi (Frec. Acumulada % Desc.)"
  ) %>%
  
  fmt_number(
    columns = c(hi, Hi_asc, Hi_dsc),
    decimals = 2
  ) %>%
  
  tab_header(
    title = md("**Tabla Nro. 1**"),
    subtitle = md("Tabla de distribución de frecuencias de los niveles de **AQI**")
  ) %>%
  
  tab_source_note(
    source_note = md("Fuente: Datos procesados por el autor a partir de archivo city.day.csv")
  ) %>%
  
  # Estilos de Bordes (Laterales)
  tab_style(
    style = cell_borders(sides = "left", color = "black", weight = px(2), style = "solid"),
    locations = cells_body()
  ) %>%
  tab_style(
    style = cell_borders(sides = "right", color = "black", weight = px(2), style = "solid"),
    locations = cells_body()
  ) %>%
  tab_style(
    style = cell_borders(sides = "left", color = "black", weight = px(2), style = "solid"),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style = cell_borders(sides = "right", color = "black", weight = px(2), style = "solid"),
    locations = cells_column_labels()
  ) %>%
  
  # Opciones de Estilos (Bordes Superiores e Inferiores, Rayado de Filas)
  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
Tabla de distribución de frecuencias de los niveles de AQI
AQI (Intervalos) ni (Frec. Absoluta) hi (%) Ni (Frec. Acumulada Asc.) Ni (Frec. Acumulada Desc.) Hi (Frec. Acumulada % Asc.) Hi (Frec. Acumulada % Desc.)
[0,500) 24305 97.81 24305 24850 97.81 100.00
[500,1000) 452 1.82 24757 545 99.63 2.19
[1000,1500) 77 0.31 24834 93 99.94 0.37
[1500,2000) 15 0.06 24849 16 100.00 0.06
[2000,2500] 1 0.00 24850 1 100.00 0.00
Total 24850 100.00 NA NA NA NA
Fuente: Datos procesados por el autor a partir de archivo city.day.csv
# ==============================================================================
# GRÁFICOS PERSONALIZADOS (ACOPLES PARA AQI)
# ==============================================================================

# Ajuste de márgenes para etiquetas largas
par(mar = c(8, 6, 4, 2))

# Diagrama de barras local (Frecuencia Absoluta: ni) 
barplot(TDFAQIFin_Agrupada$ni,
        main="Gráfica N°1: Distribución de Frecuencia Absoluta de los niveles de AQI\nen India entre 2015-2020",
        xlab = "Intervalos de AQI",
        ylab = "Frecuencia Absoluta (Días)",
        col = "blue",
        ylim = c(0,max(TDFAQIFin_Agrupada$ni)),
        names.arg = TDFAQIFin_Agrupada$AQI,
        las=2,
        cex.names=0.6,
        cex.axis = 0.7,
        cex.main = 0.9,
        mgp = c(5, 1 , 0))
mtext("*Los intervalos tienen límite inferior cerrado y superior abierto",
      side = 1, line = 6, adj = 0, cex = 0.7)

# Diagrama de barras local (Frecuencia Relativa: hi)
par(mar = c(8, 6, 4, 2))
barplot(TDFAQIFin_Agrupada$hi,
        main="Gráfica N°2: Distribución Porcentual de los niveles de AQI\nen India entre 2015-2020",
        xlab = "Intervalos de AQI",
        ylab = "Porcentaje (%)",
        col = "lightblue",
        names.arg = TDFAQIFin_Agrupada$AQI,
        las=2,
        cex.names=0.6,
        cex.axis = 0.9,
        cex.main = 0.9,
        mgp = c(5, 1, 0))

# Diagrama de barras global (Frecuencia Absoluta: ni)
par(mar = c(8, 6, 4, 2))
barplot(TDFAQIFin_Agrupada$ni,
        main="Gráfica N°3: Frecuencia Absoluta GLOBAL de los niveles de AQI\nen India entre 2015-2020",
        xlab = "Intervalos de AQI",
        ylab = "Frecuencia Absoluta (Días)",
        col = "lightgreen",
        ylim = c(0, sum(TDFAQIFin_Agrupada$ni)),
        names.arg = TDFAQIFin_Agrupada$AQI,
        las=2,
        cex.names=0.6,
        cex.axis = 0.9,
        cex.main = 0.9,
        mgp = c(5, 1, 0))

# Diagrama de barras global (Frecuencia Relativa: hi)
par(mar = c(8, 6, 4, 2))
barplot(TDFAQIFin_Agrupada$hi,
        main="Gráfica N°4: Distribución Porcentual GLOBAL de los niveles de AQI\nen India entre 2015-2020",
        xlab = "Intervalos de AQI",
        ylab = "Porcentaje (%)",
        col = "green",
        ylim = c(0,100),
        names.arg = TDFAQIFin_Agrupada$AQI,
        las=2,
        cex.names=0.6,
        cex.axis = 0.9,
        cex.main = 0.9,
        mgp = c(5, 1, 0))

# Diagrama de Caja (Boxplot) - Usa la variable AQI_limpio 
par(mar = c(4, 6, 4, 2))
boxplot(AQI_limpio,
        horizontal = TRUE,
        main = "Gráfica N°5: Distribución de los niveles de AQI\nen India entre 2015-2020",
        xlab = "Niveles de AQI",
        col = "turquoise",
        pch = 1)

# Diagrama de Ojiva Absoluta (Ni_asc y Ni_dsc)
par(mar = c(9, 6, 4, 2))
x_pos <- 1:length(TDFAQIFin_Agrupada$AQI)
plot(x_pos , TDFAQIFin_Agrupada$Ni_dsc,
     main = "Gráfica N°6: Ojiva de Frecuencia Absoluta de los niveles de AQI\nen India 2015-2020",
     xlab = "Intervalos de AQI",
     ylab = "Frecuencia Absoluta Acumulada (Ni)",
     col = "orange",
     type = "o",
     lwd = 3,
     xaxt="n",
     mgp = c(5, 1, 0),
     ylim = c(0, max(TDFAQIFin_Agrupada$Ni_asc)))

lines(x_pos, TDFAQIFin_Agrupada$Ni_asc,
      col = "green",
      type = "o",
      lwd = 3)
axis(side = 1, at = x_pos, labels = TDFAQIFin_Agrupada$AQI,
     las = 2, cex.axis = 0.6)
legend("bottomleft",
       legend = c("Ojiva Descendente (Ni_dsc)", "Ojiva Ascendente (Ni_asc)"),
       col = c("orange", "green"), pch = 1, cex = 0.7, lwd = 3)

# Diagrama de Ojiva Porcentual (Hi_asc y Hi_dsc) 
par(mar = c(9, 6, 4, 2))
x_por <- 1:length(TDFAQIFin_Agrupada$AQI)
plot(x_pos, TDFAQIFin_Agrupada$Hi_dsc,
     main = "Gráfica N°7: Ojiva de Frecuencia Porcentual de los niveles de AQI\nen India 2015-2020",
     xlab = "Intervalos de AQI",
     ylab = "Porcentaje Acumulado (%)",
     col = "red",
     type = "o",
     mgp = c(5, 1, 0),
     lwd = 2,
     xaxt="n",
     ylim = c(0, 100))
lines(x_pos, TDFAQIFin_Agrupada$Hi_asc,
      col = "blue",
      type = "o",
      lwd = 3)
axis(side = 1, at = x_pos, labels = TDFAQIFin_Agrupada$AQI,
     las = 2, cex.axis = 0.6)
legend("bottomleft",
       legend = c("Ojiva Descendente (Hi_dsc)", "Ojiva Ascendente (Hi_asc)"),
       col = c("red", "blue"), pch = 1, cex = 0.7, lwd = 3)

# ==============================================================================
# 8. CÁLCULO DE INDICADORES ESTADÍSTICOS (AQI) Y TABLA GT (Tabla Nro. 3)
# ==============================================================================

if(!require(e1071)) install.packages("e1071"); library(e1071)
library(gt)
library(dplyr)

# --- Indicadores de Tendencia Central
Me <- median(AQI_limpio)
X <- mean(AQI_limpio)
Mo <- names(sort(table(AQI_limpio), decreasing = TRUE))[1]

# --- Indicadores de Dispersión
sd_calc <- sd(AQI_limpio)
CV <- (sd_calc / X) * 100

# --- Indicadores de Forma
As <- skewness(AQI_limpio, type = 2)
K <- kurtosis(AQI_limpio, type = 2)

# --- Variables de Resumen para la Tabla
Variable <- "AQI (Nivel de Calidad del Aire)"
Rango <- paste0("[", round(min(AQI_limpio), 2), ", ", round(max(AQI_limpio), 2), "]")

# ************************************************
# CÁLCULO DE VALORES ATÍPICOS EN EL FORMATO DESEADO
# ************************************************
boxplot_stats <- boxplot.stats(AQI_limpio)
outliers <- boxplot_stats$out

if (length(outliers) > 0) {
  conteo_outliers <- length(outliers)
  min_outlier <- round(min(outliers), 0)
  max_outlier <- round(max(outliers), 0)
  # Formato: "Conteo,[Min_Outlier,Max_Outlier]"
  valoresatipicos_calc <- paste0(conteo_outliers, ",[", min_outlier, ",", max_outlier, "]")
} else {
  valoresatipicos_calc <- "Ninguno"
}
# ************************************************

# --- Creación del Data Frame de Indicadores (Tabla Nro. 3)
Tabla_indicadores <- data.frame(
  Variable,
  Rango,
  round(X, 2),
  round(Me, 2),
  Mo,
  round(sd_calc, 2),
  round(CV, 2),
  round(As, 2),
  round(K, 2),
  valoresatipicos_calc
)

# Nombres de las columnas
colnames(Tabla_indicadores) <- c("Variable","Rango","Media (X)", "Mediana (Me)", "Moda (Mo)","Desv. Est. (sd)","CV (%)","Asimetría (As)","Curtosis (K)","Valores Atípicos")

# --- Generación de la Tabla GT (Tabla Nro. 3: Indicadores)
Tabla_indicadores %>%
  gt() %>%
  tab_header(
    title = md("*Tabla Nro. 3*"),
    subtitle = md("**Indicadores Estadísticos de los Niveles de AQI en India (2015-2020)**")
  ) %>%
  tab_source_note(
    source_note = md("Fuente: Datos procesados por el autor a partir de archivo city.day.csv")
  ) %>%
  fmt_number(
    columns = c(`Media (X)`, `Mediana (Me)`, `Desv. Est. (sd)`, `CV (%)`, `Asimetría (As)`, `Curtosis (K)`),
    decimals = 2
  ) %>%
  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
Indicadores Estadísticos de los Niveles de AQI en India (2015-2020)
Variable Rango Media (X) Mediana (Me) Moda (Mo) Desv. Est. (sd) CV (%) Asimetría (As) Curtosis (K) Valores Atípicos
AQI (Nivel de Calidad del Aire) [13, 2049] 166.46 118.00 102 140.70 84.52 3.40 21.42 1358,[399,2049]
Fuente: Datos procesados por el autor a partir de archivo city.day.csv