#Variable Cuantitativa Continua
#No
#Autor: Ariel chiluisa
#Fecha:31/05/2026

0.- Carga de Librerias

#Carga de Librerias

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(e1071)
## Warning: package 'e1071' was built under R version 4.5.3

1.- Carga de Datos

# ===== CARGA DE DATOS =====
datos <- read.csv("~/ariana tercer semestre/Estadistica/city_day.csv",
                  header = TRUE, dec = ".", sep = ";")

# ===== LIMPIEZA Y PREPARACIÓN DE LA VARIABLE NO =====
# Extracción de los "-" de la variable NO porque son valores inexistentes
NO <- datos$NO[datos$NO != "-"]

# Convertimos los datos a formato de números
NO <- as.numeric(NO)
length(NO)
## [1] 25949

2. CONTEO (FRECUENCIAS)

# ===== CÁLCULOS PARA LA TABLA DE DISTRIBUCIÓN DE FRECUENCIAS (TDF) =====
# Implementación de la fórmula de Sturges
min <- min(NO, na.rm = TRUE)
max <- max(NO, na.rm = TRUE)
R = max - min
k = 1 + (3.3) * log(length(NO))
k <- floor(k)
A <- R / k

# Generación de intervalos
Li <- seq(from = min, to = max - A, by = A)
Ls <- c(seq(from = min + A, to = max - A, by = A), max)  # último límite = max
MC <- (Li + Ls) / 2

# Creación de ni (frecuencia absoluta)
ni <- numeric(length(Li))
for (i in 1:length(Li)) {
  if (i < length(Li)) {
    ni[i] <- sum(NO >= Li[i] & NO < Ls[i], na.rm = TRUE)
  } else {
    ni[i] <- sum(NO >= Li[i] & NO <= Ls[i], na.rm = TRUE)  # Último intervalo cerrado
  }
}

# Creación de hi (frecuencia relativa en porcentaje)
N <- sum(ni)
hi <- (ni / N) * 100

# Creación de frecuencias acumuladas
Ni_asc <- cumsum(ni)
Ni_desc <- rev(cumsum(rev(ni)))
Hi_asc <- cumsum(hi)
Hi_desc <- rev(cumsum(rev(hi)))

# Formateo de los intervalos como texto
Intervalo <- paste0("[", round(Li, 2), " - ", round(Ls, 2), ")")
Intervalo[length(Intervalo)] <- paste0("[", round(Li[length(Li)], 2), " - ", 
                                       round(Ls[length(Ls)], 2), "]")

3. TABLA DE DISTRIBUCIÓN DE FRECUENCIA

3.1. TABLA GENERAL

# Creación del Data Frame principal
TDF_NO <- data.frame(
  Intervalo = Intervalo,
  MC = round(MC, 2),
  ni = ni,
  hi = round(hi, 2),
  Ni_asc = Ni_asc,
  Ni_desc = Ni_desc,
  Hi_asc = round(Hi_asc, 2),
  Hi_desc = round(Hi_desc, 2)
)

# Crear fila de totales
totales <- data.frame(
  Intervalo = "Totales",
  MC = "-",
  ni = sum(ni),
  hi = sum(hi),
  Ni_asc = "-",
  Ni_desc = "-",
  Hi_asc = "-",
  Hi_desc = "-"
)

# Agregar al final del data frame
TDF_NO <- rbind(TDF_NO, totales)


# ===== GENERACIÓN Y ESTILO DE LA TABLA (gt) =====
library(gt)
library(dplyr)

TDF_NO %>%
  gt() %>%
  
  # ===== ENCABEZADO =====
tab_header(
  title = md("## **Tabla Nro. 1**"),
  subtitle = md(
    "*Distribución de frecuencia de concentración de NO* *Estudio de calidad del aire en India (2015–2020)*"
  )
) %>%
  
  # ===== FUENTE =====
tab_source_note(
  source_note = md(
    "**Autor:** Grupo 1  
       **Fuente:** https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india"
  )
) %>%
  
  # ===== ESTILO GENERAL =====
