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
# ================================

RMV <- na.omit(datos$resultMeanValue)
# Datos para gráficos
RMV_graf <- RMV[RMV >= 0.01]

3. Frecuencia

3.1 Rango

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

3.2 Uso de la Regla de Sturges

# Regla de Sturges
k <- 1 + (3.3 * log10(length(RMV)))
k <- floor(k)
# Rango y amplitud
R <- maximo - minimo
A <- R / k

3.3 Límites de clase

# Límites de clase
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(RMV >= Li[i] & RMV < Ls[i])
}

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

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

# Crear tabla
TDF_RMV <- data.frame(
  Li, Ls, MC, ni, hi
)

# ================================
# ELIMINAR INTERVALOS CON ni = 0
# ================================

TDF_RMV <- TDF_RMV[TDF_RMV$ni > 0, ]

# Recalcular acumuladas
TDF_RMV$Niasc <- cumsum(TDF_RMV$ni)
TDF_RMV$Nidsc <- rev(cumsum(rev(TDF_RMV$ni)))
TDF_RMV$Hiasc <- round(cumsum(TDF_RMV$hi))
TDF_RMV$Hidsc <- round(rev(cumsum(rev(TDF_RMV$hi))))

4. Tabla de distribución de frecuencia

4.1 Tabla general con Sturges

TDF_RMV_Completo <- rbind(
  TDF_RMV,
  data.frame(
    Li = "Total",
    Ls = " ",
    MC = " ",
    ni = sum(TDF_RMV$ni),
    hi = 100,
    Niasc = " ",
    Nidsc = " ",
    Hiasc = " ",
    Hidsc = " "
  )
)

# ================================
# TABLA GT
# ================================

