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

0.Carga de librerías

library(knitr)
library(kableExtra)
library(readr)
library(gt)
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")
datos <- read.csv("Datos cambiados..csv",
                  header = TRUE, 
                  sep = ",", dec = "." )

2. Selección de la variable

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

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

# Tamaño de muestra
n <- length(dioxido_azufre)
n
## [1] 25677

3. Conteo (frecuencia)

Construcción manual (Regla de Sturges)

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

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_azufre >= Li[i] & 
                   dioxido_azufre < Ls[i])
  } else {
    ni[i] <- sum(dioxido_azufre >= Li[i] & 
                   dioxido_azufre <= 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_azufre <-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_azufre_completo <- rbind(
  TDF_dioxido_azufre,
  data.frame(
    Li = "Total",
    Ls = "-",
    Mc = "-",
    ni = total_ni,
    hi = total_hi,
    Ni_asc = "-",
    Ni_dsc = "-",
    Hi_asc = "-",
    Hi_dsc = "-"
  )
)

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

tabla_dioxido_azufre <- TDF_dioxido_azufre_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 Azufre en el análisis
      sobre la calidad del aire en India**"
    )
  ) %>%
  
  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_azufre
Tabla Nº1
Distribución de frecuencia de Dióxiodo de Azufre en el análisis sobre la calidad del aire en India
Li Ls Mc ni hi Ni_asc Ni_dsc Hi_asc Hi_dsc
0.01 13.86 6.935 18336 71.41 18336 25677 71.41 100
13.86 27.7 20.78 4542 17.69 22878 7341 89.1 28.59
27.7 41.55 34.625 1195 4.65 24073 2799 93.75 10.9
41.55 55.4 48.475 743 2.89 24816 1604 96.64 6.25
55.4 69.24 62.32 286 1.11 25102 861 97.75 3.36
69.24 83.09 76.165 150 0.58 25252 575 98.33 2.25
83.09 96.94 90.015 117 0.46 25369 425 98.79 1.67
96.94 110.78 103.86 99 0.39 25468 308 99.18 1.21
110.78 124.63 117.705 74 0.29 25542 209 99.47 0.82
124.63 138.47 131.55 57 0.22 25599 135 99.69 0.53
138.47 152.32 145.395 30 0.12 25629 78 99.81 0.31
152.32 166.17 159.245 19 0.07 25648 48 99.88 0.19
166.17 180.01 173.09 24 0.09 25672 29 99.97 0.12
180.01 193.86 186.935 4 0.02 25676 5 99.99 0.03
193.86 193.86 193.86 1 0.01 25677 1 100 0.01
Total - - 25677 100.00 - - - -
Autor: Grupo 1

4.2 Tabla simplificada

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

# Límites y frecuencias
Limites <- histograma_simplificado$breaks

Li <- Limites[1:(length(Limites)-1)]
Ls <- Limites[2:length(Limites)]

Mc <- histograma_simplificado$mids
ni <- histograma_simplificado$counts

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

Ni_asc <- cumsum(ni)
Ni_dsc <- rev(cumsum(rev(ni)))

Hi_asc <- cumsum(hi)
Hi_dsc <- rev(cumsum(rev(hi)))
Hi_asc <- round(Hi_asc, 2)
Hi_dsc <- round(Hi_dsc, 2)
Hi_asc[length(Hi_asc)] <- 100
Hi_dsc[1] <- 100

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

# Totales
totalni <- sum(ni)
totalhi <- sum(hi)

# 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 Azufre en el 
    análisis sobre la calidad del aire en India**")
  ) %>%
  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 Azufre en el análisis sobre la calidad del aire en India
Li Ls Mc ni hi Ni_asc Ni_dsc Hi_asc Hi_dsc
0 20 10 21244 82.74 21244 25677 82.74 100
20 40 30 2735 10.65 23979 4433 93.39 17.26
40 60 50 953 3.71 24932 1698 97.1 6.61
60 80 70 287 1.12 25219 745 98.22 2.9
80 100 90 174 0.68 25393 458 98.9 1.78
100 120 110 128 0.50 25521 284 99.4 1.1
120 140 130 83 0.32 25604 156 99.72 0.6
140 160 150 40 0.16 25644 73 99.88 0.28
160 180 170 28 0.11 25672 33 99.99 0.12
180 200 190 5 0.01 25677 5 100 0.01
Total - - 25677 100.00 - - - -
Autor:Grupo 1

5. Gráficas de distribución de frecuencia

5.1 Histograma

Histograma general

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

Histograma simplificado

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

Histograma con relación al todo