opt_table_font(
  font = list(
    google_font("Poppins"),
    default_fonts()
  )
) %>%
  
  tab_options(
    # Bordes generales
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    table.border.top.width = px(3),
    table.border.bottom.width = px(3),
    
    # Encabezados
    heading.align = "center",
    heading.title.font.size = px(22),
    heading.subtitle.font.size = px(14),
    heading.background.color = "#F4F6F7",
    
    # Columnas
    column_labels.font.weight = "bold",
    column_labels.font.size = px(14),
    column_labels.background.color = "#D6EAF8",
    column_labels.border.top.color = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    
    # Filas
    table_body.hlines.color = "#B3B6B7",
    table_body.vlines.color = "#B3B6B7",   # ← líneas verticales
    table_body.border.bottom.color = "black",
    
    # Colores alternados
    row.striping.include_table_body = TRUE,
    row.striping.background_color = "#F8F9F9",
    
    # Fuente
    table.font.size = px(13),
    
    # Notas
    source_notes.font.size = px(11),
    source_notes.background.color = "#F4F6F7",
    
    # Espaciado
    data_row.padding = px(8)
  ) %>%
  
  # ===== BORDES VERTICALES COMPLETOS =====
tab_style(
  style = cell_borders(
    sides = c("left", "right"),
    color = "#A6ACAF",
    weight = px(1)
  ),
  locations = cells_body()
) %>%
  
  tab_style(
    style = cell_borders(
      sides = c("left", "right"),
      color = "black",
      weight = px(1.5)
    ),
    locations = cells_column_labels()
  ) %>%
  
  # ===== ALINEACIÓN =====
cols_align(
  align = "center",
  columns = everything()
)

Tabla Nro. 1

Distribución de frecuencia de concentración de NO Estudio de calidad del aire en India (2015–2020)
Intervalo MC ni hi Ni_asc Ni_desc Hi_asc Hi_desc
[0.02 - 11.51) 5.76 14740 56.80 14740 25949 56.8 100
[11.51 - 23) 17.25 5622 21.67 20362 11209 78.47 43.2
[23 - 34.49) 28.75 2369 9.13 22731 5587 87.6 21.53
[34.49 - 45.98) 40.24 1115 4.30 23846 3218 91.9 12.4
[45.98 - 57.47) 51.73 637 2.45 24483 2103 94.35 8.1
[57.47 - 68.96) 63.22 445 1.71 24928 1466 96.07 5.65
[68.96 - 80.45) 74.7 302 1.16 25230 1021 97.23 3.93
[80.45 - 91.94) 86.2 223 0.86 25453 719 98.09 2.77
[91.94 - 103.43) 97.68 138 0.53 25591 496 98.62 1.91
[103.43 - 114.92) 109.17 93 0.36 25684 358 98.98 1.38
[114.92 - 126.41) 120.67 82 0.32 25766 265 99.29 1.02
[126.41 - 137.9) 132.16 59 0.23 25825 183 99.52 0.71
[137.9 - 149.39) 143.64 31 0.12 25856 124 99.64 0.48
[149.39 - 160.88) 155.14 33 0.13 25889 93 99.77 0.36
[160.88 - 172.37) 166.62 14 0.05 25903 60 99.82 0.23
[172.37 - 183.86) 178.12 11 0.04 25914 46 99.87 0.18
[183.86 - 195.35) 189.61 6 0.02 25920 35 99.89 0.13
[195.35 - 206.84) 201.1 8 0.03 25928 29 99.92 0.11
[206.84 - 218.33) 212.58 4 0.02 25932 21 99.93 0.08
[218.33 - 229.82) 224.07 5 0.02 25937 17 99.95 0.07
[229.82 - 241.31) 235.56 0 0.00 25937 12 99.95 0.05
[241.31 - 252.8) 247.06 1 0.00 25938 12 99.96 0.05
[252.8 - 264.29) 258.54 0 0.00 25938 11 99.96 0.04
[264.29 - 275.78) 270.03 4 0.02 25942 11 99.97 0.04
[275.78 - 287.27) 281.52 1 0.00 25943 7 99.98 0.03
[287.27 - 298.76) 293.02 2 0.01 25945 6 99.98 0.02
[298.76 - 310.25) 304.5 1 0.00 25946 4 99.99 0.02
[310.25 - 321.74) 316 0 0.00 25946 3 99.99 0.01
[321.74 - 333.23) 327.48 0 0.00 25946 3 99.99 0.01
[333.23 - 344.72) 338.97 0 0.00 25946 3 99.99 0.01
[344.72 - 356.21) 350.46 1 0.00 25947 3 99.99 0.01
[356.21 - 367.7) 361.96 0 0.00 25947 2 99.99 0.01
[367.7 - 379.19) 373.44 0 0.00 25947 2 99.99 0.01
[379.19 - 390.68] 384.94 2 0.01 25949 2 100 0.01
Totales - 25949 100.00 - - - -
Autor: Grupo 1
Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india

