# Tema: Estadística Descriptiva
# Autor: Camila Zambrano
# Fecha: 26/05/2026

0.- Carga de librerias

library(knitr)
library(kableExtra)
library(readr)
library(gt)
## Warning: package 'gt' was built under R version 4.5.3
library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following object is masked from 'package:kableExtra':
## 
##     group_rows
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union

1.- Leer datos

setwd("~/Camila/Estadística")
datos <- read.csv("Datos cambiados..csv",
                  header = TRUE, 
                  sep = ",", dec = "." )

2.- Selección de la variable

# Limpiar variable
datos$NO2[datos$NO2 == "-"] <- NA
datos$NO2 <- as.numeric(datos$NO2)

# Eliminar NA
dioxido_nitrogeno <- na.omit(datos$NO2)
dioxido_nitrogeno <- dioxido_nitrogeno[dioxido_nitrogeno >= 0]

# Tamaño muestral
n <- length(dioxido_nitrogeno)
n
## [1] 25946

3.- Conteo (frecuencia)

Construcción manual (Regla de Sturges)

# Parámetros
minimo <- min(dioxido_nitrogeno)
maximo <- max(dioxido_nitrogeno)

R <- maximo - minimo
K <- floor(1 + 3.322 * log10(n))
A <- R / K

# Límites 
Li <- round(seq(from = minimo, to = maximo, length.out = K), 2)
Ls <- c(Li[-1], round(maximo,2))

# Marca de clase
Mc <- (Li + Ls)/2

# Frecuencia absoluta
ni <- numeric(K)

for (i in 1:K) {
  if (i < K) {
    ni[i] <- sum(dioxido_nitrogeno >= Li[i] & 
                   dioxido_nitrogeno < Ls[i])
  } else {
    ni[i] <- sum(dioxido_nitrogeno >= Li[i] & 
                   dioxido_nitrogeno <= Ls[i])
  }
}

# Frecuencia relativa
hi <- round((ni / sum(ni)) * 100, 2)
hi[length(hi)] <- round(
  100 - sum(hi[-length(hi)]),
  2
)

# Frecuencia acumuladas 
Ni_asc <- cumsum(ni)
Ni_dsc <- rev(cumsum(rev(ni)))
Hi_asc <- round(cumsum(hi), 2)
Hi_dsc <- round(rev(cumsum(rev(hi))), 2)

4.- Tabla de distribución de frecuencia

4.1 Tabla general

TDF_dioxido_nitrogeno <-data.frame(Li, Ls,
                                Mc, ni,
                                hi,Ni_asc,
                                Ni_dsc,
                                Hi_asc,
                                Hi_dsc)

# Totales
total_ni <- sum(ni)
total_hi <- sum(hi)

# Agregra fila total
TDF_dioxido_nitrogeno_completo <- rbind(
  TDF_dioxido_nitrogeno,
  data.frame(
    Li = "Total",
    Ls = "-",
    Mc = "-",
    ni = total_ni,
    hi = total_hi,
    Ni_asc = "-",
    Ni_dsc = "-",
    Hi_asc = "-",
    Hi_dsc = "-"
  )
)

# Redondeo
TDF_dioxido_nitrogeno_completo$hi <- round(
  as.numeric(TDF_dioxido_nitrogeno_completo$hi),
  2
)

tabla_dioxido_nitrogeno <- TDF_dioxido_nitrogeno_completo %>%
  gt() %>%
  
  fmt_number(
    columns = hi,
    decimals = 2
  ) %>%
  
  tab_header(
    title = md("*Tabla Nº1*"),
    subtitle = md(
      "**Distribución de frecuencia de Dióxiodo de Nitrógeno en el análisis
      sobre la calidad del aire en India 2015-2020**"
    )
  ) %>%
  
  tab_source_note(
    source_note = md("Autor: Grupo 1")
  ) %>%
  
  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"
  ) %>%
  
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_body(
      rows = Li == "Total"
    )
  )

tabla_dioxido_nitrogeno
Tabla Nº1
Distribución de frecuencia de Dióxiodo de Nitrógeno en el análisis sobre la calidad del aire en India 2015-2020
Li Ls Mc ni hi Ni_asc Ni_dsc Hi_asc Hi_dsc
0.01 25.88 12.945 15044 57.98 15044 25946 57.98 100
25.88 51.75 38.815 7462 28.76 22506 10902 86.74 42.02
51.75 77.62 64.685 2325 8.96 24831 3440 95.7 13.26
77.62 103.5 90.56 676 2.61 25507 1115 98.31 4.3
103.5 129.37 116.435 249 0.96 25756 439 99.27 1.69
129.37 155.24 142.305 94 0.36 25850 190 99.63 0.73
155.24 181.11 168.175 56 0.22 25906 96 99.85 0.37
181.11 206.98 194.045 18 0.07 25924 40 99.92 0.15
206.98 232.85 219.915 11 0.04 25935 22 99.96 0.08
232.85 258.72 245.785 6 0.02 25941 11 99.98 0.04
258.72 284.6 271.66 3 0.01 25944 5 99.99 0.02
284.6 310.47 297.535 1 0.00 25945 2 99.99 0.01
310.47 336.34 323.405 0 0.00 25945 1 99.99 0.01
336.34 362.21 349.275 0 0.00 25945 1 99.99 0.01
362.21 362.21 362.21 1 0.01 25946 1 100 0.01
Total - - 25946 100.00 - - - -
Autor: Grupo 1

