# Librerías
library(kableExtra)
library(knitr)
library(magrittr)
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
library(e1071)
# Cargar datos
datos <- read.csv("china_water_pollution_data.csv",
header = TRUE,
sep = ",",
dec = ".")
COD <- datos$COD_mg_L
COD <- na.omit(COD)
COD <- COD[COD >= 0]
n <- length(COD)
n
## [1] 3000
minimo <- min(COD)
maximo <- max(COD)
K <- floor(1 + 3.322 * log10(n))
# Creamos el rango y lo guardamos bien
rango_ajustado <- seq(from = minimo - 0.01, to = maximo + 0.01, length.out = K + 1)
intervalos <- cut(COD, breaks = rango_ajustado, include.lowest = TRUE, right = TRUE)
ni <- as.numeric(table(intervalos))
# Parche para asegurar los 3000
if(sum(ni) != n){
ni[which.max(ni)] <- ni[which.max(ni)] + (n - sum(ni))
}
Li <- rango_ajustado[-length(rango_ajustado)]
Ls <- rango_ajustado[-1]
Mc <- (Li + Ls)/2
hi <- (ni / sum(ni)) * 100
Ni_asc <- cumsum(ni)
Hi_asc <- cumsum(hi)
TDF_COD <- data.frame(
Lim_inf = Li,
Lim_sup = Ls,
MC = Mc,
ni = ni,
hi = hi,
Ni_asc = Ni_asc,
Hi_asc = Hi_asc
)
kable(TDF_COD, digits = 3, align = "c",
col.names = c("Lím. Inf.", "Lím. Sup.", "MC", "ni", "hi (%)", "Ni Asc.", "Hi Asc. (%)"),
caption = paste("TABLA FINAL - TOTAL DATOS:", sum(ni))) %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover"))
| Lím. Inf. | Lím. Sup. | MC | ni | hi (%) | Ni Asc. | Hi Asc. (%) |
|---|---|---|---|---|---|---|
| 2.080 | 5.056 | 3.568 | 4 | 0.133 | 4 | 0.133 |
| 5.056 | 8.032 | 6.544 | 22 | 0.733 | 26 | 0.867 |
| 8.032 | 11.008 | 9.520 | 73 | 2.433 | 99 | 3.300 |
| 11.008 | 13.983 | 12.495 | 239 | 7.967 | 338 | 11.267 |
| 13.983 | 16.959 | 15.471 | 476 | 15.867 | 814 | 27.133 |
| 16.959 | 19.935 | 18.447 | 683 | 22.767 | 1497 | 49.900 |
| 19.935 | 22.911 | 21.423 | 675 | 22.500 | 2172 | 72.400 |
| 22.911 | 25.887 | 24.399 | 470 | 15.667 | 2642 | 88.067 |
| 25.887 | 28.863 | 27.375 | 241 | 8.033 | 2883 | 96.100 |
| 28.863 | 31.838 | 30.350 | 88 | 2.933 | 2971 | 99.033 |
| 31.838 | 34.814 | 33.326 | 24 | 0.800 | 2995 | 99.833 |
| 34.814 | 37.790 | 36.302 | 5 | 0.167 | 3000 | 100.000 |
La tabla de distribución de frecuencia del Carbono Orgánico Disuelto fue construida inicialmente aplicando la Regla de Sturges para determinar el número óptimo de clases.
Posteriormente, el procedimiento se simplificó utilizando la función hist(), obteniendo automáticamente los intervalos y frecuencias, confirmando los resultados obtenidos manualmente.
# Usamos el objeto ni del bloque anterior para que coincida perfectamente
Hist_COD <- hist(COD, breaks = rango_ajustado, plot = FALSE)
TDF_simplificada <- data.frame(
Lim_inf = round(Hist_COD$breaks[-length(Hist_COD$breaks)], 2),
Lim_sup = round(Hist_COD$breaks[-1], 2),
ni = ni,
hi = round((ni/sum(ni))*100, 2)
)
kable(TDF_simplificada, align="c",
caption="Tabla simplificada obtenida mediante hist()") %>%
kable_styling(full_width = FALSE)
| Lim_inf | Lim_sup | ni | hi |
|---|---|---|---|
| 2.08 | 5.06 | 4 | 0.13 |
| 5.06 | 8.03 | 22 | 0.73 |
| 8.03 | 11.01 | 73 | 2.43 |
| 11.01 | 13.98 | 239 | 7.97 |
| 13.98 | 16.96 | 476 | 15.87 |
| 16.96 | 19.94 | 683 | 22.77 |
| 19.94 | 22.91 | 675 | 22.50 |
| 22.91 | 25.89 | 470 | 15.67 |
| 25.89 | 28.86 | 241 | 8.03 |
| 28.86 | 31.84 | 88 | 2.93 |
| 31.84 | 34.81 | 24 | 0.80 |
| 34.81 | 37.79 | 5 | 0.17 |
hist(COD, breaks = rango_ajustado,
main = "Gráfica N°1: Distribución de la COD",
xlab = "COD (mg/L)", ylab = "Cantidad",
col = "lightgreen")
hist(COD, breaks = 10,
main = "Gráfica N°2: Distribución general de la COD
en el estudio de contaminación del agua en China 2023",
xlab = "COD (mg/L)",
ylab = "Cantidad",
ylim = c(0, max(ni)),
col = "lightgreen")
barplot(height = TDF_COD$hi, space = 0, col = "skyblue",
main = "Gráfica N°3: Distribución porcentual de la COD",
xlab = "COD (mg/L)", ylab = "Porcentaje (%)",
names.arg = round(TDF_COD$MC, 2))
boxplot(COD, horizontal = TRUE, col = "green",
main = "Gráfica N°6: Diagrama de caja de la COD",
xlab = "COD (mg/L)")
Ni_asc <- cumsum(ni)
Ni_desc <- rev(cumsum(rev(ni)))
plot(Ls, Ni_asc,
type = "o",
col = "orange",
lwd = 3,
xlab = "COD (mg/L)",
ylab = "Frecuencia acumulada",
main = "Gráfica N°7: Ojiva Ascendente y Descendente")
lines(Li, Ni_desc,
type = "o",
col = "green",
lwd = 3)
Hi_asc <- cumsum(hi)
Hi_desc <- rev(cumsum(rev(hi)))
plot(Ls, Hi_asc,
type = "o",
col = "blue",
lwd = 3,
xlab = "COD (mg/L)",
ylab = "Porcentaje acumulado (%)",
main = "Gráfica N°8: Ojiva porcentual Ascendente y Descendente")
lines(Li, Hi_desc,
type = "o",
col = "red",
lwd = 3)
media <- round(mean(COD),2)
mediana <- median(COD)
max_ni <- max(TDF_COD$ni)
moda <- TDF_COD$MC[TDF_COD$ni == max_ni]
media
## [1] 19.99
mediana
## [1] 19.94
moda
## [1] 18.44708
varianza <- var(COD)
sd <- sd(COD)
cv <- round((sd/media)*100,2)
varianza
## [1] 25.08409
sd
## [1] 5.008402
cv
## [1] 25.05
library(e1071)
asimetria <- skewness(COD, type = 2)
curtosis <- kurtosis(COD)
asimetria
## [1] 0.02124703
curtosis
## [1] -0.03511734
tabla_indicadores <- data.frame(
"Variable" = "COD (mg/L)",
"Rango" = paste0("[",min(COD),";",max(COD),"]"),
"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)
)
kable(tabla_indicadores, align='c',
caption="Conclusiones de la variable COD (mg/L)")
| Variable | Rango | X | Me | Mo | V | Sd | Cv | As | K |
|---|---|---|---|---|---|---|---|---|---|
| COD (mg/L) | [2.09;37.78] | 19.99 | 19.94 | 18.44708 | 25.08 | 5.01 | 25.05 | 0.02 | -0.04 |
La variable COD (mg/L) fluctúa entre 2.09 y 37.78 mg/L, y sus valores giran en torno a 19.99 mg/L, con una desviación estándar de 5.01 mg/L, siendo un conjunto de datos con variabilidad moderada (CV = 25.05%). Los valores se distribuyen de manera prácticamente simétrica (As ≈ 0.02), indicando que no existe una concentración marcada hacia valores bajos o altos, y presentan una curtosis cercana a cero (K = -0.04), evidenciando una distribución muy similar a la normal. Por lo anterior, el comportamiento de la variable COD (mg/L) puede considerarse estable y representativo para el análisis de la calidad del agua en China durante el año 2023.