#Variable Cuantitativa Continua
#co
#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

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

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

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

2. CONTEO (FRECUENCIAS)

# ===== CÁLCULOS PARA LA TABLA DE DISTRIBUCIÓN DE FRECUENCIAS (TDF) =====
# Implementación de la fórmula de Sturges
min <- min(CO, na.rm = TRUE)
max <- max(CO, na.rm = TRUE)
R = max - min
k = 1 + (3.3) * log(length(CO))
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(CO >= Li[i] & CO < Ls[i], na.rm = TRUE)
  } else {
    ni[i] <- sum(CO >= Li[i] & CO <= 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_CO <- 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_CO <- rbind(TDF_CO, totales)


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

TDF_CO %>%
  gt() %>%
  
  # ===== ENCABEZADO =====
tab_header(
  title = md("## **Tabla Nro. 1**"),
  subtitle = md(
    "*Distribución de frecuencia de concentración de CO* *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 CO Estudio de calidad del aire en India (2015–2020)
Intervalo MC ni hi Ni_asc Ni_desc Hi_asc Hi_desc
[0 - 5.17) 2.59 25782 93.85 25782 27472 93.85 100
[5.17 - 10.34) 7.76 572 2.08 26354 1690 95.93 6.15
[10.34 - 15.51) 12.93 311 1.13 26665 1118 97.06 4.07
[15.51 - 20.68) 18.1 206 0.75 26871 807 97.81 2.94
[20.68 - 25.85) 23.27 131 0.48 27002 601 98.29 2.19
[25.85 - 31.03) 28.44 140 0.51 27142 470 98.8 1.71
[31.03 - 36.2) 33.61 84 0.31 27226 330 99.1 1.2
[36.2 - 41.37) 38.78 52 0.19 27278 246 99.29 0.9
[41.37 - 46.54) 43.95 49 0.18 27327 194 99.47 0.71
[46.54 - 51.71) 49.12 32 0.12 27359 145 99.59 0.53
[51.71 - 56.88) 54.29 18 0.07 27377 113 99.65 0.41
[56.88 - 62.05) 59.47 19 0.07 27396 95 99.72 0.35
[62.05 - 67.22) 64.64 13 0.05 27409 76 99.77 0.28
[67.22 - 72.39) 69.81 11 0.04 27420 63 99.81 0.23
[72.39 - 77.56) 74.98 6 0.02 27426 52 99.83 0.19
[77.56 - 82.73) 80.15 9 0.03 27435 46 99.87 0.17
[82.73 - 87.9) 85.32 5 0.02 27440 37 99.88 0.13
[87.9 - 93.08) 90.49 8 0.03 27448 32 99.91 0.12
[93.08 - 98.25) 95.66 4 0.01 27452 24 99.93 0.09
[98.25 - 103.42) 100.83 3 0.01 27455 20 99.94 0.07
[103.42 - 108.59) 106 1 0.00 27456 17 99.94 0.06
[108.59 - 113.76) 111.17 5 0.02 27461 16 99.96 0.06
[113.76 - 118.93) 116.34 3 0.01 27464 11 99.97 0.04
[118.93 - 124.1) 121.52 3 0.01 27467 8 99.98 0.03
[124.1 - 129.27) 126.69 0 0.00 27467 5 99.98 0.02
[129.27 - 134.44) 131.86 2 0.01 27469 5 99.99 0.02
[134.44 - 139.61) 137.03 1 0.00 27470 3 99.99 0.01
[139.61 - 144.78) 142.2 0 0.00 27470 2 99.99 0.01
[144.78 - 149.96) 147.37 1 0.00 27471 2 100 0.01
[149.96 - 155.13) 152.54 0 0.00 27471 1 100 0
[155.13 - 160.3) 157.71 0 0.00 27471 1 100 0
[160.3 - 165.47) 162.88 0 0.00 27471 1 100 0
[165.47 - 170.64) 168.05 0 0.00 27471 1 100 0
[170.64 - 175.81] 173.22 1 0.00 27472 1 100 0
Totales - 27472 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 arriba)
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
ni_simpl <- numeric(length(Li_simpl))
for (i in 1:length(Li_simpl)) {
  if (i < length(Li_simpl)) {
    ni_simpl[i] <- sum(CO >= Li_simpl[i] & CO < Ls_simpl[i], na.rm = TRUE)
  } else {
    ni_simpl[i] <- sum(CO >= Li_simpl[i] & CO <= 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
TDF_CO_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_CO_simpl <- rbind(TDF_CO_simpl, totales_simpl)

# ===== GENERACIÓN Y ESTILO DE LA TABLA NRO 2 (gt) =====
TDF_CO_simpl %>%
  gt() %>%
  
  # ===== ENCABEZADO =====
tab_header(
  title = md("## **Tabla Nro. 2**"),
  subtitle = md(
    "*Distribución de frecuencia simplificada de concentración de CO, 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 CO, estudio calidad del aire en India entre 2015-2020
Intervalo MC ni hi Ni_asc Ni_desc Hi_asc Hi_desc
[0 - 18) 9 26788 97.51 26788 27472 97.51 100
[18 - 36) 27 432 1.57 27220 684 99.08 2.49
[36 - 54) 45 148 0.54 27368 252 99.62 0.92
[54 - 72) 63 52 0.19 27420 104 99.81 0.38
[72 - 90) 81 24 0.09 27444 52 99.9 0.19
[90 - 108) 99 12 0.04 27456 28 99.94 0.1
[108 - 126) 117 11 0.04 27467 16 99.98 0.06
[126 - 144) 135 3 0.01 27470 5 99.99 0.02
[144 - 162) 153 1 0.00 27471 2 100 0.01
[162 - 180] 171 1 0.00 27472 1 100 0
Totales - 27472 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) ==============
# ====================================================================

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

hist(CO, 
     breaks = cortes_exactos,  
     main = "Gráfica Nro1: Distribución de la Concentración de CO\nEstudio sobre calidad del aire en India (2015-2020)",
     xlab = "CO (mg/m3)",
     ylab = "Días",
     col = "purple",        
     border = "black",
     xaxt = "n",                # Apagamos el eje X automático
     freq = TRUE)

# Dibujamos el eje X con los valores de nuestros 10 intervalos
axis(1, 
     at = cortes_exactos, 
     labels = cortes_exactos, 
     las = 1, 
     cex.axis = 0.8)

4.2. HISTOGRAMA GLOBAL

# ====================================================================
# ===== GRÁFICA GLOBAL (Con límite Y redondeado a 30,000) ============
# ====================================================================

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

hist(CO, 
     breaks = cortes_exactos,  
     main = "Gráfica Nro2: Distribución de la Concentración de CO\nEstudio sobre calidad del aire en India (2015-2020)",
     xlab = "CO (mg/m3)",
     ylab = "Días",
     ylim = c(0, 30000),           # Techo visual mantenido en 30000
     col = "lightblue",        
     border = "black",
     xaxt = "n",                   
     yaxt = "n",                   # Apagamos el eje Y automático
     freq = TRUE)

# Dibujamos nuestro eje X
axis(1, 
     at = cortes_exactos, 
     labels = cortes_exactos, 
     las = 1, 
     cex.axis = 0.8)

# NUEVO: Eje Y manual y redondeado hasta 30,000 (saltos de 5,000)
marcas_y <- seq(0, 30000, by = 5000)

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

4.3. HISTOGRAMA LOCAL PORCENTUAL

# ====================================================================
# ===== GRÁFICA PORCENTUAL (Con regleta de límites y números altos) ==
# ====================================================================

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

# Aseguramos tener los cortes listos (los límites exactos de los intervalos)
cortes_exactos <- c(Li_simpl, Ls_simpl[length(Ls_simpl)])

# 2. Generamos el diagrama (apagando el eje Y automático con yaxt = "n")
posiciones <- barplot(hi_simpl, 
                      main = "Gráfica Nro 3: Distribución Porcentual de CO\nEstudio sobre calidad del aire en India (2015-2020)",
                      ylab = "Días (%)",               # ← CAMBIO 1: Nueva etiqueta
                      xlab = "Concentración de CO (mg/m3)", 
                      ylim = c(0, max(hi_simpl) + 10), 
                      col = "#A9DFBF",
                      border = "black",
                      space = 0,                       
                      yaxt = "n",                      # ← CAMBIO 2: Apagamos el eje Y automático
                      las = 1)                         

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

# 4. NUEVO: Dibujamos el eje Y personalizado con el símbolo %
# Usamos la función pretty() para que R calcule saltos numéricos perfectos según tus datos
marcas_y_porc <- pretty(c(0, max(hi_simpl) + 10))

axis(2, 
     at = marcas_y_porc, 
     labels = paste0(marcas_y_porc, "%"),   # ← CAMBIO 3: Se le pega el "%" al número
     las = 1, 
     cex.axis = 0.8)

4.4. HISTOGRAMA GLOBAL PROCENTUAL

# ====================================================================
# ===== GRÁFICA PORCENTUAL GLOBAL ===
# ====================================================================

par(mar = c(5, 4, 4, 2) + 0.1)

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

# 1. Generamos el diagrama usando los DATOS REALES (ni_simpl) y el techo en 30,000
posiciones_global <- barplot(ni_simpl, 
                             main = "Gráfica Nro 4: Distribución Porcentual Global de CO\nEstudio sobre calidad del aire en India (2015-2020)",
                             ylab = " Dias (%)",
                             xlab = "Concentración de CO (mg/m3)", 
                             ylim = c(0, 30000),               # Techo real en 30,000 para alejar la gráfica
                             col = "lightblue",                
                             border = "black",
                             space = 0,                        
                             yaxt = "n",                       # Apagamos el Y de R
                             las = 1)                          

# 2. Dibujamos la "regleta" del eje X
axis(1, 
     at = 0:k_simpl,                  
     labels = cortes_exactos,         
     las = 1,                         
     cex.axis = 0.8)                  


# Las marcas reales van de 6,000 en 6,000 hasta 30,000
marcas_y_reales <- seq(0, 30000, by = 6000)
# Pero las etiquetas de texto van de 20 en 20 hasta 100%
etiquetas_y_porc <- c("0%", "20%", "40%", "60%", "80%", "100%")

axis(2, 
     at = marcas_y_reales,          # R pone la raya en el valor real 
     labels = etiquetas_y_porc,     # Pero escribe el porcentaje 
     las = 1,
     cex.axis = 0.8)

5. DIAGRAMA DE CAJA

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

# Restauramos los márgenes por defecto por si quedaron modificados de gráficas anteriores
par(mar = c(5, 4, 4, 2) + 0.1)

CajaCO <- boxplot(CO, 
                  horizontal = TRUE, 
                  col = "green", 
                  border = "black",
                  main = "Gráfica Nro 5: Distribución de la concentración de CO\nEstudio calidad del aire en India (2015-2020)",
                  xlab = "Concentración de CO (mg/m3)")

6. OJIVAS

6.1. OJIVAS (NI)

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

# 1. Ampliamos el margen izquierdo (el segundo número pasa de 4 a 5.5) 
# para que los números grandes no choquen con el título "Cantidad Acumulada"
par(mar = c(5, 5.5, 4, 2) + 0.1)

x <- Ls_simpl

# 2. 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 CO\nEstudio calidad del aire en India (2015-2020)",
  xlab = "Concentración de CO (mg/m3)",
  ylab = "Cantidad Acumulada (Días)",
  ylim = c(0, N_simpl),                
  las = 1,                             
  cex.main = 0.9,
  yaxt = "n"                           # Apagamos el eje Y automático
)

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

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

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

# 5. 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) ===
# ====================================================================

# 1. Ajustamos márgenes: Aumentamos el de abajo (6) y el de la izquierda (5)
# para que los números rotados y las etiquetas tengan suficiente espacio.
par(mar = c(6, 5, 4, 2) + 0.1)

x <- Ls_simpl

# 2. Dibujamos la primera gráfica (Ojiva Ascendente Porcentual - Naranja)
plot(
  x, Hi_asc_simpl,                     # Usamos Hi (Frecuencia relativa acumulada porcentual)
  type = "b",                          
  col = "orange",
  pch = 19,                            
  lwd = 2,                             # Líneas más gruesas para resaltar
  main = "Gráfica Nro 7: Ojiva Porcentual Local de Concentración de CO\nEstudio calidad del aire en India (2015-2020)",
  xlab = "",                           # Vacío para colocarlo manualmente abajo
  ylab = "Porcentaje Dias (%)",
  ylim = c(0, 100),                    # El techo es exactamente 100%
  xaxt = "n",                          # Apagamos el eje X automático
  yaxt = "n",                          # Apagamos el eje Y automático
  panel.first = grid(col = "lightgray", lty = 2)  # Cuadrícula de fondo
)

# 3. 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
)

# 4. 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 más abajo para que no choque con los números
mtext("Concentración de CO (mg/m3)", side = 1, line = 4.5, font = 1)

# 5. 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)

# 6. LEYENDA (Ubicada arriba a la derecha, estilo limpio sin recuadro)
legend("topright", 
       legend = c("Ascendente", "Descendente"),
       col = c("orange", "blue"),
       pch = 19,
       lty = 1,
       lwd = 2,
       bty = "n",                      # Quita el contorno de la caja
       cex = 0.9)

7. INDICADORES ESTADÍSTICOS

# ====================================================================
# ===== INDICADORES ESTADÍSTICOS Y TABLA RESUMEN =====================
# ====================================================================

# Cargar librerías necesarias
library(e1071)  # Requerida para calcular Asimetría (skewness) y Curtosis (kurtosis)
library(gt)
library(dplyr)

# --- Indicadores de Tendencia Central ---
X <- mean(CO)
Me <- median(CO)

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

# --- Indicadores de Dispersión ---
var_co <- var(CO)
desv <- sd(CO)
CV <- (desv / X) * 100


# --- Indicadores de Forma ---
As <- skewness(CO)
K <- kurtosis(CO)

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

# Rango exacto (Utiliza los valores Min y Max calculados para el CO en tu paso 1)
Rango <- paste0("[", min, " - ", max, "]")

# Identificación automática de valores atípicos usando la lógica del Boxplot
atipicos_reales <- boxplot.stats(CO)$out
valoresatipicos <- paste0(length(atipicos_reales), " atípicos (>", round(min(atipicos_reales), 2), ")")

# ===== CREACIÓN DEL DATA FRAME =====
Tabla_indicadores <- 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) <- 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 %>%
  gt() %>%
  
  # ===== ENCABEZADO =====
tab_header(
  title = md("## **Tabla Nro. 3**"),
  subtitle = md("*Indicadores Estadísticos de concentración de CO, 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(
    # 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.background.color = "#F4F6F7",
    
    # Columnas
    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),
    
    # Filas
    row.striping.include_table_body = TRUE,
    row.striping.background_color = "#F8F9F9",
    table_body.hlines.color = "#B3B6B7",
    table_body.border.bottom.color = "black"
  ) %>%
  
  # ===== ALINEACIÓN =====
cols_align(
  align = "center",
  columns = everything()
)

Tabla Nro. 3

Indicadores Estadísticos de concentración de CO, estudio calidad del aire en India entre 2015-2020
Variable Rango X Me Mo sd CV As K Valores atípicos
CO [0 - 175.81] 2.249 0.89 [0 - 18) 6.96 309.65 8.88 109.46 2475 atípicos (>2.87)
Autor: Grupo 1 Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india

8. CONCLUCIÓNES

# 1. Guardamos todo el texto en una variable de forma DINÁMICA
# (R insertará automáticamente los valores de CO, Me y Mo calculados previamente)
texto_conclusion <- paste0(
  "La variable cuantitativa CO fluctúa entre ", round(min(CO, na.rm = TRUE), 2), 
  " como valor mínimo y ", round(max(CO, na.rm = TRUE), 2), " mg/m3 como valor máximo, ",
  "girando en torno a niveles de concentración bajos (con una mediana de ", round(Me, 2), 
  " mg/m3 y el intervalo modal en ", Mo, "). Esto evidencia que las condiciones ",
  "diarias son generalmente favorables, reflejando una calidad del aire aceptable la ",
  "mayor parte del tiempo, aunque con la presencia de valores atípicos extremos ",
  "(picos episódicos) de alta contaminación que pueden generar severos impactos ",
  "en la salud respiratoria y el medio ambiente."
)

# 2. Lo convertimos en un pequeño Data Frame de una sola celda
df_conclusion <- data.frame(Texto = texto_conclusion)

# 3. Generamos el recuadro visual con gt
df_conclusion %>%
  gt() %>%
  
  # Añadimos el título del recuadro
  tab_header(
    title = md("## **CONCLUSIÓN DEL ANÁLISIS**")
  ) %>%
  
  # Configuramos la estética del recuadro
  tab_options(
    column_labels.hidden = TRUE,             # Ocultamos el nombre de la columna para que parezca un texto libre
    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",      # Fondo blanco limpio
    table.width = pct(90)                    # Ancho del recuadro
  ) %>%
  
  # Le damos estilo al texto (justificado, tamaño de letra y bordes)
  tab_style(
    style = list(
      cell_text(align = "justify", size = px(15), font = google_font("Poppins")),
      cell_borders(sides = c("left", "right", "top", "bottom"), color = "#A6ACAF", weight = px(1.5))
    ),
    locations = cells_body()
  )

CONCLUSIÓN DEL ANÁLISIS

La variable cuantitativa CO fluctúa entre 0 como valor mínimo y 175.81 mg/m3 como valor máximo, girando en torno a niveles de concentración bajos (con una mediana de 0.89 mg/m3 y el intervalo modal en [0 - 18)). Esto evidencia que las condiciones diarias son generalmente favorables, reflejando una calidad del aire aceptable la mayor parte del tiempo, aunque con la presencia de valores atípicos extremos (picos episódicos) de alta contaminación que pueden generar severos impactos en la salud respiratoria y el medio ambiente.