0. Librerías

# -------------------------
# Cargar librerías
# -------------------------
library(gt)
library(dplyr)
## 
## 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

1.Leer datos

# -------------------------
# Cargar datos
# -------------------------

datos <- read.csv("waterPollution.csv",
                  sep = ",",
                  stringsAsFactors = FALSE)

2. Extracción y depuración de la variable

# ================================
# VARIABLE CUANTITATIVA CONTINUA
# ================================
CCP <- na.omit(datos$composition_paper_cardboard_percent)

# Asegurar que se maneje numéricamente
CCP <- as.numeric(CCP)

3. Frecuencia

3.1 Rango

# Valores mínimo y máximo
minimo <- min(CCP)
maximo <- max(CCP)

3.2 Uso de la Regla de Sturges

# Regla de Sturges
k <- 1 + (3.3 * log10(length(CCP)))
k <- floor(k)

# Rango y amplitud
R <- maximo - minimo
A <- R / k

3.3 Límites de clase

# Límites de clase continuos sin saltos
Li <- round(seq(from = minimo, to = maximo - A, by = A), 4)
Ls <- round(seq(from = minimo + A, to = maximo, by = A), 4)

# Marca de clase
MC <- round((Li + Ls) / 2, 2)

3.4 Creación de columnas

# Frecuencia absoluta
ni <- numeric(length(Li))

for (i in 1:length(Li)) {
  ni[i] <- sum(CCP >= Li[i] & CCP < Ls[i])
}

# Incluir el valor máximo en el último intervalo
ni[length(Li)] <- sum(CCP >= Li[length(Li)] & CCP <= maximo)

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

# Crear tabla base continua (conservando los intervalos con ni = 0)
TDF_CCP <- data.frame(
  Li, Ls, MC, ni, hi
)

# Calcular frecuencias acumuladas continuas
TDF_CCP$Niasc <- cumsum(TDF_CCP$ni)
TDF_CCP$Nidsc <- rev(cumsum(rev(TDF_CCP$ni)))
TDF_CCP$Hiasc <- round((TDF_CCP$Niasc / sum(TDF_CCP$ni)) * 100, 2)
TDF_CCP$Hidsc <- round((TDF_CCP$Nidsc / sum(TDF_CCP$ni)) * 100, 2)

# Ajuste fino de extremos al 100% exacto
TDF_CCP$Hiasc[nrow(TDF_CCP)] <- 100.00
TDF_CCP$Hidsc[1] <- 100.00

4. Tabla de distribución de frecuencia

4.1 Tabla general con Sturges

# Fila Total
TDF_CCP_Completo <- rbind(
  TDF_CCP,
  data.frame(
    Li = "Total",
    Ls = " ",
    MC = " ",
    ni = sum(TDF_CCP$ni),
    hi = 100.00,
    Niasc = " ",
    Nidsc = " ",
    Hiasc = " ",
    Hidsc = " "
  )
)

# Generar Tabla GT
tabla_CCP <- TDF_CCP_Completo %>%
  gt() %>%
  tab_header(
    title = md("*Tabla Nº1*"),
    subtitle = md("**Distribución de frecuencias de la composición porcentual de cartón y papel en el estudio de la calidad de agua en Europa (1991-2017)**")
  ) %>%
  cols_label(
    Li = "Li",
    Ls = "Ls",
    MC = "MC",
    ni = "ni",
    hi = "hi (%)",
    Niasc = "Ni ↑",
    Nidsc = "Ni ↓",
    Hiasc = "Hi ↑ (%)",
    Hidsc = "Hi ↓ (%)"
  ) %>%
  tab_source_note(
    source_note = md("Autor: Grupo 3")
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    column_labels.border.bottom.color = "black",
    row.striping.include_table_body = TRUE
  )

tabla_CCP
Tabla Nº1
Distribución de frecuencias de la composición porcentual de cartón y papel en el estudio de la calidad de agua en Europa (1991-2017)
Li Ls MC ni hi (%) Ni ↑ Ni ↓ Hi ↑ (%) Hi ↓ (%)
5 7.1887 6.09 87 0.44 87 19893 0.44 100
7.1887 9.3773 8.28 479 2.41 566 19806 2.85 99.56
9.3773 11.566 10.47 346 1.74 912 19327 4.58 97.15
11.566 13.7547 12.66 246 1.24 1158 18981 5.82 95.42
13.7547 15.9433 14.85 3463 17.41 4621 18735 23.23 94.18
15.9433 18.132 17.04 0 0.00 4621 15272 23.23 76.77
18.132 20.3207 19.23 14007 70.41 18628 15272 93.64 76.77
20.3207 22.5093 21.41 4 0.02 18632 1265 93.66 6.36
22.5093 24.698 23.6 661 3.32 19293 1261 96.98 6.34
24.698 26.8867 25.79 74 0.37 19367 600 97.36 3.02
26.8867 29.0753 27.98 0 0.00 19367 526 97.36 2.64
29.0753 31.264 30.17 0 0.00 19367 526 97.36 2.64
31.264 33.4527 32.36 0 0.00 19367 526 97.36 2.64
33.4527 35.6413 34.55 0 0.00 19367 526 97.36 2.64
35.6413 37.83 36.74 526 2.64 19893 526 100 2.64
Total 19893 100.00
Autor: Grupo 3

