#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
#Cargar los datos 
datos <- read.csv("~/semestre 3 y 4/Estadistica/Datos Cambiados.csv",
                  header = TRUE, dec = ".", sep = ",")

#----------------------------------------
# Selección de variable
ozono<- datos$O3

# NOTA: Asumimos que la columna se llama 'O3'
ozono <- datos$O3[datos$O3 != "-"]

# Conversión a numérico
ozono <- as.numeric(ozono)


# Conteo para ozono
# Preparamos los datos que vamos a necesitar para realizar Sturges
# Regla de Sturges: k = 1 + 3.322 * log10(n)
# A = R/K
# =========================================================

# Tamaño de muestra
n <- length(ozono)

# Valor mínimo y máximo
min_ozono <- min(ozono, na.rm = TRUE)
max_ozono <- max(ozono, na.rm = TRUE)

# Rango
R <- max_ozono - min_ozono

# Número de intervalos (Regla de Sturges)
k_detallado <- ceiling(1 + 3.322 * log10(n))

# Amplitud de clase
A <- R / k_detallado

# Mostrar resultados
cat("Número de intervalos (k):", k_detallado, "\n")
## Número de intervalos (k): 16
cat("Amplitud de clase:", A, "\n")
## Amplitud de clase: 16.1075
# Generación de límites de intervalos
Li <- seq(from = min_ozono, to = max_ozono - A, by = A)
Ls <- c(seq(from = min_ozono + A, to = max_ozono - A, by = A), max_ozono)

# Redondeo
ozono <- round(ozono, 3)
Li <- round(Li, 3)
Ls <- round(Ls, 3)

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

# Frecuencias absolutas
ni <- numeric(length(Li))

for(i in 1:length(Li)){
  if(i < length(Li)){
    ni[i] <- sum(ozono >= Li[i] & ozono < Ls[i])
  } else {
    ni[i] <- sum(ozono >= Li[i] & ozono <= 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)))

# Intervalos
Intervalo <- paste0("[", round(Li, 2), " - ", round(Ls, 2), ")")

# Último intervalo cerrado
Intervalo[length(Intervalo)] <- paste0(
  "[",
  round(Li[length(Li)], 2),
  " - ",
  round(Ls[length(Ls)], 2),
  "]"
)

# Tabla de distribución de frecuencias
TDF_ozono <- 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)
)

# Fila de totales
totales <- data.frame(
  Intervalo = "Totales",
  MC = "-",
  ni = sum(ni),
  hi = round(sum(hi), 2),
  Ni_ascendente = "-",
  Ni_descendente = "-",
  Hi_ascendente = "-",
  Hi_descendente = "-"
)

# Tabla completa
TDF_ozono_completa <- rbind(TDF_ozono, totales)

#TABLA DE FRECUENCIAS DETALLADA

TDF_ozono_completa %>%
  gt() %>%
  tab_header(
    title = "Tabla Nro. 1",
    subtitle = "Distribución de frecuencia de concentración de Ozono (O3), estudio calidad del aire en India entre 2015-2020"
  ) %>%
  tab_source_note(
    source_note = md("Grupo: 1 <br> Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india ")
  ) %>%
  tab_style(
    style = cell_borders(sides = "left", color = "black", weight = px(2)),
    locations = cells_body()
  ) %>%
  tab_style(
    style = cell_borders(sides = "right", color = "black", weight = px(2)),
    locations = cells_body()
  ) %>%
  tab_style(
    style = cell_borders(sides = "left", color = "black", weight = px(2)),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style = cell_borders(sides = "right", color = "black", weight = px(2)),
    locations = cells_column_labels()
  ) %>%
  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 Ozono (O3), estudio calidad del aire en India entre 2015-2020