3.2. TABLA SIMPLIFICADA

# ===== Proceso de simplificación de intervalos =====

# Forzamos a que existan 10 filas exactas
k_simpl <- 10
# Calculamos la nueva amplitud redondeada hacia arriba para no perder datos
A_simpl <- ceiling(R / k_simpl)
# Generación de los nuevos intervalos (usamos el 'min' original de la variable NO)
Li_simpl <- seq(from = floor(min), by = A_simpl, length.out = k_simpl)
Ls_simpl <- seq(from = floor(min) + A_simpl, by = A_simpl, length.out = k_simpl)
MC_simpl <- (Li_simpl + Ls_simpl) / 2

# Creación de ni (frecuencia absoluta) para la tabla 2 de NO
ni_simpl <- numeric(length(Li_simpl))
for (i in 1:length(Li_simpl)) {
  if (i < length(Li_simpl)) {
    ni_simpl[i] <- sum(NO >= Li_simpl[i] & NO < Ls_simpl[i], na.rm = TRUE)
  } else {
    ni_simpl[i] <- sum(NO >= Li_simpl[i] & NO <= Ls_simpl[i], na.rm = TRUE)
  }
}

# Creación de hi (frecuencia relativa) para la tabla 2
N_simpl <- sum(ni_simpl)
hi_simpl <- (ni_simpl / N_simpl) * 100

# Creación de frecuencias acumuladas para la tabla 2
Ni_asc_simpl <- cumsum(ni_simpl)
Ni_desc_simpl <- rev(cumsum(rev(ni_simpl)))
Hi_asc_simpl <- cumsum(hi_simpl)
Hi_desc_simpl <- rev(cumsum(rev(hi_simpl)))

# Formateo de los intervalos como texto (sin decimales)
Intervalo_simpl <- paste0("[", Li_simpl, " - ", Ls_simpl, ")")
Intervalo_simpl[length(Intervalo_simpl)] <- paste0("[", Li_simpl[length(Li_simpl)], " - ", Ls_simpl[length(Ls_simpl)], "]")

# Creación del Data Frame para la tabla simplificada de NO
TDF_NO_simpl <- data.frame(
  Intervalo = Intervalo_simpl,
  MC = MC_simpl,
  ni = ni_simpl,
  hi = round(hi_simpl, 2),
  Ni_asc = Ni_asc_simpl,
  Ni_desc = Ni_desc_simpl,
  Hi_asc = round(Hi_asc_simpl, 2),
  Hi_desc = round(Hi_desc_simpl, 2)
)

# Crear fila de totales
totales_simpl <- data.frame(
  Intervalo = "Totales",
  MC = "-",
  ni = sum(ni_simpl),
  hi = sum(hi_simpl),
  Ni_asc = "-",
  Ni_desc = "-",
  Hi_asc = "-",
  Hi_desc = "-"
)

# Unir la fila de totales a la nueva tabla
TDF_NO_simpl <- rbind(TDF_NO_simpl, totales_simpl)

# ===== GENERACIÓN Y ESTILO DE LA TABLA NRO 2 (gt) =====
TDF_NO_simpl %>%
  gt() %>%
  
  # ===== ENCABEZADO =====
tab_header(
  title = md("## **Tabla Nro. 2**"),
  subtitle = md(
    "*Distribución de frecuencia simplificada de concentración de NO, estudio calidad del aire en India entre 2015-2020*"
  )
) %>%
  
  # ===== FUENTE =====