4.2 Tabla simplificada

histograma_simplificado <- hist(
  dioxido_nitrogeno,
  breaks = 10,
  plot = FALSE
)

# Límites y frecuencias simplificadas independientes
Limites_simp <- histograma_simplificado$breaks

Li_simp <- Limites_simp[1:(length(Limites_simp)-1)]
Ls_simp <- Limites_simp[2:length(Limites_simp)]

Mc_simp <- histograma_simplificado$mids
ni_simp <- histograma_simplificado$counts

hi_simp <- ni_simp/sum(ni_simp)*100
hi_simp <- round(hi_simp, 2)
hi_simp[length(hi_simp)] <- round(
  100 - sum(hi_simp[-length(hi_simp)]),
  2
)

Ni_asc_simp <- cumsum(ni_simp)
Ni_dsc_simp <- rev(cumsum(rev(ni_simp)))

Hi_asc_simp <- cumsum(hi_simp)
Hi_dsc_simp <- rev(cumsum(rev(hi_simp)))
Hi_asc_simp <- round(Hi_asc_simp, 2)
Hi_dsc_simp <- round(Hi_dsc_simp, 2)
Hi_asc_simp[length(Hi_asc_simp)] <- 100
Hi_dsc_simp[1] <- 100

# Tabla
TDF_completa <- data.frame(
  Li = Li_simp,
  Ls = Ls_simp,
  Mc = Mc_simp,
  ni = ni_simp,
  hi = hi_simp,
  Ni_asc = Ni_asc_simp,
  Ni_dsc = Ni_dsc_simp,
  Hi_asc = Hi_asc_simp,
  Hi_dsc = Hi_dsc_simp
)

# Totales
totalni <- sum(ni_simp)
totalhi <- sum(hi_simp)

# Agregar fila total
TDF_simplificada_completa <-rbind(
  TDF_completa,
  data.frame(
    Li = "Total",
    Ls = "-",
    Mc = "-",
    ni = totalni,
    hi = totalhi,
    Ni_asc = "-",
    Ni_dsc = "-",
    Hi_asc = "-",
    Hi_dsc = "-"
  )
)

# Crear tabla gt
tabla_simplificada <-TDF_simplificada_completa %>%
  gt() %>%
  
  tab_header(
    title = md("*Tabla Nº2*"),
    subtitle = md(
      "**Distribución de frecuencia simplificada de Dióxiodo de Nitrógeno en el 
    análisis sobre la calidad del aire en India 2015-2020**")
  ) %>%
  tab_source_note(
    source_note = md("Autor:Grupo 1")
  ) %>%
  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"
  )  %>%
  
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_body(
      rows = Li == "Total"
    )
  )

tabla_simplificada
Tabla Nº2
Distribución de frecuencia simplificada de Dióxiodo de Nitrógeno en el análisis sobre la calidad del aire en India 2015-2020
Li Ls Mc ni hi Ni_asc Ni_dsc Hi_asc Hi_dsc
0 50 25 22236 85.70 22236 25946 85.7 100
50 100 75 3218 12.40 25454 3710 98.1 14.3
100 150 125 384 1.48 25838 492 99.58 1.9
150 200 175 79 0.30 25917 108 99.88 0.42
200 250 225 24 0.09 25941 29 99.97 0.12
250 300 275 4 0.02 25945 5 99.99 0.03
300 350 325 0 0.00 25945 1 99.99 0.01
350 400 375 1 0.01 25946 1 100 0.01
Total - - 25946 100.00 - - - -
Autor:Grupo 1

5.- Gráficas de distribución de frecuencia

5.1 Histrograma

Histograma general

histograma_general <-hist(
  dioxido_nitrogeno,
  main= "Gráfica Nº1: Distribución de frecuencia de Dióxiodo de Nitrógeno en el 
  análisis sobre la calidad del aire en India 2015-2020",
  xlab= "Dióxido de nitrógeno (µg/m3)",
  ylab= "Cantidad", col="blue",
)