Intervalo MC ni hi Ni_ascendente Ni_descendente Hi_ascendente Hi_descendente
[0.01 - 16.12) 8.06 4880 19.13 4880 25509 19.13 100
[16.12 - 32.23) 24.17 8602 33.72 13482 20629 52.85 80.87
[32.23 - 48.33) 40.28 6518 25.55 20000 12027 78.4 47.15
[48.33 - 64.44) 56.39 3291 12.90 23291 5509 91.31 21.6
[64.44 - 80.55) 72.49 1298 5.09 24589 2218 96.39 8.69
[80.55 - 96.66) 88.6 521 2.04 25110 920 98.44 3.61
[96.66 - 112.76) 104.71 226 0.89 25336 399 99.32 1.56
[112.76 - 128.87) 120.82 96 0.38 25432 173 99.7 0.68
[128.87 - 144.98) 136.92 45 0.18 25477 77 99.87 0.3
[144.98 - 161.08) 153.03 19 0.07 25496 32 99.95 0.13
[161.08 - 177.19) 169.14 9 0.04 25505 13 99.98 0.05
[177.19 - 193.3) 185.25 1 0.00 25506 4 99.99 0.02
[193.3 - 209.41) 201.35 2 0.01 25508 3 100 0.01
[209.41 - 225.51) 217.46 0 0.00 25508 1 100 0
[225.51 - 241.62) 233.57 0 0.00 25508 1 100 0
[241.62 - 257.73] 249.68 1 0.00 25509 1 100 0
Totales - 25509 100.00 - - - -
Grupo: 1
Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india
# ==============================================================================
# Por una gran cantidad de intervalos se realizara una reducción de filas en la
# tabla Nro. 2 creando solo 10 intervalos
# ==============================================================================

# 1. Calculamos el rango y definimos la amplitud necesaria para 10 intervalos
min_oz <- floor(min(ozono, na.rm = TRUE))
max_oz <- ceiling(max(ozono, na.rm = TRUE))

# Redondeamos la amplitud hacia arriba para asegurar que cubra el rango en 10 pasos
A_ajustada <- ceiling((max_oz - min_oz) / 10)

# 2. Definimos los cortes (breaks) forzando los 10 intervalos
mis_breaks <- seq(from = min_oz, by = A_ajustada, length.out = 11)

# 3. Generamos el histograma con esos breaks
histo_ozono <- hist(ozono, breaks = mis_breaks, plot = FALSE)

# 4. Extraemos límites y calculamos estadísticas
Li2 <- histo_ozono$breaks[1:(length(histo_ozono$breaks)-1)]
Ls2 <- histo_ozono$breaks[2:length(histo_ozono$breaks)]

MC2 <- (Li2 + Ls2) / 2

ni2 <- histo_ozono$counts
hi2 <- (ni2 / sum(ni2)) * 100

Ni2_asc <- cumsum(ni2)
Hi2_asc <- cumsum(hi2)

Ni2_desc <- rev(cumsum(rev(ni2)))
Hi2_desc <- rev(cumsum(rev(hi2)))

# 5. Creamos los intervalos como texto
Intervalo2 <- paste0("[", Li2, " - ", Ls2, ")")

Intervalo2[length(Intervalo2)] <- paste0(
  "[",
  Li2[length(Li2)],
  " - ",
  Ls2[length(Ls2)],
  "]"
)

# 6. Construcción de la tabla
TDF_ozono_final <- data.frame(
  Intervalo = Intervalo2,
  MC = MC2,
  ni = ni2,
  hi = round(hi2, 2),
  Ni_asc = Ni2_asc,
  Hi_asc = round(Hi2_asc, 2),
  Ni_desc = Ni2_desc,
  Hi_desc = round(Hi2_desc, 2)
)

# 7. Totales
totaless <- data.frame(
  Intervalo = "Totales",
  MC = "-",
  ni = sum(ni2),
  hi = sum(hi2),
  Ni_asc = "-",
  Hi_asc = "-",
  Ni_desc = "-",
  Hi_desc = "-"
)

TDF_ozono_final <- rbind(TDF_ozono_final, totaless)