tabla_RMV <- TDF_RMV_Completo %>%
  gt() %>%
  tab_header(
    title = md("*Tabla Nº1*"),
    subtitle = md("**Distribución de frecuencias del valor medio  
     en el estudio de la calidad de agua en Europa (1991-2017)**")
  ) %>%
  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_RMV
Tabla Nº1
Distribución de frecuencias del valor medio
en el estudio de la calidad de agua en Europa (1991-2017)
Li Ls MC ni hi Niasc Nidsc Hiasc Hidsc
0 940.5333 470.27 19948 99.74 19948 20000 100 100
940.5333 1881.0667 1410.8 43 0.22 19991 52 100 0
1881.0667 2821.6 2351.33 4 0.02 19995 9 100 0
2821.6 3762.1333 3291.87 2 0.01 19997 5 100 0
4702.6667 5643.2 5172.93 1 0.00 19998 3 100 0
10345.8667 11286.4 10816.13 1 0.00 19999 2 100 0
13167.4667 14108 13637.73 1 0.00 20000 1 100 0
Total 20000 100.00
Autor: Grupo 3

4.2 Tabla Simplificada

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

RMV_filtrado <- RMV_graf[RMV_graf <= quantile(RMV_graf, 0.99, na.rm = TRUE)]

# 1. Calcular el histograma 
histoP <- hist(
  RMV_filtrado,
  breaks = 6,
  plot = FALSE 
)

# 2. Extraer datos del histograma para la tabla
Limites <- histoP$breaks
LimInf <- Limites[1:(length(Limites) - 1)]
LimSup <- Limites[2:length(Limites)]
Mc <- histoP$mids
ni <- histoP$counts
hi <- round((ni / sum(ni)) * 100, 2)

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

# Eliminar intervalos vacíos
TDF_Histo_RMV <- TDF_Histo_RMV[TDF_Histo_RMV$ni > 0, ]

# Recalcular frecuencias acumuladas
TDF_Histo_RMV$Ni_asc <- cumsum(TDF_Histo_RMV$ni)
TDF_Histo_RMV$Ni_dsc <- rev(cumsum(rev(TDF_Histo_RMV$ni)))
TDF_Histo_RMV$Hi_asc <- round(cumsum(TDF_Histo_RMV$hi), 2)
TDF_Histo_RMV$Hi_dsc <- round(rev(cumsum(rev(TDF_Histo_RMV$hi))), 2)

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

# 5. Generar y mostrar la Tabla con 'gt'
tabla_Histo_RMV <- TDF_Histo_RMV_Completo %>%
  gt() %>%
  tab_header(
    title = md("*Tabla Nº2*"),
    subtitle = md("**Distribución de frecuencias simplificada del valor medio  
     en el estudio de la calidad de agua en Europa (1991-2017)**")
  ) %>%
  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_RMV
Tabla Nº2
Distribución de frecuencias simplificada del valor medio
en el estudio de la calidad de agua en Europa (1991-2017)
LimInf LimSup Mc ni hi Ni_asc Ni_dsc Hi_asc Hi_dsc
0 100 50 17464 93.32 17464 18714 93.32 100
100 200 150 683 3.65 18147 1250 96.97 6.68
200 300 250 180 0.96 18327 567 97.93 3.03
300 400 350 157 0.84 18484 387 98.77 2.07
400 500 450 135 0.72 18619 230 99.49 1.23
500 600 550 95 0.51 18714 95 100 0.51
Total 18714 100.00
Autor: Grupo 3

5. Gráficas

5.1 Histograma (ni)

# =========================================
# Histograma genrado por RStudio 
# =========================================

hist(
  RMV_filtrado,
  breaks = histoP$breaks,
  main = "Gráfica Nº1: Distribución de frecuencias del valor medio  
     en el estudio de la calidad de agua en Europa (1991-2017)",
  xlab = "Valor medio",
  ylab = "Cantidad",
  col = "deepskyblue",
  border = "black"
)

5.2 Histograma General (ni)

# ===========================================================
# Histograma con relación a la totalidad de los datos
# ===========================================================

bp <- barplot(
  TDF_Histo_RMV$ni,
  col = "lightskyblue1",
  main = "Gráfica Nº2: Distribución de frecuencias del valor medio  
     en el estudio de la calidad de agua en Europa (1991-2017)",
  xlab = "Valor medio",
  ylab = "Cantidad",
  space = 0,
  xaxt = "n", 
  ylim = c(0, 20000)
)

limites_etiquetas <- c(TDF_Histo_RMV$LimInf, tail(TDF_Histo_RMV$LimSup, 1))

axis(
  side = 1, 
  at = 0:length(TDF_Histo_RMV$ni), 
  labels = round(limites_etiquetas, 2),
  las = 1 
)

5.3 Histograma Porcentual (hi)

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

bp <- barplot(
  TDF_Histo_RMV$hi,
  col = "deepskyblue",
  main = "Gráfica Nº3: Distribución porcentual de frecuencias del valor medio  
     en el estudio de la calidad de agua en Europa (1991-2017)",
  xlab = "Valor medio",
  ylab = "Porcentaje (%)",
  space = 0,
  xaxt = "n", 
)

limites_etiquetas <- c(TDF_Histo_RMV$LimInf, tail(TDF_Histo_RMV$LimSup, 1))

axis(
  side = 1, 
  at = 0:length(TDF_Histo_RMV$hi), 
  labels = round(limites_etiquetas, 2)
)

5.4 Histograma Porcentual General (hi)

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

bp <- barplot(
  TDF_Histo_RMV$hi,
  col = "lightskyblue",
  main = "Gráfica Nº4: Distribución porcentual de frecuencias del valor medio  
     en el estudio de la calidad de agua en Europa (1991-2017)",
  xlab = "Valor medio",
  ylab = "Porcentaje (%)",
  space = 0,
  xaxt = "n", 
  ylim = c(0, 100)
)

limites_etiquetas <- c(TDF_Histo_RMV$LimInf, tail(TDF_Histo_RMV$LimSup, 1))

axis(
  side = 1, 
  at = 0:length(TDF_Histo_RMV$hi), 
  labels = round(limites_etiquetas, 2)
)

5.5 Polígono de frecuencias (hi)

# ======================================
# Polígono de frecuencias 
# ======================================

bp <- barplot(
  TDF_Histo_RMV$hi,
  col = "royalblue",
  main = "Gráfica Nº5: Polígono de frecuencia de la distribución
  porcentual del valor medio, en el estudio de la calidad de agua  
  en Europa (1991-2017)",
  xlab = "Valor Medio",
  ylab = "Porcentaje (%)",
  space = 0,
  xaxt = "n",
  ylim = c(0, max(TDF_Histo_RMV$hi) * 1.2)
)

limites_etiquetas <- c(TDF_Histo_RMV$LimInf, tail(TDF_Histo_RMV$LimSup, 1))

axis(
  side = 1, 
  at = 0:length(TDF_Histo_RMV$hi), 
  labels = round(limites_etiquetas, 2)
)

lines(
  bp,
  TDF_Histo_RMV$hi,
  type = "o",
  pch = 16,
  lwd = 2,
  col = "darkred"
)

text(
  bp,
  TDF_Histo_RMV$hi,
  labels = round(TDF_Histo_RMV$hi, 2),
  pos = 3,
  cex = 0.8,
  col = "black"
)

5.6 Boxplot sin valores atípicos

# =============================
# BOXPLOT SIN VALORES ATÍPICOS
# =============================
boxplot(
  RMV,
  horizontal = TRUE,
  outline = FALSE,
  col = "forestgreen",
  main = "Gráfica Nº6: Diagrama de caja del Valor medio sin valores atipicos, en  
  el estudio de la calidad de agua en Europa (1991-2017)",
  xlab = "Valor medio"
)

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

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

5.7 Boxplot con valores atípicos

# =============================
# BOXPLOT CON VALORES ATÍPICOS
# =============================

boxplot(
  RMV,
  horizontal = TRUE,
  col = "forestgreen",
  main = "Gráfica Nº7: Diagrama de caja del Valor Medio con valores atipicos, en
  el estudio de la calidad de agua en Europa (1991-2017)",
  xlab = "Valor Medio"
)

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

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

5.8 Ojiva ascendente y descendente (Ni)

# =========================
# OJIVAS Ni
# =========================

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

# Ojiva Ascendente
x_asc <- c(TDF_Histo_RMV$LimInf[1], TDF_Histo_RMV$LimSup)
y_asc <- c(0, TDF_Histo_RMV$Ni_asc)

# Ojiva Descendente
x_dsc <- c(TDF_Histo_RMV$LimInf, tail(TDF_Histo_RMV$LimSup, 1))
y_dsc <- c(TDF_Histo_RMV$Ni_dsc, 0)

plot(
  x_dsc,
  y_dsc,
  main = "Gráfica Nº8: Ojiva ascendente y descendente del Valor Medio, en el  
  estudio de la calidad de agua en Europa (1991-2017)",
  xlab = "Valor Medio",
  ylab = "Frecuencia acumulada",
  col = "red",
  type = "o",
  lwd = 2,
  xaxt = "n",
  ylim = c(0, max(TDF_Histo_RMV$Ni_asc) * 1.05)
)

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

# 5. Dibujar el eje X 
axis(
  side = 1,
  at = todos_limites,
  labels = round(todos_limites, 2)
)

# 6. Añadir la leyenda
legend(
  "right",
  legend = c(
    "Ojiva descendente",
    "Ojiva ascendente"
  ),
  col = c("red", "forestgreen"),
  pch = c(16, 16),
  lty = 1,
  bty = "n"
)

5.9 Ojiva ascendente y descendente (Hi)

# =========================
# OJIVAS PORCENTUALES
# =========================

# 1. Definir todos los límites 
todos_limites <- c(TDF_Histo_RMV$LimInf[1], TDF_Histo_RMV$LimSup)

# Ojiva Ascendente
x_asc_hi <- c(TDF_Histo_RMV$LimInf[1], TDF_Histo_RMV$LimSup)
y_asc_hi <- c(0, TDF_Histo_RMV$Hi_asc)

# Ojiva Descendente:
x_dsc_hi <- c(TDF_Histo_RMV$LimInf, tail(TDF_Histo_RMV$LimSup, 1))
y_dsc_hi <- c(TDF_Histo_RMV$Hi_dsc, 0)

plot(
  x_asc_hi,
  y_asc_hi,
  type = "o",
  col = "deepskyblue",
  pch = 16,
  lwd = 2,
  main = "Gráfica Nº9: Ojiva ascendente y descendente del Valor Medio, en el  
  estudio de la calidad de agua en Europa (1991-2017)",
  xlab = "Valor Medio",
  ylab = "Porcentaje acumulado (%)",
  ylim = c(0, 100),
  xaxt = "n"
)

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

# 5. Dibujar el eje X 
axis(
  side = 1,
  at = todos_limites,
  labels = round(todos_limites, 2)
)

grid()

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

6 Indicadores Estadísticos

6.1 Indicadores de Tendencia Central

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

RMV <- na.omit(datos$resultMeanValue)
RMV <- as.numeric(RMV)

# Obtener valores atípicos según el criterio del boxplot
atipicos <- boxplot.stats(RMV)$out
n_atipicos <- length(atipicos)

# Formatear el rango de los valores atípicos 
if (n_atipicos > 0) {
  rango_atipicos <- paste0("[", round(min(atipicos), 2), " ; ", round(max(atipicos), 2), "] (Valores: ", n_atipicos, ")")
} else {
  rango_atipicos <- "No existen"
}

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

# =========================
# MODA (INTERVALO MODAL)
# =========================

# Moda 
fila_modal <- which.max(TDF_Histo_RMV$ni)
moda_intervalar <- paste0(
  "[", round(TDF_Histo_RMV$LimInf[fila_modal], 2),  
  " ; ", round(TDF_Histo_RMV$LimSup[fila_modal], 2), "]"
)

6.2 Dispersión

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

6.3 Asimetría

library(e1071)

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

6.4 Tabla de Indicadores

# =========================
# TABLA RESUMEN FINAL
# =========================

tabla_indicadores <- data.frame(
  Variable = "Valor Medio",
  Rango = paste0("[", round(min(RMV), 2), " ; ", round(max(RMV), 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
)

tabla_indicadores_gt <- tabla_indicadores %>%
  gt() %>%
  tab_header(
    title = md("*Tabla Nº3*"),
    subtitle = md("**Indicadores estadísticos de la variable valor medio 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")
  )

tabla_indicadores_gt
Tabla Nº3
Indicadores estadísticos de la variable valor medio 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
Valor Medio [0 ; 14108] 34.44 2 [0 ; 100] 30500.26 174.64 507.09 41.57 2870.26 [27.28 ; 14108] (Valores: 3346)
Autor: Grupo 3

7. Conclusión

La variable Valor Medio fluctúa entre 0 y 14108, y sus valores giran en torno a una mediana de 2, con una desviación estándar de 174.64. Dado que el coeficiente de variación es de 507.09, se trata de un conjunto de valores extremadamente heterogéneo. Los datos presentan una asimetría positiva muy pronunciada, lo que indica que los valores se acumulan de manera masiva en la parte baja de la variable. Con la presencia de valores atípicos en el intervalo de 27.28 a 14108 (3346 valores), resulta altamente perjudicial para la gestión ambiental, ya que evidencia una contaminación o concentración de contaminantes extrema y focalizada en ciertos cuerpos hídricos de Europa.