tab_source_note(
  source_note = md(
    "**Autor:** Grupo 1  
       **Fuente:** https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india"
  )
) %>%
  
  # ===== ESTILO GENERAL =====
opt_table_font(
  font = list(
    google_font("Poppins"),
    default_fonts()
  )
) %>%
  
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    table.border.top.width = px(3),
    table.border.bottom.width = px(3),
    
    heading.align = "center",
    heading.title.font.size = px(22),
    heading.subtitle.font.size = px(14),
    heading.background.color = "#F4F6F7",
    
    column_labels.font.weight = "bold",
    column_labels.font.size = px(14),
    column_labels.background.color = "#D6EAF8",
    column_labels.border.top.color = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    
    table_body.hlines.color = "#B3B6B7",
    table_body.vlines.color = "#B3B6B7",
    table_body.border.bottom.color = "black",
    
    row.striping.include_table_body = TRUE,
    row.striping.background_color = "#F8F9F9",
    
    table.font.size = px(13),
    source_notes.font.size = px(11),
    source_notes.background.color = "#F4F6F7",
    data_row.padding = px(8)
  ) %>%
  
  # ===== BORDES VERTICALES COMPLETOS =====
tab_style(
  style = cell_borders(
    sides = c("left", "right"),
    color = "#A6ACAF",
    weight = px(1)
  ),
  locations = cells_body()
) %>%
  
  tab_style(
    style = cell_borders(
      sides = c("left", "right"),
      color = "black",
      weight = px(1.5)
    ),
    locations = cells_column_labels()
  ) %>%
  
  # ===== ALINEACIÓN =====
cols_align(
  align = "center",
  columns = everything()
)

Tabla Nro. 2

Distribución de frecuencia simplificada de concentración de NO, estudio calidad del aire en India entre 2015-2020
Intervalo MC ni hi Ni_asc Ni_desc Hi_asc Hi_desc
[0 - 40) 20 23347 89.97 23347 25949 89.97 100
[40 - 80) 60 1867 7.19 25214 2602 97.17 10.03
[80 - 120) 100 506 1.95 25720 735 99.12 2.83
[120 - 160) 140 169 0.65 25889 229 99.77 0.88
[160 - 200) 180 37 0.14 25926 60 99.91 0.23
[200 - 240) 220 11 0.04 25937 23 99.95 0.09
[240 - 280) 260 5 0.02 25942 12 99.97 0.05
[280 - 320) 300 4 0.02 25946 7 99.99 0.03
[320 - 360) 340 1 0.00 25947 3 99.99 0.01
[360 - 400] 380 2 0.01 25949 2 100 0.01
Totales - 25949 100.00 - - - -
Autor: Grupo 1
Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india

4. HISTOGRAMA

4.1. HISTOGRAMA LOCAL

# ===== GRÁFICA LOCAL (Eje Y automático generado por R - NO) =========


# Ajustamos márgenes para que los números del eje X rotados entren perfectamente
par(mar = c(6, 5, 4, 2) + 0.1)

# Aseguramos tener los cortes de los 10 intervalos simplificados listos para la variable NO
cortes_exactos <- c(Li_simpl, Ls_simpl[length(Ls_simpl)])

#  Dibujamos el histograma
hist(NO, 
     breaks = cortes_exactos,  
     main = "Gráfica Nro 1: Distribución de la Concentración de NO\nEstudio sobre calidad del aire en India (2015-2020)",
     xlab = "",                 # Lo dejamos vacío para colocarlo más abajo y que no choque
     ylab = "Días",
     col = "purple",        
     border = "black",
     xaxt = "n",                # Apagamos el eje X automático
     freq = TRUE,
     panel.first = grid(col = "lightgray", lty = 2) # Cuadrícula de fondo
)
## Warning in plot.window(xlim, ylim, log, ...): "panel.first" es un parámetro
## gráfico inválido
## Warning in title(main = main, sub = sub, xlab = xlab, ylab = ylab, ...):
## "panel.first" es un parámetro gráfico inválido
## Warning in axis(1, ...): "panel.first" es un parámetro gráfico inválido
## Warning in axis(2, at = yt, ...): "panel.first" es un parámetro gráfico
## inválido
# Dibujamos el eje X con los valores rotados a 90 grados (verticales)
axis(1, 
     at = cortes_exactos, 
     labels = cortes_exactos, 
     las = 2,                   # las = 2 rota las etiquetas verticalmente
     cex.axis = 0.8)