4.2 Tabla Simplificada

# =============================================
# TABLA SIMPLIFICADA (BASADA EN EL HISTOGRAMA)
# =============================================

# 1. Calcular el histograma para extraer intervalos continuos
histoP <- hist(
  CCP,
  breaks = 10,
  plot = FALSE 
)

# 2. Extraer límites continuos
Limites <- histoP$breaks
LimInf <- Limites[1:(length(Limites) - 1)]
LimSup <- Limites[2:length(Limites)]
Mc <- round(histoP$mids, 2)
ni <- histoP$counts
hi <- round((ni / sum(ni)) * 100, 2)

# 3. Crear DataFrame base continuo
TDF_Histo_CCP <- data.frame(
  LimInf,
  LimSup,
  Mc,
  ni,
  hi
)

# Recalcular acumuladas sobre la estructura secuencial continua
TDF_Histo_CCP$Ni_asc <- cumsum(TDF_Histo_CCP$ni)
TDF_Histo_CCP$Ni_dsc <- rev(cumsum(rev(TDF_Histo_CCP$ni)))
TDF_Histo_CCP$Hi_asc <- round((TDF_Histo_CCP$Ni_asc / sum(TDF_Histo_CCP$ni)) * 100, 2)
TDF_Histo_CCP$Hi_dsc <- round((TDF_Histo_CCP$Ni_dsc / sum(TDF_Histo_CCP$ni)) * 100, 2)

# Ajuste de extremos teóricos para evitar el 100.01% por redondeo
TDF_Histo_CCP$Hi_asc[nrow(TDF_Histo_CCP)] <- 100.00
TDF_Histo_CCP$Hi_dsc[1] <- 100.00

# 4. Crear fila de totales
TDF_Histo_CCP_Completo <- rbind(
  TDF_Histo_CCP,
  data.frame(
    LimInf = "Total",
    LimSup = " ",
    Mc = " ",
    ni = sum(TDF_Histo_CCP$ni),
    hi = 100.00,
    Ni_asc = " ",
    Ni_dsc = " ",
    Hi_asc = " ",
    Hi_dsc = " "
  )
)

# 5. Generar Tabla GT
tabla_Histo_CCP <- TDF_Histo_CCP_Completo %>%
  gt() %>%
  tab_header(
    title = md("*Tabla Nº2*"),
    subtitle = md("**Distribución simplificada de frecuencias de la composición porcentual de cartón y papel en el estudio de la calidad de agua en Europa (1991-2017)**")
  ) %>%
  cols_label(
    LimInf = "Límite Inferior",
    LimSup = "Límite Superior",
    Mc = "Marca de Clase",
    ni = "ni",
    hi = "hi (%)",
    Ni_asc = "Ni ↑",
    Ni_dsc = "Ni ↓",
    Hi_asc = "Hi ↑ (%)",
    Hi_dsc = "Hi ↓ (%)"
  ) %>%
  tab_source_note(
    source_note = md("Autor: Grupo 3")
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    column_labels.border.bottom.color = "black",
    row.striping.include_table_body = TRUE
  )

tabla_Histo_CCP
Tabla Nº2
Distribución simplificada de frecuencias de la composición porcentual de cartón y papel en el estudio de la calidad de agua en Europa (1991-2017)
Límite Inferior Límite Superior Marca de Clase ni hi (%) Ni ↑ Ni ↓ Hi ↑ (%) Hi ↓ (%)
5 10 7.5 566 2.85 566 19893 2.85 100
10 15 12.5 4055 20.38 4621 19327 23.23 97.15
15 20 17.5 14007 70.41 18628 15272 93.64 76.77
20 25 22.5 712 3.58 19340 1265 97.22 6.36
25 30 27.5 27 0.14 19367 553 97.36 2.78
30 35 32.5 0 0.00 19367 526 97.36 2.64
35 40 37.5 526 2.64 19893 526 100 2.64
Total 19893 100.00
Autor: Grupo 3