# 8. Tabla con gt()
TDF_ozono_final %>%
  gt() %>%
  tab_header(
    title = md("*Tabla Nro. 2*"),
    subtitle = md("*Distribución de frecuencia simplificada de concentración de Ozono (O3), estudio calidad del aire en India*")
  ) %>%
  tab_source_note(
    source_note = md("Autor: Grupo 1 <br> Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india")
  ) %>%
  tab_style(
    style = cell_borders(sides = c("left", "right"), color = "black", weight = px(2)),
    locations = cells_body()
  ) %>%
  tab_style(
    style = cell_borders(sides = c("left", "right"), color = "black", weight = px(2)),
    locations = cells_column_labels()
  ) %>%
  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 Ozono (O3), estudio calidad del aire en India
Intervalo MC ni hi Ni_asc Hi_asc Ni_desc Hi_desc
[0 - 26) 13 10183 39.92 10183 39.92 25509 100
[26 - 52) 39 10801 42.34 20984 82.26 15326 60.08
[52 - 78) 65 3493 13.69 24477 95.95 4525 17.74
[78 - 104) 91 759 2.98 25236 98.93 1032 4.05
[104 - 130) 117 200 0.78 25436 99.71 273 1.07
[130 - 156) 143 53 0.21 25489 99.92 73 0.29
[156 - 182) 169 16 0.06 25505 99.98 20 0.08
[182 - 208) 195 3 0.01 25508 100 4 0.02
[208 - 234) 221 0 0.00 25508 100 1 0
[234 - 260] 247 1 0.00 25509 100 1 0
Totales - 25509 100.00 - - - -
Autor: Grupo 1
Fuente: https://www.kaggle.com/datasets/rohanrao/air-quality-data-in-india
# ==============================================================================
# Histograma de Ozono con poligono de frecuencia 
hist(ozono,
     breaks = mis_breaks,
     main = "Gráfica Nro. 1\nHistograma con el polígono de frecuencias de Ozono\nen el estudio calidad del aire en India de 2015-2020",
     xlab = "Ozono (µg/m³)",
     ylab = "Cantidad",
     col = "lightsteelblue",
     xaxt = "n",
     cex.main = 0.9,
     ylim = c(0, max(histo_ozono$counts) * 1.1))

# Cuadrícula
abline(v = mis_breaks, col = "gray70", lty = 2, lwd = 0.8)
abline(h = axTicks(2), col = "gray70", lty = 2, lwd = 0.8)
# Redibujar histograma encima de la cuadrícula
hist(ozono,breaks = mis_breaks,col = "lightsteelblue",add = TRUE)
# Polígono de frecuencias
lines(MC2, ni2,
      type = "o",
      col = "red3",
      pch = 16,
      lwd = 2)

# Eje X personalizado
axis(1,at = mis_breaks,labels = round(mis_breaks, 0),las = 1,cex.axis = 0.9)

# ==============================================================================
# Histograma de Ozono generado por R Studio
# ==============================================================================
# 1. Creamos el histograma y guardamos la información
histo_ozono <- hist(ozono,breaks = mis_breaks,plot = FALSE)

# 2. Creamos el marco del gráfico
hist(ozono,
     breaks = mis_breaks,
     main = "Gráfica Nro. 2\nDistribución de frecuencias de concentración de Ozono\nen el estudio calidad del aire en India de 2015-2020",
     xlab = "Ozono (µg/m³)",
     ylab = "Cantidad",
     col = "darkseagreen3",
     ylim = c(0, max(histo_ozono$counts) * 1.1),
     xaxt = "n",
     cex.main = 0.9)

# 3. Agregamos las líneas de la cuadrícula
abline(v = mis_breaks,col = "gray70",lty = 2,lwd = 0.8)

abline(h = axTicks(2),col = "gray70",lty = 2,lwd = 0.8)

# 4. Redibujamos el histograma encima para que las barras queden al frente
hist(ozono,breaks = mis_breaks,col = "darkseagreen3",add = TRUE)