#  Colocamos el título del eje X manualmente más abajo
mtext("Concentración de NO (µg/m3)", side = 1, line = 4.5, font = 1)

4.2. HISTOGRAMA GLOBAL

# ====================================================================
# ===== GRÁFICA NRO 2: HISTOGRAMA (Con límite Y personalizado - NO) ===
# ====================================================================

# Ajustamos márgenes para dar espacio al texto vertical del eje X
par(mar = c(6, 5, 4, 2) + 0.1)

# Aseguramos tener los cortes de los 10 intervalos listos para la variable NO
cortes_exactos <- c(Li_simpl, Ls_simpl[length(Ls_simpl)])

# CALCULAMOS EL TECHO DEL EJE Y AUTOMÁTICAMENTE PARA EL NO
# Buscamos la frecuencia más alta y la redondeamos un poco hacia arriba para que respire la gráfica
max_frecuencia <- max(ni_simpl, na.rm = TRUE)
techo_y <- ceiling(max_frecuencia / 5000) * 5000  # Redondea al múltiplo de 5000 superior

# Dibujamos el histograma
hist(NO, 
     breaks = cortes_exactos,  
     main = "Gráfica Nro 2: Distribución de la Concentración de NO\nEstudio sobre calidad del aire en India (2015-2020)",
     xlab = "",                 # Vacío para colocarlo manualmente abajo
     ylab = "Días",
     ylim = c(0, techo_y),      # Techo visual adaptado dinámicamente para NO
     col = "lightblue",        
     border = "black",
     xaxt = "n",                    
     yaxt = "n",                # Apagamos el eje Y automático
     freq = TRUE,
     panel.first = grid(col = "lightgray", lty = 2) # Cuadrícula de fondo
)
## Warning in plot.window(xlim, ylim, log, ...): "panel.first" es un parámetro
## gráfico inválido
## Warning in title(main = main, sub = sub, xlab = xlab, ylab = ylab, ...):
## "panel.first" es un parámetro gráfico inválido
## Warning in axis(1, ...): "panel.first" es un parámetro gráfico inválido
## Warning in axis(2, at = yt, ...): "panel.first" es un parámetro gráfico
## inválido
#  Dibujamos nuestro eje X rotado a 90 grados (vertical)
axis(1, 
     at = cortes_exactos, 
     labels = cortes_exactos, 
     las = 2,                   # las = 2 gira las etiquetas verticalmente
     cex.axis = 0.8)

# Colocamos el título del eje X manualmente más abajo para que no choque con los números
mtext("Concentración de NO (µg/m3)", side = 1, line = 4.5, font = 1)

#  Eje Y manual con saltos cada 5,000 unidades hasta el techo calculado
marcas_y <- seq(0, techo_y, by = 5000)

axis(2, 
     at = marcas_y, 
     labels = marcas_y, 
     las = 1,
     cex.axis = 0.8)

4.3. HISTOGRAMA LOCAL PORCENTUAL

# ====================================================================
# ===== GRÁFICA NRO 3: DISTRIBUCIÓN PORCENTUAL (NO - FIJADO A 100%) ==
# ====================================================================

#  Ajustamos los márgenes ampliamente
par(mar = c(6, 5, 4, 2) + 0.1)

# Aseguramos tener los cortes listos
cortes_exactos <- c(Li_simpl, Ls_simpl[length(Ls_simpl)])