5. Gráficas

5.1 Histograma (ni)

# =========================================
# Histograma generado por RStudio 
# =========================================

hist(
  CCP,
  breaks = histoP$breaks,
  main = "Gráfica Nº1: Distribución de frecuencias de la composición\nporcentual de cartón y papel en el estudio de la calidad de\nagua en Europa (1991-2017)",
  xlab = "Porcentaje de cartón y papel (%)",
  ylab = "Cantidad",
  col = "forestgreen",
  border = "black",
  xaxt = "n" 
)

axis(
  side = 1,
  at = histoP$breaks,
  labels = round(histoP$breaks, 1),
  las = 1,
  cex.axis = 0.8
)

grid()

5.2 Histograma General (ni)

# ===========================================================
# Histograma con relación a la totalidad de los datos
# ===========================================================
bp <- barplot(
  TDF_Histo_CCP$ni,
  col = "limegreen",
  border = "black",
  main = "Gráfica Nº2: Distribución de frecuencias de la composición\nporcentual de cartón y papel en el estudio de la calidad de\nagua en Europa (1991-2017)",
  xlab = "Porcentaje de cartón y papel (%)",
  ylab = "Cantidad",
  space = 0,
  xaxt = "n",
  ylim = c(0, 20000)
)

limites_etiquetas_ccp <- c(TDF_Histo_CCP$LimInf, tail(TDF_Histo_CCP$LimSup, 1))

axis(
  side = 1,
  at = 0:length(TDF_Histo_CCP$ni),
  labels = round(limites_etiquetas_ccp, 1),
  las = 1,
  cex.axis = 0.8
)

grid()

5.3 Histograma Porcentual (hi)

# ======================================
# Histograma porcentual que genera RStudio
# ======================================

bp <- barplot(
  TDF_Histo_CCP$hi,
  col = "forestgreen",
  border = "black",
  main = "Gráfica Nº3: Distribución porcentual de frecuencias de\n la composición de cartón y papel en el estudio de la calidad de\nagua en Europa (1991-2017)",
  xlab = "Porcentaje de cartón y papel (%)",
  ylab = "Porcentaje (%)",
  space = 0,
  xaxt = "n",
  ylim = c(0, max(TDF_Histo_CCP$hi) * 1.15)
)

limites_etiquetas_ccp <- c(TDF_Histo_CCP$LimInf, tail(TDF_Histo_CCP$LimSup, 1))

axis(
  side = 1,
  at = 0:length(TDF_Histo_CCP$hi),
  labels = round(limites_etiquetas_ccp, 1),
  las = 1,
  cex.axis = 0.8
)

grid()

5.4 Histograma Porcentual General (hi)

# ===========================================================
# Histograma porcentual con relación a la totalidad 
# ===========================================================

hi_global_ccp <- round((TDF_Histo_CCP$ni / length(CCP)) * 100, 2)

bp <- barplot(
  hi_global_ccp,
  space = 0,
  col = "limegreen",
  border = "black",
  main = "Gráfica Nº4: Distribución porcentual de frecuencias de\n la composición de cartón y papel en el estudio de la calidad de\nagua en Europa (1991-2017)",
  xlab = "Porcentaje de cartón y papel (%)",
  ylab = "Porcentaje (%)",
  xaxt = "n",
  ylim = c(0, 100)
)

limites_etiquetas_ccp <- c(TDF_Histo_CCP$LimInf, tail(TDF_Histo_CCP$LimSup, 1))

axis(
  side = 1,
  at = 0:length(TDF_Histo_CCP$ni),
  labels = round(limites_etiquetas_ccp, 1),
  las = 1,
  cex.axis = 0.8
)

grid()

5.5 Polígono de frecuencias (hi)

bp <- barplot(
  TDF_Histo_CCP$hi,
  col = "darkseagreen3",
  border = "black",
  main = "Gráfica Nº5: Polígono de frecuencia de la distribución porcentual\nde la composición de cartón y papel en el estudio de la calidad de\nagua en Europa (1991-2017)",
  xlab = "Porcentaje de cartón y papel (%)",
  ylab = "Porcentaje (%)",
  space = 0,
  xaxt = "n",
  ylim = c(0, max(TDF_Histo_CCP$hi) * 1.2)
)

limites_etiquetas_ccp <- c(TDF_Histo_CCP$LimInf, tail(TDF_Histo_CCP$LimSup, 1))