Histograma simplificado

hist(
  dioxido_nitrogeno,
  breaks = seq(minimo, maximo, A),
  main = "Gráfica Nº2: Distribución de frecuencia de Dióxiodo de nitrógeno en el 
  análisis sobre la calidad del aire en India 2015-2020",
  xlab = "Dióxido de nitrógeno (µg/m3)",
  ylab = "Cantidad",
  col = "lightgreen",
  cex.main = 1.1,
  cex.lab = 1.1
)

Histograma con relación al todo

hist(
  dioxido_nitrogeno,
  breaks = seq(minimo, maximo, A),
  main = "Gráfica Nº3: Distribución de frecuencia de Dióxido de nitrógeno en el
  análisis sobre la calidad del aire en India 2015-2020",
  xlab = "Dióxido de nitrógeno (µg/m3)",
  ylab = "Cantidad",
  col = "skyblue",
  ylim = c(0, 30000),
  xlim = c(0, 150),
  cex.main = 1.1,
  cex.lab = 1.1
)

5.2 Histograma porcentual

Histograma porcentual simplificado

# Eliminar la fila total de la tabla
TDF_simplificada_completa_sintotal <- 
  TDF_simplificada_completa[
    TDF_simplificada_completa$Li != "Total", 
  ]

barplot(
  TDF_simplificada_completa_sintotal$hi,
  space = 0,
  col = "pink",
  main = "Gráfica Nº4: Diagrama porcentual de Dióxido de Nitrógeno en el 
  análisis sobre la calidad del aire en India 2015-2020",
  xlab = "Dióxido de nitrógeno (µg/m3)",
  ylab = "Porcentaje",
  names.arg = TDF_simplificada_completa_sintotal$Mc,
  cex.names = 0.9,
  cex.main = 1.1,
  cex.lab = 1.1
)

Histograma porcentual con relación al todo

barplot(
  TDF_simplificada_completa_sintotal$hi,
  space = 0,
  col = "yellow",
  main = "Gráfica Nº5: Diagrama porcentual de Dióxido de Nitrógeno en el 
  análisis sobre la calidad del aire en India",
  xlab = "Dióxido de nitrógeno (µg/m3)",
  ylab = "Porcentaje",
  names.arg = TDF_simplificada_completa_sintotal$Mc,
  ylim = c(0, 100),
  cex.names = 0.8,
  cex.main = 1.1,
  cex.lab = 1.1
)

5.3 Diagrama de caja

boxplot(dioxido_nitrogeno,
        horizontal = TRUE,
        main = "Gráfica N°6: Diagrama de caja del Dióxido de Nitrógeno en el
        análisis sobre la calidad del aire en India 2015-2020",
        xlab = "Dióxido de nitrógeno (µg/m3)",
        col = "orange",
        outline = TRUE)

summary(dioxido_nitrogeno)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.01   11.75   21.69   28.56   37.62  362.21
# Valores atípicos
atipicos <- boxplot.stats(dioxido_nitrogeno)$out
rango_atipicos <- range(atipicos)
print(rango_atipicos)
## [1]  76.43 362.21

5.4 Diagrama de Ojivas

# Recuperar de manera segura los datos exactos de la construcción manual (Sturges)
Li_graf <- TDF_dioxido_nitrogeno$Li
Ls_graf <- TDF_dioxido_nitrogeno$Ls
ni_graf <- TDF_dioxido_nitrogeno$ni
hi_graf <- TDF_dioxido_nitrogeno$hi

Ni_asc_graf <- TDF_dioxido_nitrogeno$Ni_asc
Ni_dsc_graf <- TDF_dioxido_nitrogeno$Ni_dsc
Hi_asc_graf <- TDF_dioxido_nitrogeno$Hi_asc
Hi_dsc_graf <- TDF_dioxido_nitrogeno$Hi_dsc

Ojivas Ascendentes y Descendentes (ni)

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

x <- Ls_graf
marcas_x <- seq(0, max(Ls_graf), by = 20)

plot(
  x, Ni_asc_graf,
  type = "b",
  col = "skyblue",
  pch = 19,
  lwd = 2,
  main = "Gráfica N°7: Distribución de frecuencia ascendente y descendente de\n dióxido de nitrógeno",
  xlab = "Dióxido de nitrógeno (µg/m3)",
  ylab = "Cantidad",
  xlim = c(0, max(Ls_graf)),
  ylim = c(0, max(c(Ni_asc_graf, Ni_dsc_graf))),
  xaxt = "n",
  yaxt = "n",
  las = 1
)

lines(
  x, Ni_dsc_graf,
  type = "b",
  col = "red",
  pch = 19,
  lwd = 2
)