#  Generamos el diagrama (Forzamos el ylim exactamente a 100)
posiciones <- barplot(hi_simpl, 
                      main = "Gráfica Nro 3: Distribución Porcentual de NO\nEstudio sobre calidad del aire en India (2015-2020)",
                      ylab = "Días (%)",               
                      xlab = "",                       
                      ylim = c(0, 100),                # ← CORRECCIÓN: El techo visual ahora es 100%
                      col = "#A9DFBF",
                      border = "black",
                      space = 0,                       
                      xaxt = "n",                      
                      yaxt = "n",                      
                      las = 1)                         

# Creamos la cuadrícula de fondo adaptada al nuevo techo de 100
grid(nx = NA, ny = NULL, col = "lightgray", lty = 2)

# Dibujamos la "regleta" exacta (el eje X) rotada a 90 grados
axis(1, 
     at = 0:k_simpl,                  
     labels = cortes_exactos,         
     las = 2,                          
     cex.axis = 0.8)                  

# Colocamos el título del eje X manualmente
mtext("Concentración de NO (µg/m3)", side = 1, line = 4.5, font = 1)

# CORRECCIÓN: Eje Y manual con saltos exactos de 20% en 20% hasta el 100%
marcas_y_porc <- seq(0, 100, by = 20)

axis(2, 
     at = marcas_y_porc, 
     labels = paste0(marcas_y_porc, "%"),   
     las = 1, 
     cex.axis = 0.8)

4.4. HISTOGRAMA GLOBAL PROCENTUAL

# ====================================================================
# ===== GRÁFICA NRO 4: DISTRIBUCIÓN PORCENTUAL GLOBAL (NO) - AJUSTADA
# ====================================================================

par(mar = c(6, 5, 4, 2) + 0.1)
cortes_exactos <- c(Li_simpl, Ls_simpl[length(Ls_simpl)])

total_registros <- sum(ni_simpl)
techo_global_ficticio <- total_registros * 1.11  

# Definimos las posiciones Y (basadas en datos reales) y etiquetas (porcentajes)
marcas_y_proporcionales <- seq(0, total_registros, length.out = 6)
etiquetas_y_porc <- c("0%", "20%", "40%", "60%", "80%", "100%")

#  Generamos el barplot
posiciones_global <- barplot(ni_simpl, 
                             main = "Gráfica Nro 4: Distribución Porcentual Global de NO\nEstudio sobre calidad del aire en India (2015-2020)",
                             ylab = "Días (%)",
                             xlab = "",
                             ylim = c(0, techo_global_ficticio),
                             col = "lightblue", border = "black",
                             space = 0, xaxt = "n", yaxt = "n", las = 1)

#  DIBUJAMOS LA CUADRÍCULA MANUALMENTE PARA QUE COINCIDA CON EL EJE Y
# Esto dibuja una línea gris horizontal en cada marca de porcentaje
for(y in marcas_y_proporcionales) {
  abline(h = y, col = "lightgray", lty = 2)
}

#  Dibujamos los ejes
axis(1, at = 0:k_simpl, labels = cortes_exactos, las = 2, cex.axis = 0.8)
mtext("Concentración de NO (µg/m3)", side = 1, line = 4.5, font = 1)

axis(2, at = marcas_y_proporcionales, labels = etiquetas_y_porc, las = 1, cex.axis = 0.8)

5. DIAGRAMA DE CAJA

# ====================================================================
# ===== GRÁFICA NRO 5: DIAGRAMA DE CAJA (BOX PLOT - NO) ==============
# ====================================================================

# Restauramos los márgenes por defecto
par(mar = c(5, 4, 4, 2) + 0.1)

# Generamos el boxplot para la variable NO
CajaNO <- boxplot(NO, 
                  horizontal = TRUE, 
                  col = "lightgreen", # Un tono un poco más suave
                  border = "black",
                  main = "Gráfica Nro 5: Distribución de la concentración de NO\nEstudio calidad del aire en India (2015-2020)",
                  xlab = "Concentración de NO (µg/m3)")

6. OJIVAS

6.1. OJIVAS (NI)

# ====================================================================
# ===== GRÁFICA NRO 6: OJIVAS LOCALES (Diseño espaciado - NO) ========
# ====================================================================

#  Ampliamos el margen izquierdo para que los números grandes no choquen
par(mar = c(5, 5.5, 4, 2) + 0.1)