# 3. Dibujamos el eje X 
axis(
  side = 1,
  at = 0:length(TDF_Histo_CCP$hi),
  labels = round(limites_etiquetas_ccp, 1),
  las = 1,
  cex.axis = 0.8
)

# 4. Polígono superpuesto
lines(
  bp,
  TDF_Histo_CCP$hi,
  type = "o",
  pch = 16,
  lwd = 2,
  col = "darkred"
)

# 5. Etiquetas de texto
text(
  bp,
  TDF_Histo_CCP$hi,
  labels = round(TDF_Histo_CCP$hi, 2),
  pos = 3,
  cex = 0.8,
  col = "black"
)

grid()

legend(
  "topright",
  legend = c("Frecuencia relativa (%)"),
  col = "darkred",
  lwd = 2,
  pch = 16,
  bty = "n"
)

5.6 Boxplot

# =============================
# BOXPLOT CON VALORES ATÍPICOS
# =============================
boxplot(
  CCP,
  horizontal = TRUE,
  col = "forestgreen",
  main = "Gráfica Nº6: Diagrama de caja de la composición porcentual de cartón y papel\nen el estudio de la calidad de agua en Europa (1991-2017)",
  xlab = "Porcentaje de cartón y papel (%)"
)

points(
  mean(CCP),
  1,
  pch = 19,
  col = "red"
)

legend(
  "topright",
  legend = "Media",
  pch = 19,
  col = "red"
)

5.7 Ojiva ascendente y descendente (Ni)

# =========================
# OJIVAS Ni
# =========================
par(mar = c(10, 4, 7, 2))

# 1. Definir todos los límites de clase 
todos_limites_ccp <- c(TDF_Histo_CCP$LimInf[1], TDF_Histo_CCP$LimSup)

# Ojiva Ascendente
x_asc_ccp <- c(TDF_Histo_CCP$LimInf[1], TDF_Histo_CCP$LimSup)
y_asc_ccp <- c(0, TDF_Histo_CCP$Ni_asc)

# Ojiva Descendente
x_dsc_ccp <- c(TDF_Histo_CCP$LimInf, tail(TDF_Histo_CCP$LimSup, 1))
y_dsc_ccp <- c(TDF_Histo_CCP$Ni_dsc, 0)

plot(
  x_dsc_ccp,
  y_dsc_ccp,
  main = "Gráfica Nº7: Ojiva ascendente y descendente de la composición\nporcentual de cartón y papel en el estudio de la calidad de\nagua en Europa (1991-2017)",
  xlab = "Porcentaje de cartón y papel (%)",
  ylab = "Frecuencia acumulada",
  col = "red",
  type = "o",
  lwd = 2,
  xaxt = "n",
  ylim = c(0, max(TDF_Histo_CCP$Ni_asc) * 1.05)
)

# 4. Dibujar la ojiva ascendente
lines(
  x_asc_ccp,
  y_asc_ccp,
  col = "forestgreen",
  type = "o",
  lwd = 2
)

# 5. Dibujar el eje X 
axis(
  side = 1,
  at = todos_limites_ccp,
  labels = round(todos_limites_ccp, 1),
  las = 1,
  cex.axis = 0.8
)

grid()

# 6. Leyenda
legend(
  "right",
  legend = c(
    "Ojiva descendente",
    "Ojiva ascendente"
  ),
  col = c("red", "forestgreen"),
  pch = c(16, 16),
  lty = 1,
  bty = "n"
)

5.8 Ojiva ascendente y descendente (Hi)

# =========================
# OJIVAS PORCENTUALES
# =========================
par(mar = c(10, 4, 7, 2))

# 1. Definir todos los límites de clase 
todos_limites_ccp <- c(TDF_Histo_CCP$LimInf[1], TDF_Histo_CCP$LimSup)

# Ojiva Ascendente
x_asc_p_ccp <- c(TDF_Histo_CCP$LimInf[1], TDF_Histo_CCP$LimSup)
y_asc_p_ccp <- c(0, TDF_Histo_CCP$Hi_asc)

# Ojiva Descendente
x_dsc_p_ccp <- c(TDF_Histo_CCP$LimInf, tail(TDF_Histo_CCP$LimSup, 1))
y_dsc_p_ccp <- c(TDF_Histo_CCP$Hi_dsc, 0)

plot(
  x_asc_p_ccp,
  y_asc_p_ccp,
  type = "o",
  col = "limegreen",
  pch = 16,
  lwd = 2,
  main = "Gráfica Nº8: Ojiva ascendente y descendente de la composición\nporcentual de cartón y papel en el estudio de la calidad de\nagua en Europa (1991-2017)",
  xlab = "Porcentaje de cartón y papel (%)",
  ylab = "Porcentaje acumulado (%)",
  ylim = c(0, 100),
  xaxt = "n"
)