hist(
  dioxido_azufre,
  breaks = seq(minimo, maximo, A),
  main = "Gráfica Nº3: Distribución de frecuencia de Dióxiodo de Azufre en el
  análisis sobre la calidad del aire en India",
  xlab = "Dióxido de azufre (µg/m3)",
  ylab = "Cantidad",
  col = "skyblue",
  ylim = c(0, 29531),
  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 Azufre en el 
  análisis sobre la calidad del aire en India",
  xlab = "Dióxido de azufre (µ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 azufre en el 
  análisis sobre la calidad del aire en India",
  xlab = "Dióxido de azufre (µ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
)

6. Diagrama de caja

boxplot(dioxido_azufre,
        horizontal = TRUE,
        main = "Gráfica N°6: Diagrama de caja del Dioxiodo de Azufre en el
        análisis sobre la calidad del aire en India",
        xlab = "Dióxido de azufre (µg/m3)",
        col = "orange",
        outline = TRUE)

summary(dioxido_azufre)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.01    5.67    9.16   14.53   15.22  193.86
# Valores atípicos
atipicos <- boxplot.stats(dioxido_azufre)$out
rango_atipicos <- range(atipicos)
print(rango_atipicos)
## [1]  29.56 193.86
# Recuperar datos de la tabla original
Li <- TDF_dioxido_azufre$Li
Ls <- TDF_dioxido_azufre$Ls
ni <- TDF_dioxido_azufre$ni
hi <- TDF_dioxido_azufre$hi

7. Ojivas

7.1 Ojivas Ascendentes y Descendentes (ni)

Ni_asc <- cumsum(ni)
Ni_dsc <- rev(cumsum(rev(ni)))

plot(Ls, Ni_asc,
     type = "o",
     col = "skyblue",
     lwd = 3,
     xlim = c(minimo,maximo),
     xlab = "Dióxido de azufre (µg/m3)",
     ylab = "Cantidad",
     main = "Gráfica N°7: Distribución de frecuencia ascendente y descendente de
     dióxido de azufre",
     cex.axis = 0.8,
     las = 1,
     xaxt = "n")

lines(Li, Ni_dsc,
      type = "o",
      col = "red",
      lwd = 3)

axis(1, at = Li, las = 1)

7.2 Ojivas Ascendentes y Descendentes (hi)

Hi_asc <- cumsum(hi)
Hi_dsc <- rev(cumsum(rev(hi)))

plot(Ls, Hi_asc,
     type = "o",
     col = "skyblue",
     lwd = 3,
     xlim = c(minimo,maximo),
     xlab = "Dióxido de azufre (µg/m3)",
     ylab = "Porcentaje",
     main = "Gráfica N°8: Distribución porcentual ascendente y descendente de
     dióxido de azufre",
     cex.axis = 0.8,
     las = 1,
     xaxt = "n")

lines(Ls, Hi_dsc,
      type = "o",
      col = "red",
      lwd = 3)

axis(1, at = Li, las = 1)

8.Indicadores Estadísticos

8.1 Indicadores de Tendencia Central

# Media aritmética
media <- round(mean(dioxido_azufre),2)
media
## [1] 14.53
# Mediana
mediana <- median(dioxido_azufre)
mediana
## [1] 9.16
# Moda
max_ni <- max(TDF_dioxido_azufre$ni)
moda <- TDF_dioxido_azufre$Mc[TDF_dioxido_azufre$ni == max_ni]
moda
## [1] 6.935

8.2 Indicadores de Dispersión

# Varianza
varianza <- var(dioxido_azufre)
varianza
## [1] 328.8338
# Desviación estándar
sd <- sd(dioxido_azufre)
sd
## [1] 18.13377
# Coeficiente de variación
cv <- round((sd / media) * 100, 2)
cv
## [1] 124.8

8.3 Indicadores de Forma

# Asimetría
library(e1071)
asimetria <- skewness(dioxido_azufre, type = 2)
asimetria
## [1] 4.08366
# Curtosis
curtosis <- kurtosis(dioxido_azufre)
curtosis
## [1] 22.06062
tabla_indicadores <- data.frame(
  "Variable" = c("Dióxido de azufre"),
  "Rango" = paste0("[",
    min(dioxido_azufre), ";",
    max(dioxido_azufre), "]"),
  "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 azufre"
)
Conclusiones de la variable Dióxido de azufre
Variable Rango X Me Mo V Sd Cv As K Valores.Atípicos
Dióxido de azufre [0.01;193.86] 14.53 9.16 6.935 328.83 18.13 124.8 4.08 22.06 [76.43;362.21]

9. Conclusiones

La variable Dióxido de azufre dados en (µg/m3) fluctúa entre 0.01 y 193.86 (µg/m3), y sus valores giran entorno a 9.16 con una desviación estándar de 18.13 (µg/m3) siendo un conjunto de valores homogéneo. Con la presencia de valores atípicos del intervalo 29.56 a 193.86 (µg/m3).