# Usamos los límites superiores de los intervalos simplificados de NO
x <- Ls_simpl

#  Dibujamos la primera gráfica (Ojiva Ascendente - Naranja)
plot(
  x, Ni_asc_simpl,                     
  type = "b",                          
  col = "orange",
  pch = 19,                            
  main = "Gráfica Nro 6: Distribución Acumulada (Ojivas) de NO\nEstudio calidad del aire en India (2015-2020)",
  xlab = "Concentración de NO (µg/m3)", # Unidad actualizada
  ylab = "Cantidad Acumulada (Días)",
  ylim = c(0, N_simpl),                
  las = 1,                             
  cex.main = 0.9,
  yaxt = "n"                           # Apagamos el eje Y automático
)

#  Superponemos la segunda línea (Ojiva Descendente - Azul)
lines(
  x, Ni_desc_simpl,                    
  type = "b",
  col = "blue",
  pch = 19
)

#  Dibujamos un eje Y limpio y automático
# pretty() calculará marcas perfectas según tu N_simpl de NO
marcas_y_ojiva <- pretty(c(0, N_simpl))

axis(2, 
     at = marcas_y_ojiva, 
     labels = marcas_y_ojiva, 
     las = 1, 
     cex.axis = 0.8)

#  Agregamos la leyenda
legend("right",                        
       legend = c("Ascendente (Ojiva Menor que)", "Descendente (Ojiva Mayor que)"),
       col = c("orange", "blue"),
       pch = 19,                       
       lty = 1,                        
       bty = "n",                      
       cex = 0.8)

6.2. OJIVAS (HI)

# ====================================================================
# ===== GRÁFICA NRO 7: OJIVAS PORCENTUALES (Frecuencias Relativas - NO)
# ====================================================================

#  Ajustamos márgenes (abajo 6, izquierda 5)
par(mar = c(6, 5, 4, 2) + 0.1)

# Usamos los límites superiores de los intervalos simplificados
x <- Ls_simpl

#  Dibujamos la primera gráfica (Ojiva Ascendente Porcentual - Naranja)
plot(
  x, Hi_asc_simpl,                     # Usamos frecuencias relativas porcentuales (Hi)
  type = "b",                          
  col = "orange",
  pch = 19,                            
  lwd = 2,                             
  main = "Gráfica Nro 7: Ojiva Porcentual Local de Concentración de NO\nEstudio calidad del aire en India (2015-2020)",
  xlab = "",                           # Vacío para colocarlo manualmente
  ylab = "Porcentaje Días (%)",
  ylim = c(0, 100),                    # Techo en 100%
  xaxt = "n",                          # Apagamos ejes automáticos
  yaxt = "n",                          
  panel.first = grid(col = "lightgray", lty = 2) # Cuadrícula de fondo
)

#  Superponemos la segunda línea (Ojiva Descendente Porcentual - Azul)
lines(
  x, Hi_desc_simpl,                    # Versión descendente de Hi
  type = "b",
  col = "blue",
  pch = 19,
  lwd = 2
)

# EJE X ROTADO A 90 GRADOS (Vertical)
axis(1, 
     at = x, 
     labels = x, 
     las = 2,                          # Texto vertical
     cex.axis = 0.9)

# Colocamos el título del eje X manualmente
mtext("Concentración de NO (µg/m3)", side = 1, line = 4.5, font = 1)

# EJE Y LIMPIO CON SÍMBOLO % (Saltos de 20% en 20%)
marcas_y_porc_ojiva <- seq(0, 100, by = 20)
axis(2, 
     at = marcas_y_porc_ojiva, 
     labels = paste0(marcas_y_porc_ojiva, "%"), 
     las = 1, 
     cex.axis = 0.9)

# LEYENDA (Estilo limpio sin recuadro)
legend("right",                        # Ubicado a la derecha para no tapar el cruce de las ojivas
       legend = c("Ascendente", "Descendente"),
       col = c("orange", "blue"),
       pch = 19,
       lty = 1,
       lwd = 2,
       bty = "n",                      # Sin contorno
       cex = 0.9)

7. INDICADORES ESTADÍSTICOS

