# 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$Xylene[datos$Xylene == "-"] <- NA
datos$Xylene <- as.numeric(datos$Xylene)

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

# Tamaño de muestra
n <- length(xileno)
n
## [1] 11422

3. Conteo (frecuencia)

Construcción manual (Regla de Sturges)

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

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

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

tabla_xileno <- TDF_xileno_completo %>%
  gt() %>%
  
  fmt_number(
    columns = hi,
    decimals = 2
  ) %>%
  
  tab_header(
    title = md("*Tabla Nº1*"),
    subtitle = md(
      "**Distribución de frecuencia de Xileno 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_xileno
Tabla Nº1
Distribución de frecuencia de Xileno 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 13.11 6.555 10892 95.36 10892 11422 95.36 100
13.11 26.21 19.66 409 3.58 11301 530 98.94 4.64
26.21 39.32 32.765 71 0.62 11372 121 99.56 1.06
39.32 52.42 45.87 27 0.24 11399 50 99.8 0.44
52.42 65.53 58.975 11 0.10 11410 23 99.9 0.2
65.53 78.63 72.08 2 0.02 11412 12 99.92 0.1
78.63 91.74 85.185 3 0.03 11415 10 99.95 0.08
91.74 104.84 98.29 1 0.01 11416 7 99.96 0.05
104.84 117.95 111.395 3 0.03 11419 6 99.99 0.04
117.95 131.05 124.5 1 0.01 11420 3 100 0.01
131.05 144.16 137.605 1 0.01 11421 2 100.01 0
144.16 157.26 150.71 0 0.00 11421 1 100.01 -0.01
157.26 170.37 163.815 0 0.00 11421 1 100.01 -0.01
170.37 170.37 170.37 1 −0.01 11422 1 100 -0.01
Total - - 11422 100.00 - - - -
Autor: Grupo 1

4.2 Tabla simplificada

histograma_simplificado <- hist(
  xileno,
  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 Xileno 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 Xileno 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 11198 98.04 11198 11422 98.04 100
20 40 30 177 1.55 11375 224 99.59 1.96
40 60 50 32 0.28 11407 47 99.87 0.41
60 80 70 5 0.04 11412 15 99.91 0.13
80 100 90 4 0.04 11416 10 99.95 0.09
100 120 110 3 0.03 11419 6 99.98 0.05
120 140 130 2 0.02 11421 3 100 0.02
140 160 150 0 0.00 11421 1 100 0
160 180 170 1 0.00 11422 1 100 0
Total - - 11422 100.00 - - - -
Autor:Grupo 1

5. Gráficas de distribución de frecuencia

5.1 Histograma

Histograma general

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

Histograma simplificado

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

Histograma con relación al todo

hist(
  xileno,
  breaks = seq(minimo, maximo, A),
  main = "Gráfica Nº3: Distribución de frecuencia de Xileno en el
  análisis sobre la calidad del aire en India",
  xlab = "Xileno (µ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 Xileno en el 
  análisis sobre la calidad del aire en India",
  xlab = "Xileno (µ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 Xileno en el 
  análisis sobre la calidad del aire en India",
  xlab = "Xileno (µ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(xileno,
        horizontal = TRUE,
        main = "Gráfica N°6: Diagrama de caja del Xileno en el
        análisis sobre la calidad del aire en India",
        xlab = "Xileno (µg/m3)",
        col = "orange",
        outline = TRUE)

summary(xileno)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.00    0.14    0.98    3.07    3.35  170.37
# Valores atípicos
atipicos <- boxplot.stats(xileno)$out
rango_atipicos <- range(atipicos)
print(rango_atipicos)
## [1]   8.17 170.37
# Recuperar datos de la tabla original
Li <- TDF_xileno$Li
Ls <- TDF_xileno$Ls
ni <- TDF_xileno$ni
hi <- TDF_xileno$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 = "Xileno (µg/m3)",
     ylab = "Cantidad",
     main = "Gráfica N°7: Distribución de frecuencia ascendente y descendente de
     xileno",
     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 = "Xileno (µg/m3)",
     ylab = "Porcentaje",
     main = "Gráfica N°8: Distribución porcentual ascendente y descendente de
     xileno",
     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(xileno),2)
media
## [1] 3.07
# Mediana
mediana <- median(xileno)
mediana
## [1] 0.98
# Moda
max_ni <- max(TDF_xileno$ni)
moda <- TDF_xileno$Mc[TDF_xileno$ni == max_ni]
moda
## [1] 6.555

8.2 Indicadores de Dispersión

# Varianza
varianza <- var(xileno)
varianza
## [1] 39.98346
# Desviación estándar
sd <- sd(xileno)
sd
## [1] 6.323247
# Coeficiente de variación
cv <- round((sd / media) * 100, 2)
cv
## [1] 205.97

8.3 Indicadores de Forma

# Asimetría
library(e1071)
asimetria <- skewness(xileno, type = 2)
asimetria
## [1] 7.891515
# Curtosis
curtosis <- kurtosis(xileno)
curtosis
## [1] 119.9056
tabla_indicadores <- data.frame(
  "Variable" = c("Xileno"),
  "Rango" = paste0("[",
    min(xileno), ";",
    max(xileno), "]"),
  "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 Xileno"
)
Conclusiones de la variable Xileno
Variable Rango X Me Mo V Sd Cv As K Valores.Atípicos
Xileno [0;170.37] 3.07 0.98 6.555 39.98 6.32 205.97 7.89 119.91 [76.43;362.21]

9. Conclusiones

La variable Xileno dados en (µg/m3) fluctúa entre 0 y 170.37 (µg/m3), y sus valores giran entorno a 0.98 con una desviación estándar de 6.32 (µg/m3) siendo un conjunto de valores homogéneo. Con la presencia de valores atípicos del intervalo 8.17 a 170.37 (µg/m3).