# 4. Ojiva Descendente
lines(
  x_dsc_p_ccp,
  y_dsc_p_ccp,
  type = "o",
  col = "red",
  pch = 17,
  lwd = 2
)

# 5. Dibujar el eje X 
axis(
  side = 1,
  at = todos_limites_ccp,
  labels = round(todos_limites_ccp, 1),
  las = 1,
  cex.axis = 0.8
)

grid()

# 6. Leyenda
legend(
  "right",
  legend = c(
    "Ojiva Ascendente (%)",
    "Ojiva Descendente (%)"
  ),
  col = c("limegreen", "red"),
  pch = c(16, 17),
  lty = 1,
  bty = "n"
)

6 Indicadores Estadísticos

6.1 Indicadores de Tendencia Central

# =========================
# INDICADORES ESTADISTICOS
# =========================

# Criterio del boxplot para atípicos
atipicos_ccp <- boxplot.stats(CCP)$out
n_atipicos_ccp <- length(atipicos_ccp)

# Rango de los valores atípicos [Mínimo ; Máximo] junto con la cantidad al lado
if (n_atipicos_ccp > 0) {
  rango_atipicos_ccp <- paste0("[", round(min(atipicos_ccp), 2), " ; ", round(max(atipicos_ccp), 2), "] (Valores: ", n_atipicos_ccp, ")")
} else {
  rango_atipicos_ccp <- "No existen"
}

media <- round(mean(CCP), 2)
mediana <- round(median(CCP), 2)

# Moda basada en el Intervalo Modal 
fila_modal <- which.max(TDF_Histo_CCP$ni)
moda_intervalar <- paste0(
  "[", round(TDF_Histo_CCP$LimInf[fila_modal], 2),  
  " ; ", round(TDF_Histo_CCP$LimSup[fila_modal], 2), "]"
)

6.2 Dispersión

varianza <- var(CCP)
desv_est <- sd(CCP)
cv <- round((desv_est / media) * 100, 2)

6.3 Asimetría

library(e1071)

asimetria <- skewness(CCP, type = 2)
curtosis <- kurtosis(CCP)

6.4 Tabla de Indicadores

tabla_indicadores <- data.frame(
  Variable = "Composición Cartón y Papel (%)",
  Rango = paste0("[", round(min(CCP), 2), " ; ", round(max(CCP), 2), "]"),
  X = media,
  Me = mediana,
  Mo = moda_intervalar,
  V = round(varianza, 2),
  Sd = round(desv_est, 2),
  Cv = cv,
  As = round(asimetria, 2),
  K = round(curtosis, 2),
  Valores_Atipicos = rango_atipicos_ccp
)

tabla_indicadores_gt <- tabla_indicadores %>%
  gt() %>%
  tab_header(
    title = md("*Tabla Nº3*"),
    subtitle = md("**Indicadores estadísticos de la variable composición porcentual de cartón y papel en el estudio de la calidad de agua en Europa (1991-2017)**")
  ) %>%
  cols_label(
    Valores_Atipicos = "Rango Atípicos"
  ) %>%
  tab_source_note(
    source_note = md("Autor: Grupo 3")
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    column_labels.border.bottom.color = "black",
    row.striping.include_table_body = TRUE
  )

tabla_indicadores_gt
Tabla Nº3
Indicadores estadísticos de la variable composición porcentual de cartón y papel en el estudio de la calidad de agua en Europa (1991-2017)
Variable Rango X Me Mo V Sd Cv As K Rango Atípicos
Composición Cartón y Papel (%) [5 ; 37.83] 18.9 20 [15 ; 20] 18.08 4.25 22.5 1.51 8.07 [5 ; 37.83] (Valores: 5882)
Autor: Grupo 3

7. Conclusión

La variable Composición Cartón y Papel (%) fluctúa entre 5 y 37.83, y sus valores giran en torno a una mediana de 20, con una desviación estándar de 4.25. Dado que el coeficiente de variación es de 22.5%, se trata de un conjunto de valores homogéneo. Los datos presentan una asimetría positiva, lo que indica que los valores se acumulan de manera pronunciada en la parte baja de la variable. Con la presencia de valores atípicos en el intervalo de 5 a 37.83 (5882 valores), resulta perjudicial para la gestión ambiental, ya que evidencia una contaminación o concentración de residuos de cartón y papel extrema y focalizada en ciertos cuerpos hídricos de Europa.