# ====================================================================
# ===== INDICADORES ESTADÍSTICOS Y TABLA RESUMEN (NO) ================
# ====================================================================

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

# --- Indicadores de Tendencia Central ---
X <- mean(NO, na.rm = TRUE)
Me <- median(NO, na.rm = TRUE)

# Para la Moda en datos agrupados, usamos el intervalo con mayor frecuencia de la variable NO
Mo <- Intervalo_simpl[which.max(ni_simpl)] 

# --- Indicadores de Dispersión ---
var_no <- var(NO, na.rm = TRUE)
desv <- sd(NO, na.rm = TRUE)
CV <- (desv / X) * 100

# --- Indicadores de Forma ---
As <- skewness(NO, na.rm = TRUE)
K <- kurtosis(NO, na.rm = TRUE)

# --- Datos dinámicos para la tabla ---
Variable <- "NO"

# Rango exacto (Utiliza los valores Min y Max calculados para el NO)
min_no <- min(NO, na.rm = TRUE)
max_no <- max(NO, na.rm = TRUE)
Rango <- paste0("[", round(min_no, 2), " - ", round(max_no, 2), "]")

# Identificación automática de valores atípicos
atipicos_reales <- boxplot.stats(NO)$out
valoresatipicos <- paste0(length(atipicos_reales), " atípicos (>", round(min(atipicos_reales), 2), ")")

# ===== CREACIÓN DEL DATA FRAME =====
Tabla_indicadores_NO <- data.frame(
  Variable = Variable,
  Rango = Rango,
  X = round(X, 3),
  Me = round(Me, 2),
  Mo = Mo,
  sd = round(desv, 2),
  CV = round(CV, 2),
  As = round(As, 2),
  K = round(K, 2),
  valoresatipicos = valoresatipicos
)

colnames(Tabla_indicadores_NO) <- c("Variable", "Rango", "X", "Me", "Mo", "sd", "CV", "As", "K", "Valores atípicos")

# ===== GENERACIÓN Y ESTILO DE LA TABLA NRO 3 (gt) =====
Tabla_indicadores_NO %>%
  gt() %>%
  
  # ===== ENCABEZADO =====
tab_header(
  title = md("## **Tabla Nro. 3**"),
  subtitle = md("*Indicadores Estadísticos de concentración de NO, estudio calidad del aire en India entre 2015-2020*")
) %>%
  
  # ===== FUENTE =====
tab_source_note(
  source_note = md("**Autor:** Grupo 1\n**Fuente:** https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india")
) %>%
  
  # ===== ESTILO GENERAL =====
opt_table_font(
  font = list(
    google_font("Poppins"),
    default_fonts()
  )
) %>%
  
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    table.border.top.width = px(3),
    table.border.bottom.width = px(3),
    heading.align = "center",
    heading.background.color = "#F4F6F7",
    column_labels.font.weight = "bold",
    column_labels.background.color = "#D6EAF8",
    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,
    row.striping.background_color = "#F8F9F9",
    table_body.hlines.color = "#B3B6B7",
    table_body.border.bottom.color = "black"
  ) %>%
  
  cols_align(
    align = "center",
    columns = everything()
  )

Tabla Nro. 3

Indicadores Estadísticos de concentración de NO, estudio calidad del aire en India entre 2015-2020
Variable Rango X Me Mo sd CV As K Valores atípicos
NO [0.02 - 390.68] 17.575 9.89 [0 - 40) 22.79 129.65 3.88 25.16 2459 atípicos (>41.44)
Autor: Grupo 1 Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india

8. CONCLUCIÓNES

Conclusión

Conclusión
El análisis de la concentración de NO (µg/m3) en la India durante el periodo 2015-2020 revela un comportamiento altamente asimétrico, con una media de 17.57 y una mediana de 9.89 . La moda se concentra en el intervalo [0 - 40) . Dada la presencia significativa de valores atípicos, se observa una distribución con un sesgo positivo marcado. Estos niveles de concentración indican una calidad del aire con variaciones críticas, siendo necesario el monitoreo constante para la mitigación de impactos ambientales adversos.