# 5. Creamos el eje X personalizado
axis(1,
     at = mis_breaks,
     labels = round(mis_breaks, 0),
     las = 1,
     cex.axis = 0.9)

#======================================================
#Histograma con relación a la totalidad de los datos
hist(ozono,
     breaks = mis_breaks,
     main = "Gráfica Nro. 3\nDistribución de frecuencias de concentración de Ozono\nen el estudio calidad del aire en India de 2015-2020",
     xlab = "Ozono (µg/m³)",
     ylab = "Cantidad",
     col = "darkseagreen3",
     ylim = c(0, length(ozono)),      # Eje Y desde 0 hasta el tamaño muestral
     xaxt = "n",
     cex.main = 0.9)

# 3. Agregamos las líneas de la cuadrícula
abline(v = mis_breaks,col = "gray70",lty = 2,lwd = 0.8)

abline(h = axTicks(2),col = "gray70",lty = 2,lwd = 0.8)

# 4. Redibujamos el histograma encima para que las barras queden al frente
hist(ozono,breaks = mis_breaks,col = "darkseagreen3",add = TRUE)

# Eje X personalizado
axis(1,
     at = mis_breaks,
     labels = round(mis_breaks, 0),
     las = 1,
     cex.axis = 0.9)

# ================================
# Histograma que genera r studio porcentual
plot(histo_ozono,
     freq = FALSE,
     main = "Gráfica Nro. 4\nDistribución porcentual de concentración de Ozono\nen el estudio calidad del aire en India de 2015-2020",
     xlab = "Ozono (µg/m³)",
     ylab = "Porcentaje ",
     xaxt = "n",
     cex.main = 1,
     ylim = c(0, max(hi2) * 1.1))

# Cuadrícula
abline(v = mis_breaks, col = "gray70", lty = 2, lwd = 0.8)
abline(h = axTicks(2), col = "gray70", lty = 2, lwd = 0.8)

# Barras porcentuales
rect(histo_ozono$breaks[-length(histo_ozono$breaks)],
     0,
     histo_ozono$breaks[-1],
     hi2, #hi2 es hi simplificado 
     col = "darkseagreen3",
     border = "black")

# Eje X personalizado
axis(1,
     at = mis_breaks,
     labels = round(mis_breaks, 0),
     las = 1,
     cex.axis = 0.9)

#=================================================
# Histograma porcentual con respecto al total
plot(histo_ozono,
     freq = FALSE,
     main = "Gráfica Nro. 5\nDistribución porcentual de concentración de Ozono\nen el estudio calidad del aire en India de 2015-2020",
     xlab = "Ozono (µg/m³)",
     ylab = "Porcentaje",
     xaxt = "n",
     cex.main = 1,
     ylim = c(0, 100))

# Cuadrícula
abline(v = mis_breaks, col = "gray70", lty = 2, lwd = 0.8)
abline(h = axTicks(2), col = "gray70", lty = 2, lwd = 0.8)

# Barras porcentuales
rect(histo_ozono$breaks[-length(histo_ozono$breaks)],
     0,
     histo_ozono$breaks[-1],
     hi2, # hi2 es hi simplificado
     col = "darkseagreen3",
     border = "black")

# Eje X personalizado
axis(1,
     at = mis_breaks,
     labels = round(mis_breaks, 0),
     las = 1,
     cex.axis = 0.9)

#=================================================
# Diagrama de caja de Ozono

boxplot(ozono,
        horizontal = TRUE,
        main = "Gráfica Nro. 6\nDiagrama de caja de la concentración de Ozono (O3)\nen el estudio calidad del aire en India de 2015-2020",
        xlab = "Ozono (µg/m³)",
        col = "turquoise",
        border = "black",
        cex.main = 0.9)

# Cuadrícula
abline(v = axTicks(1),
       col = "gray70",
       lty = 2,
       lwd = 0.8)