axis(
  1,
  at = marcas_x,
  labels = marcas_x,
  las = 1,
  cex.axis = 0.9
)

marcas_y <- pretty(c(0, max(c(Ni_asc_graf, Ni_dsc_graf))))

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

grid(
  nx = NULL,
  ny = NA,
  col = "gray85",
  lty = 1
)

legend(
  "right",
  legend = c(
    "Ascendente",
    "Descendente"
  ),
  col = c("skyblue", "red"),
  pch = 19,
  lty = 1,
  lwd = 2,
  seg.len = 1.2,
  bty = "n",
  cex = 0.9
)

Ojivas Ascendentes y Descendentes (hi)

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

x <- Ls_graf 
marcas_x <- seq(0, max(x), by = 20) 

plot(
  x, Hi_asc_graf,
  type = "b",
  col = "skyblue",
  pch = 19,
  lwd = 2,
  main = "Gráfica N°8: Distribución porcentual ascendente y descendente de\n dióxido de nitrógeno",
  xlab = "Dióxido de nitrógeno (µg/m3)",
  ylab = "Porcentaje",
  xlim = c(0, max(x)), 
  ylim = c(0, 100),    
  xaxt = "n",
  yaxt = "n",
  las = 1
)

lines(
  x, Hi_dsc_graf,
  type = "b",
  col = "red",
  pch = 19,
  lwd = 2
)

axis(
  1,
  at = marcas_x,
  labels = marcas_x,
  las = 1,
  cex.axis = 0.9
)

marcas_y <- pretty(c(0, 100))

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

grid(
  nx = NULL,
  ny = NA,
  col = "gray85",
  lty = 1
)

legend(
  "right",
  legend = c(
    "Ascendente",
    "Descendente"
  ),
  col = c("skyblue", "red"),
  pch = 19,
  lty = 1,
  lwd = 2,
  seg.len = 1.2,
  bty = "n",
  cex = 0.9
)

6.- Indicadores Estadísticos

6.1 Indicadores de Tendencia Central

# Media aritmética
media <- round(mean(dioxido_nitrogeno),2)
media
## [1] 28.56
# Mediana
mediana <- median(dioxido_nitrogeno)
mediana
## [1] 21.69
# Moda
max_ni <- max(TDF_dioxido_nitrogeno$ni)
moda <- TDF_dioxido_nitrogeno$Mc[TDF_dioxido_nitrogeno$ni == max_ni]
moda
## [1] 12.945

6.2 Indicadores de Dispersión

# Varianza
varianza <- var(dioxido_nitrogeno)
varianza
## [1] 599.0132
# Desviación estándar
sd <- sd(dioxido_nitrogeno)
sd
## [1] 24.47475
# Coeficiente de variación
cv <- round((sd / media) * 100, 2)
cv
## [1] 85.7

6.3 Indicadores de Forma

# Asimetría
library(e1071)
asimetria <- skewness(dioxido_nitrogeno, type = 2)
asimetria
## [1] 2.46456
# Curtosis
curtosis <- kurtosis(dioxido_nitrogeno)
curtosis
## [1] 11.20764
tabla_indicadores <- data.frame(
  "Variable" = c("Dióxido de nitrógeno"),
  "Rango" = paste0("[",
                   min(dioxido_nitrogeno), ";",
                   max(dioxido_nitrogeno), "]"),
  "X" = media,
  "Me" = round(mediana, 2),
  "Mo" = moda,
  "V" = round(varianza, 2),
  "Sd" = round(sd, 2),
  "Cv" = cv,
  "As" = round(asimetria, 2),
  "K" = round(curtosis, 2),
  "Valores Atípicos" = "[76.43;362.21]"
)

library(knitr)

kable(
  tabla_indicadores,
  align = "c",
  caption = "Conclusiones de la variable Dióxido de nitrógeno"
)
Conclusiones de la variable Dióxido de nitrógeno
Variable Rango X Me Mo V Sd Cv As K Valores.Atípicos
Dióxido de nitrógeno [0.01;362.21] 28.56 21.69 12.945 599.01 24.47 85.7 2.46 11.21 [76.43;362.21]

7.- Conclusión

La variable Dióxido de Nitrógeno (\(NO_2\)) fluctúa entre un mínimo de 0.01 y un máximo de 362.21 (\(\mu g/m^3\)), con una media de 21.69 y una desviación estándar de 24.47.
Debido a un coeficiente de variación del 85.7%, se concluye que es un conjunto de valores heterogéneos con una alta dispersión. Los datos se acumulan de manera predominante en el primer intervalo [0.01 - 25.88). No obstante, se han detectado valores atípicos [76.43 ; 362.21], los cuales representan picos de contaminación que pueden afectar moderadamente al medio ambiente.