La calidad de los datos es un aspecto crítico en cualquier investigación. A menudo, la metodología de recolección de datos no se revisa adecuadamente, lo que puede introducir sesgos que afectan tanto los resultados como las conclusiones de la investigación. En el ámbito estadístico, es esencial que los datos se recojan utilizando metodologías basadas en el muestreo, ya sea probabilístico o no probabilístico, y con un entendimiento claro del dato que se desea recolectar. Esto garantiza la calidad de los datos.
Además, los datos deben ser suficientes para permitir todo tipo de análisis, produciendo resultados que sean tanto reproducibles como replicables. La recolección de datos debe estar vinculada a la creación de un sistema de información que facilite la comprensión de los datos a todos los investigadores en términos de variables recolectadas, medidas, escalas, etc. Es importante que estas variables estén estandarizadas para garantizar su usabilidad en diferentes programas computacionales para su posterior análisis.
En el contexto específico de este estudio, se busca comprender la calidad del agua en la cuenca hidrográfica del río Dagua. Para ello, se decide recolectar ciertos parámetros fisicoquímicos que, según la literatura, son relevantes para este tipo de análisis. Este documento tiene como objetivo establecer las pautas para el manejo, la recolección y el almacenamiento de datos. Además, propone rutas de análisis que comienzan con un enfoque descriptivo y la creación de un índice particular para la zona de estudio, y terminan con inferencias a través del uso de pruebas de hipótesis.
Para el trabajo de campo, se dispone del uso de la sonda HANA capaz de registrar una amplia gama de parámetros fisicoquímicos.
Estudios previos, como el realizado por Larrahondo y Russi en 2017, han demostrado a través de un Análisis de Componentes Principales (ACP) cuáles son los parámetros más útiles para la construcción de un indicador de calidad del agua. Además, hemos examinado la correlación entre los parámetros que la sonda puede medir. Esta revisión, combinada con la consulta de antecedentes para la construcción de indicadores de calidad del agua, ha llevado a que el presente estudio se centre en las siguientes variables que pueden ser medidas de forma directa mediante la sonda:
Temp_Agua, pH, mV,
ORP, EC, EC_Abs,
Res, TDS, Sal,
Sigma, Press, DO%,
DO_ppm, NH y NO.
Además, otra variable que podría ser de interés es el caudal.
El análisis de la cuenca hidrográfica del río Dagua se llevará a cabo en cinco puntos de muestreo, seleccionados por un grupo de expertos que conocen en profundidad los lugares críticos para las mediciones. Esta selección permitirá recoger la mayor variabilidad a lo largo del río.
Se utilizará una sonda para medir diferentes parámetros fisicoquímicos, como se mencionó anteriormente. Se espera que la recolección de datos dure alrededor de seis meses, durante los cuales se realizarán mediciones en tres franjas horarias: mañana (7 a 9 a.m.), mediodía (12 a 2 p.m.) y tarde-noche (4:30 - 7 p.m.).
En cada punto de muestreo, se tomarán tramos de 100 metros y se recolectarán datos cada 20 metros con la sonda. Esto significa que se obtendrán cinco mediciones por cada punto de muestreo.
Las mediciones se realizarán semanalmente, los días jueves, viernes y sábado, durante las últimas tres semanas de cada mes. En la primera semana, se tomarán datos en el punto 1 (El Carmen), en la segunda semana en los puntos 2 (La Harinera), 3 y 4 (Loboguerrero), y en la tercera semana en el punto 5 (Córdoba).
De esta manera, se estima obtener 45 datos al mes para cada una de las variables mencionadas anteriormente por punto. Dado que hay cinco puntos, se espera obtener un total de 225 datos por cada variable al mes, lo que resulta en un total de 1350 datos por variable durante los seis meses de recolección de datos.
Una vez que los datos sean recolectados, se planea realizar un resumen descriptivo que ilustre el comportamiento de las distintas variables de calidad del agua. Este análisis se llevará a cabo, como mínimo, para cada punto de muestreo.
Dado que la mayoría de las variables son cuantitativas y de carácter continuo, se revisarán las medidas de tendencia central más comunes, el análisis de correlaciones y la variabilidad a través de la desviación estándar.
En cuanto a la representación gráfica, se propone el uso de histogramas y diagramas de caja. Estos tipos de gráficos permiten comprender la posible distribución de los datos, su tendencia a generar valores atípicos y su respectiva dispersión.
Finalmente, se revisarán las correlaciones entre variables con el objetivo de evitar el análisis de variables que estén capturando una variabilidad similar, lo cual podría provocar un sesgo en el índice.
El primer paso consiste en transformar el dataframe data de formato ancho a largo, esto facilita el uso de los paquetes de visualización en R y la creación de tablas.
Las brechas se definen para cada variable y se almacenan en una lista
llamada brechas. Si el valor medido de una variable se encuentra dentro
de su brecha correspondiente, se asigna el valor 1 a una nueva columna
llamada cumplimiento_brecha. Si el valor medido no cumple
con la brecha, se asigna el valor 0.
Los ponderadores se establecen mediante comité de expertos.
El indicador se calcula multiplicando el
cumplimiento_brecha por el ponderador correspondiente.
Luego, se agrupa el dataset por punto de muestreo, fecha de recolección,
distancia cada 100 metros, franja horaria y campaña de recolección. El
objetivo es generar subgrupos donde se pueda precisar cada registro
obtenido ya que cualquier medición realizada con la sonda permite
obtener el valor del índice.
En cada subgrupo, se suman los valores obtenidos al ponderar y multiplicar las variables. Finalmente, se promedia el resultado de cada subgrupo para obtener el resultado final del indicador.
Para esta interpretación se definen algunos umbrales que sirven para definir si el valor del indicador corresponde a una calidad baja, moderada o alta.
Con base en la metodología descrita, se construye un RMarkdown. Este permite conocer toda la base de programación usada realmente para la obtención de resultados. También aclarar que los resultados se pueden adecuar a las necesidades de la comunidad e investigadores según los grupos a nivel temporal o espacial que se deseen crear, teniendo en cuenta el diseño muestral.
library(tidyverse)
library(skimr)
library(stringi)
library(highcharter)
library(readxl)
library(heatmaply)
library(plotly)
library(FSA)
library(dplyr)
library(purrr)
library(broom)
library(ggpubr)
library(kableExtra)
| Name | data |
| Number of rows | 1350 |
| Number of columns | 23 |
| _______________________ | |
| Column type frequency: | |
| character | 8 |
| numeric | 15 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| Punto | 0 | 1 | 1 | 1 | 0 | 5 | 0 |
| Fecha | 0 | 1 | 10 | 10 | 0 | 54 | 0 |
| Dia | 0 | 1 | 6 | 7 | 0 | 3 | 0 |
| Semana | 0 | 1 | 1 | 1 | 0 | 3 | 0 |
| Dist | 0 | 1 | 2 | 3 | 0 | 5 | 0 |
| Franja | 0 | 1 | 5 | 9 | 0 | 3 | 0 |
| Hora | 0 | 1 | 1 | 17 | 0 | 30 | 0 |
| Campaña | 0 | 1 | 1 | 1 | 0 | 6 | 0 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| Temp_Agua | 0 | 1 | 24.55 | 2.51 | 18.99 | 22.36 | 24.91 | 26.26 | 29.84 | ▃▅▆▇▂ |
| pH | 0 | 1 | 8.09 | 0.41 | 6.81 | 7.84 | 8.14 | 8.37 | 9.39 | ▁▃▇▅▁ |
| mV | 0 | 1 | -61.15 | 23.56 | -109.20 | -75.20 | -61.25 | -43.40 | 2.00 | ▃▆▇▅▁ |
| ORP | 0 | 1 | 216.27 | 69.06 | 76.90 | 159.33 | 245.20 | 267.48 | 356.00 | ▃▃▂▇▂ |
| EC | 0 | 1 | 156.82 | 39.78 | 45.00 | 135.00 | 160.00 | 189.00 | 211.00 | ▁▃▃▇▇ |
| EC_Abs | 0 | 1 | 156.11 | 42.94 | 45.00 | 125.25 | 163.00 | 187.00 | 226.00 | ▁▃▆▇▆ |
| Res | 0 | 1 | 6965.37 | 2487.19 | 4739.00 | 5291.00 | 6250.00 | 7410.00 | 22220.00 | ▇▁▁▁▁ |
| TDS | 0 | 1 | 78.43 | 19.88 | 23.00 | 68.00 | 80.00 | 95.00 | 106.00 | ▁▃▃▇▇ |
| Sal | 0 | 1 | 0.07 | 0.02 | 0.02 | 0.06 | 0.07 | 0.09 | 0.10 | ▁▃▃▇▇ |
| Sigma | 0 | 1 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | ▁▁▇▁▁ |
| Press | 0 | 1 | 13.52 | 0.58 | 12.57 | 13.26 | 13.62 | 13.65 | 14.60 | ▃▅▇▁▃ |
| DO% | 0 | 1 | 118.55 | 27.52 | 68.40 | 106.93 | 116.05 | 128.90 | 391.30 | ▇▂▁▁▁ |
| DO_ppm | 0 | 1 | 9.09 | 2.28 | 5.13 | 8.09 | 8.81 | 10.10 | 30.63 | ▇▂▁▁▁ |
| NH | 0 | 1 | 0.09 | 0.28 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 | ▇▁▁▁▁ |
| NO | 0 | 1 | 1.83 | 0.99 | 0.00 | 1.00 | 2.00 | 2.00 | 8.00 | ▃▇▁▁▁ |
Se inicia con la interpretación del resumen de los datos depurados.
data.Respecto a las variables categoricas
El resumen muestra que todas las variables, incluyendo
Punto, Fecha, Dia,
Semana, Dist, Franja,
Hora y Campaña, se encuentran sin valores
faltantes. Además, la longitud de las cadenas de texto en estas
variables también varía, desde 1 carácter para ‘Punto’ y ‘Semana’, hasta
17 caracteres para ‘Hora’. Importante destacar que no hay espacios en
blanco ni valores vacíos en ninguna de las variables, lo cual indica una
buena calidad de los datos.
Finalmente frente a las variables continuas
El resumen muestra que las variables Temp_Agua,
pH, mV, ORP, EC,
EC_Abs, Res, TDS,
Sal, Sigma, Press,
DO%, DO_ppm, NH y NO
están completamente llenas sin valores faltantes. Las variables varían
en términos de sus valores mínimos y máximos, así como en sus cuartiles,
lo que proporciona una idea de la distribución de los datos. Por
ejemplo, la variable Temp_Agua tiene un valor mínimo de
\(18.99\) y un valor máximo de \(29.84\), mientras que la variable
pH tiene un valor mínimo de \(6.81\) y un valor máximo de \(9.39\).
La variable Res tiene un rango de valores en los miles,
con un valor mínimo de \(4739\) y un
valor máximo de \(22220\). Por otro
lado, la variable Temp_Agua tiene valores que son números
mucho más pequeños en comparación, como se mostró anteriormente. Además,
hay variables como mV que incluso tienen valores negativos,
con un valor mínimo de \(-109.20\) y un
valor máximo de \(2.00\). Esto podría
indicar que esta variable mide una cantidad que puede tener tanto
valores positivos como negativos.
Es importante tener en cuenta estos rangos al analizar los datos, ya que pueden afectar los resultados. Por ejemplo, las variables con rangos más grandes pueden tener una mayor variabilidad o dispersión en sus datos. Para el indicador se tendrán en cuenta esta información ya que es importante capturar la variabilidad existente en cada variable pero no tanto su escala de medición.
Tras obtener estos resultados, el comité de expertos se reúne para seleccionar las variables pertinentes. Una vez que se hayan definido estas variables, se procede a analizar su variabilidad.
skim(caudales)
| Name | caudales |
| Number of rows | 270 |
| Number of columns | 3 |
| _______________________ | |
| Column type frequency: | |
| character | 2 |
| numeric | 1 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| Punto | 0 | 1 | 1 | 1 | 0 | 5 | 0 |
| Hora | 0 | 1 | 1 | 2 | 0 | 3 | 0 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| Caudal | 0 | 1 | 20.82 | 21.66 | 4.56 | 7.21 | 9.14 | 17.9 | 72.55 | ▇▁▁▁▁ |
La variación entre caudales medidos está en \(21.6\) metros cúbicos, siendo el mínimo \(4.56\) y el máximo \(72.6\). Se observa una distribución asimetrica con cola derecha, por lo que se asume que los datos en su conjunto para todo el río carecen de normalidad.
# Calcula la media de Caudal por Punto
media_caudales <- aggregate(Caudal ~ Punto, data = caudales, FUN = mean)
median_caudales <- aggregate(Caudal ~ Punto, data = caudales, FUN = median)
# Muestra el resultado
print(median_caudales)
## Punto Caudal
## 1 1 7.010
## 2 2 7.205
## 3 3 8.815
## 4 4 17.060
## 5 5 60.895
Se calcula el promedio para los caudales, la tabla muestra como el punto de muestre 5, en general posee el caudal más lejos con diferencia sobre los demás puntos de muestreo.
variables <- c('pH', 'TDS', 'DO_ppm', 'NO', 'NH', 'ORP')
data_cor <- select(data, all_of(variables))
# Estandarizar todas las variables en el dataframe
data_cor_scaled <- as.data.frame(scale(data_cor))
# Convertir el dataframe a formato largo
data_cor_long <- reshape2::melt(data_cor)
data_cor_scaled_long <- reshape2::melt(data_cor_scaled)
Se construyen boxplots de las variables continuas luego de la selección de variables realizada por comité de expertos
# Crear el gráfico de boxplot interactivo
plot_ly(data_cor_long, x = ~variable, y = ~value, type = "box")
Por la escala resulta casi imposible determinar como se comportan las variables, por lo que se decide estandarizar las variables y construir nuevamente el boxplot
# Crear el gráfico de boxplot interactivo
plot_ly(data_cor_scaled_long, x = ~variable, y = ~value, type = "box")
Este gráfico muestra los datos luego de ser estandarizados, la idea es analizar cada variable respecto a su desviación estándar.
Podemos observar que las variables pH, TDS,
NO y ORP, poseen su mediana por encima de la
media indicado que no hay simetría en los datos y un posible sesgo
negativo en ellas. También destacar que todas presentan presencia de
outliers excepto por ORP.
Para revisar las variables de forma bivariada se realiza una matriz de correlación para las variables continuas, las categoricas se usarán más adelante para definir si hay diferencias significativas entre los puntos de muestreo u otra condición inherente en la medición tomada por los investigadores
# Calcular la matriz de correlación de Spearman
cor_mat <- cor(data_cor, method = "spearman")
cor_mat
## pH TDS DO_ppm NO NH ORP
## pH 1.0000000 0.7140694 -0.48399271 0.19629620 -0.26401274 -0.50057957
## TDS 0.7140694 1.0000000 -0.47481793 0.32048825 -0.20863567 -0.54601753
## DO_ppm -0.4839927 -0.4748179 1.00000000 -0.25762190 0.01750588 0.63708956
## NO 0.1962962 0.3204882 -0.25762190 1.00000000 0.07107813 -0.37033416
## NH -0.2640127 -0.2086357 0.01750588 0.07107813 1.00000000 0.04249878
## ORP -0.5005796 -0.5460175 0.63708956 -0.37033416 0.04249878 1.00000000
# Crear el gráfico interactivo de la matriz de correlación
heatmaply(cor_mat, xlab = "Variables", ylab = "Variables")
La matriz de correlación calculada mediante el coeficiente de Spearman proporciona una medida de la relación monótona entre cada par de variables.
Las relaciones fuertes entre variables son pH y
TDS con una correlación positiva fuerte (0.71). Esto
significa que cuando el pH aumenta, los sólidos disueltos también
tienden a aumentar. Además de DO_ppm y ORP con
una correlación positiva fuerte (0.64). Esto sugiere que cuando el
DO_ppm aumenta, el ORP también tiende a aumentar. Mencionar también que
los TDS y ORP poseen una correlación negativa
fuerte (-0.55). Esto indica que cuando los TDS aumentan, el ORP tiende a
disminuir.
Es importante tener en cuenta que una correlación cercana a \(0\) indica que no hay una relación lineal fuerte entre las variables. Además, una correlación positiva indica una relación directa (a medida que una variable aumenta, la otra también lo hace), mientras que una correlación negativa indica una relación inversa (a medida que una variable aumenta, la otra disminuye). Sin embargo, la correlación no implica causalidad, por lo que aunque dos variables estén fuertemente correlacionadas, no significa necesariamente que una cause el cambio en la otra, a menos que hayan estudios que demuestren que si es así.
Para el indicador, se decide trabajar con las variables de forma individual, ya que, como se ha observado, aunque existen variables con correlaciones fuertes, estas no son lo suficientemente altas como para suponer que están explicando la misma variabilidad entre ellas. Lo anterior se revisa con el fin de evitar sesgos creados por variables que puedan ser multicolineales.
Los histogramas que se observan en el análisis univariado de las variables continuas evidencian que no todas poseen simetría. Por lo tanto, se procede a usar pruebas no paramétricas basadas en la comparación de medianas y no de medias, como se acostumbra en los estudios que no revisan la distribución de los datos por variable. Se decide realizar la prueba de Kruskal-Wallis para el contraste de medianas.
La prueba de Kruskal-Wallis permite determinar si hay diferencias significativas entre variables. Sin embargo, no logra determinar, en este caso, donde se comparan las medianas entre puntos de muestreo, cuáles son los puntos que presentan diferencias significativas. Por lo que, para precisar el análisis, se realiza la prueba post hoc de Dunn, la cual se puede entender como un complemento de la prueba anterior.
df <-data
df$Punto <- as.factor(df$Punto)
# Define las variables
variables <- c("TDS", "pH", "DO_ppm", "NO", "NH", "ORP")
# Función para realizar la prueba de Kruskal-Wallis y determinar la significancia
kruskal_test <- function(var, data) {
formula <- as.formula(paste(var, "~ Punto"))
test <- kruskal.test(formula, data = data)
tidy_result <- tidy(test)
# Añade una columna para indicar si el resultado es significativo
tidy_result <- tidy_result %>%
mutate(Variable = var,
Significativo = ifelse(p.value < 0.05, "Si", "No"))
return(tidy_result)
}
# Aplica la prueba de Kruskal-Wallis a cada variable
resultados_kruskal <- map_dfr(variables, kruskal_test, data = df)
# Muestra los resultados de la prueba de Kruskal-Wallis
resultados_kruskal %>%
kable("html", escape = F, align = "c") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = F)
| statistic | p.value | parameter | method | Variable | Significativo |
|---|---|---|---|---|---|
| 766.1874 | 0 | 4 | Kruskal-Wallis rank sum test | TDS | Si |
| 587.8235 | 0 | 4 | Kruskal-Wallis rank sum test | pH | Si |
| 312.7497 | 0 | 4 | Kruskal-Wallis rank sum test | DO_ppm | Si |
| 156.2040 | 0 | 4 | Kruskal-Wallis rank sum test | NO | Si |
| 526.4390 | 0 | 4 | Kruskal-Wallis rank sum test | NH | Si |
| 188.5458 | 0 | 4 | Kruskal-Wallis rank sum test | ORP | Si |
La tabla proporcionada demuestra de manera concluyente que todas las variables exhiben diferencias significativas al comparar sus medianas entre los distintos puntos de muestreo. Dada la considerable distancia espacial entre los puntos de muestreo, así como las variaciones temporales inherentes a las mediciones, este resultado era predecible.
Es importante destacar que las similitudes en los datos podrían ser escasas debido a los posibles residuos de materiales que el agua del río puede transportar.
A continuación, se procede a examinar cada variable por punto de medición para determinar cuáles son las variables y los puntos en los que se observan diferencias significativas.
# Función para realizar la prueba de Dunn y determinar la significancia
dunn_test <- function(var, data) {
# Realiza la prueba de Dunn
dunn_result <- dunnTest(as.formula(paste(var, "~ Punto")), data = data)
# Convierte los resultados a un formato tidy y añade una columna para indicar si el resultado es significativo
tidy_result <- dunn_result$res %>%
rownames_to_column(var = "Comparacion") %>%
mutate(Variable = var,
Significativo = ifelse(P.adj < 0.05, "Si", "No"))
return(tidy_result)
}
# Aplica la prueba de Dunn a cada variable
resultados_dunn <- map_dfr(variables, dunn_test, data = df)
# Selecciona solo las columnas de interés
resultados_dunn <- resultados_dunn %>%
select(Comparison, Variable, Significativo)
# Muestra los resultados de la prueba de Dunn
resultados_dunn %>%
kable("html", escape = F, align = "c") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = F)
| Comparison | Variable | Significativo |
|---|---|---|
| 1 - 2 | TDS | Si |
| 1 - 3 | TDS | Si |
| 2 - 3 | TDS | Si |
| 1 - 4 | TDS | Si |
| 2 - 4 | TDS | Si |
| 3 - 4 | TDS | No |
| 1 - 5 | TDS | Si |
| 2 - 5 | TDS | Si |
| 3 - 5 | TDS | Si |
| 4 - 5 | TDS | Si |
| 1 - 2 | pH | Si |
| 1 - 3 | pH | Si |
| 2 - 3 | pH | No |
| 1 - 4 | pH | Si |
| 2 - 4 | pH | No |
| 3 - 4 | pH | No |
| 1 - 5 | pH | Si |
| 2 - 5 | pH | Si |
| 3 - 5 | pH | Si |
| 4 - 5 | pH | Si |
| 1 - 2 | DO_ppm | No |
| 1 - 3 | DO_ppm | No |
| 2 - 3 | DO_ppm | No |
| 1 - 4 | DO_ppm | No |
| 2 - 4 | DO_ppm | No |
| 3 - 4 | DO_ppm | No |
| 1 - 5 | DO_ppm | Si |
| 2 - 5 | DO_ppm | Si |
| 3 - 5 | DO_ppm | Si |
| 4 - 5 | DO_ppm | Si |
| 1 - 2 | NO | No |
| 1 - 3 | NO | No |
| 2 - 3 | NO | No |
| 1 - 4 | NO | No |
| 2 - 4 | NO | No |
| 3 - 4 | NO | No |
| 1 - 5 | NO | Si |
| 2 - 5 | NO | Si |
| 3 - 5 | NO | Si |
| 4 - 5 | NO | Si |
| 1 - 2 | NH | Si |
| 1 - 3 | NH | Si |
| 2 - 3 | NH | No |
| 1 - 4 | NH | Si |
| 2 - 4 | NH | No |
| 3 - 4 | NH | No |
| 1 - 5 | NH | Si |
| 2 - 5 | NH | No |
| 3 - 5 | NH | No |
| 4 - 5 | NH | No |
| 1 - 2 | ORP | Si |
| 1 - 3 | ORP | No |
| 2 - 3 | ORP | No |
| 1 - 4 | ORP | No |
| 2 - 4 | ORP | Si |
| 3 - 4 | ORP | No |
| 1 - 5 | ORP | Si |
| 2 - 5 | ORP | Si |
| 3 - 5 | ORP | Si |
| 4 - 5 | ORP | Si |
La prueba de Dunn es una prueba post-hoc que se utiliza después de una prueba de Kruskal-Wallis para determinar qué grupos son significativamente diferentes entre sí. La hipótesis nula de la prueba de Dunn es que no hay diferencia entre los grupos.
Aquí está la interpretación de los resultados:
Para TDS hay diferencias significativas entre todos los
pares de puntos. Para pH hay diferencias significativas
entre los pares de puntos \(1-2\),
\(1-3\), \(1-4\), \(1-5\), \(2-5\) y \(3-5\). No hay diferencias significativas
entre los pares de puntos \(2-3\),
\(2-4\) y \(3-4\). Para DO_ppm hay
diferencias significativas entre los pares de puntos \(1-5\), \(2-5\) y \(3-5\). No hay diferencias significativas
entre los pares de puntos \(1-2\),
\(1-3\), \(1-4\), \(2-3\), \(2-4\) y \(3-4\). Para NO hay diferencias
significativas entre los pares de puntos \(1-5\), \(2-5\) y \(3-5\). No hay diferencias significativas
entre los pares de puntos \(1-2\),
\(1-3\), \(1-4\), \(2-3\), \(2-4\) y \(3-4\). Para NH hay diferencias
significativas entre los pares de puntos \(1-2\), \(1-3\), \(1-4\) y \(1-5\). No hay diferencias significativas
entre los pares de puntos \(2-3\),
\(2-4\), \(2-5\), \(3-4\), \(3-5\) y \(4-5\). ORP Hay diferencias
significativas entre todos los pares de puntos excepto \(1-3\) y \(1-4\).
Es notable que para las variables DO_ppm,
NO, NH y ORP, siempre hay una
diferencia significativa cuando se compara el punto \(1\) con los demás puntos. Esto sugiere que
el punto \(1\) puede tener
características únicas en comparación con los otros puntos para estas
variables.
Ahora, para los caudales se realiza el siguiente análisis:
# Aplicamos la prueba de Kruskal-Wallis
kruskal_result <- kruskal.test(Caudal ~ Punto, data = caudales)
# Convertimos el resultado de la prueba de Kruskal-Wallis a un formato tidy
tidy_kruskal <- broom::tidy(kruskal_result)
# Muestra los resultados de la prueba de Kruskal-Wallis
tidy_kruskal %>%
kable("html", escape = F, align = "c") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = F)
| statistic | p.value | parameter | method |
|---|---|---|---|
| 234.2759 | 0 | 4 | Kruskal-Wallis rank sum test |
# Aplicamos la prueba de Dunn
dunn_result <- dunnTest(Caudal ~ as.factor(Punto), data = caudales)
# Convertimos el resultado de la prueba de Dunn a un formato tidy
tidy_dunn <- dunn_result$res %>%
rownames_to_column(var = "Comparacion") %>%
mutate(Significativo = ifelse(P.adj < 0.05, "Si", "No"))
# Muestra los resultados de la prueba de Dunn
tidy_dunn %>%
kable("html", escape = F, align = "c") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = F)
| Comparacion | Comparison | Z | P.unadj | P.adj | Significativo |
|---|---|---|---|---|---|
| 1 | 1 - 2 | -0.7011935 | 0.4831823 | 0.4831823 | No |
| 2 | 1 - 3 | -4.9120512 | 0.0000009 | 0.0000045 | Si |
| 3 | 2 - 3 | -4.2108577 | 0.0000254 | 0.0001018 | Si |
| 4 | 1 - 4 | -9.0317168 | 0.0000000 | 0.0000000 | Si |
| 5 | 2 - 4 | -8.3305233 | 0.0000000 | 0.0000000 | Si |
| 6 | 3 - 4 | -4.1196656 | 0.0000379 | 0.0001138 | Si |
| 7 | 1 - 5 | -12.6448964 | 0.0000000 | 0.0000000 | Si |
| 8 | 2 - 5 | -11.9437030 | 0.0000000 | 0.0000000 | Si |
| 9 | 3 - 5 | -7.7328453 | 0.0000000 | 0.0000000 | Si |
| 10 | 4 - 5 | -3.6131796 | 0.0003025 | 0.0006049 | Si |
El resultado de la prueba de Kruskal-Wallis indica que hay una
diferencia estadísticamente significativa en la variable
Caudal entre al menos dos de los grupos definidos por la
variable Punto.
Esto se debe a que el valor p (p-value) es menor a 0.05 (en este caso, p < 2.2e-16), lo que generalmente se considera el umbral para la significancia estadística.
Para la prueba de Dunn se observa que solo la diferencia entre los puntos \(1-2\) no es significativa, para el resto se evidencian diferencias significativas entre los caudales en los diferentes puntos de recolección.
(Posible falta de diferencia entre los puntos 1-2 por tema de que parte del río se usa para una turbina).
Se debe iniciar para la construcción del indicador pasando de ancho a largo los datos que se han estado trabajando.
# Selecciona solo las columnas de interés
data_seleccionada <- df %>%
select(Punto, Fecha, Dia, Semana, Dist, Franja, Hora, Campaña, TDS, pH, ORP, DO_ppm, NH, NO)
# Convierte el dataframe de formato ancho a largo
data_largo <- data_seleccionada %>%
pivot_longer(cols = c(TDS, pH, ORP, DO_ppm, NH, NO), names_to = "Variable", values_to = "Valor")
# Crea un dataframe con los ponderadores
ponderadores <- data.frame(
Variable = c("pH", "TDS", "DO_ppm", "NO", "NH", "ORP"),
Ponderador = c(0.21, 0.21, 0.1, 0.12, 0.12, 0.24)
)
# Une los ponderadores al dataframe
data_largo <- data_largo %>%
left_join(ponderadores, by = "Variable")
Ahora se procede con la construcción del indicador. Para ello, se establecen diferentes brechas, las cuales se definen por variable mediante la revisión de literatura.
El cálculo del indicador se realiza tal como se describe en el punto 5 del presente informe. Se recomienda referirse a esa sección para obtener una comprensión detallada del proceso.
# Define las brechas para cada variable
brechas <- list(
"pH" = c(5, 8), # Fuera de 4.5 y 9 es un 0
"TDS" = c(-Inf, 300), # Mayor a 300 es un 0
"DO_ppm" = c(5, Inf), # Menor a 5 es un 0
"NO" = c(-Inf, 10), # Mayor a 10 es un 0
"NH" = c(-Inf, 0.1), # Mayor a 0.1 es un 0
"ORP" = c(500, Inf) # Por debajo de 500 es un 0
)
# Función para calcular el cumplimiento de la brecha
cumplimiento_brecha <- function(var, valor) {
if (valor >= brechas[[var]][1] & valor <= brechas[[var]][2]) {
return(1)
} else {
return(0)
}
}
# Aplica la función a cada variable
data_largo <- data_largo %>%
mutate(cumplimiento_brecha = mapply(cumplimiento_brecha, Variable, Valor))
# Multiplica el cumplimiento de la brecha por el ponderado por variable
data_largo$ponderado <- data_largo$cumplimiento_brecha * data_largo$Ponderador
# Filtra las filas donde la variable está en la lista de interés
data_filtrada <- data_largo %>%
filter(Variable %in% c("pH", "TDS", "DO_ppm", "NO", "NH", "ORP"))
# Calcula la suma de ponderado por cada grupo
data_resumen <- data_filtrada %>%
group_by(Punto, Fecha, Dia, Semana, Dist, Franja, Hora, Campaña) %>%
summarise(Suma_Ponderado = sum(ponderado, na.rm = TRUE), .groups = "drop")
# Suma las medias para obtener el indicador final
indicador_final <- median(data_resumen$Suma_Ponderado)
# Clasifica el indicador final
clasificacion <- case_when(
indicador_final >= 0.65 ~ "Calidad Alta",
indicador_final >= 0.35 ~ "Calidad Moderada",
TRUE ~ "Calidad Baja"
)
# Crea un dataframe con el indicador final y la clasificación
resultado_final <- data.frame(Indicador_Final = indicador_final, Clasificacion = clasificacion)
# Muestra el resultado final usando kable
resultado_final %>%
kable("html", escape = F, align = "c") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = F)
| Indicador_Final | Clasificacion |
|---|---|
| 0.55 | Calidad Moderada |
Finalmente para obtener el resultado por puntos de muestreo se tiene lo siguiente:
# Calcula la suma de ponderado por cada grupo
data_resumen <- data_filtrada %>%
group_by(Punto, Fecha, Dia, Semana, Dist, Franja, Hora) %>%
summarise(Suma_Ponderado = sum(ponderado, na.rm = TRUE), .groups = "drop")
# Calcula el indicador para cada Punto
indicadores <- data_resumen %>%
group_by(Punto) %>%
summarise(Indicador = mean(Suma_Ponderado))
# Clasifica el indicador para cada Punto
indicadores$Clasificacion <- case_when(
indicadores$Indicador >= 0.65 ~ "Calidad Alta",
indicadores$Indicador >= 0.35 ~ "Calidad Moderada",
TRUE ~ "Calidad Baja"
)
# Muestra los indicadores y su clasificación usando kable
indicadores %>%
kable("html", escape = F, align = "c") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = F)
| Punto | Indicador | Clasificacion |
|---|---|---|
| 1 | 0.6561111 | Calidad Alta |
| 2 | 0.5912222 | Calidad Moderada |
| 3 | 0.5850000 | Calidad Moderada |
| 4 | 0.5694444 | Calidad Moderada |
| 5 | 0.7226667 | Calidad Alta |
# Calcula la suma de ponderado por cada grupo
data_resumen <- data_filtrada %>%
group_by(Punto, Fecha, Dia, Semana, Dist, Franja, Hora, Campaña) %>%
summarise(Suma_Ponderado = sum(ponderado, na.rm = TRUE), .groups = "drop")
# Calcula el indicador para cada Punto
indicadores <- data_resumen %>%
group_by(Campaña, Punto) %>%
summarise(Indicador = mean(Suma_Ponderado), .groups = "drop")
# Clasifica el indicador para cada Punto
indicadores$Clasificacion <- case_when(
indicadores$Indicador >= 0.65 ~ "Calidad Alta",
indicadores$Indicador >= 0.35 ~ "Calidad Moderada",
TRUE ~ "Calidad Baja"
)
# Muestra los indicadores y su clasificación usando kable
indicadores %>%
kable("html", escape = F, align = "c") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = F)
| Campaña | Punto | Indicador | Clasificacion |
|---|---|---|---|
| 1 | 1 | 0.6386667 | Calidad Moderada |
| 1 | 2 | 0.5920000 | Calidad Moderada |
| 1 | 3 | 0.5500000 | Calidad Moderada |
| 1 | 4 | 0.6106667 | Calidad Moderada |
| 1 | 5 | 0.7553333 | Calidad Alta |
| 2 | 1 | 0.5980000 | Calidad Moderada |
| 2 | 2 | 0.6153333 | Calidad Moderada |
| 2 | 3 | 0.6666667 | Calidad Alta |
| 2 | 4 | 0.5500000 | Calidad Moderada |
| 2 | 5 | 0.7553333 | Calidad Alta |
| 3 | 1 | 0.6260000 | Calidad Moderada |
| 3 | 2 | 0.6200000 | Calidad Moderada |
| 3 | 3 | 0.6200000 | Calidad Moderada |
| 3 | 4 | 0.5873333 | Calidad Moderada |
| 3 | 5 | 0.7600000 | Calidad Alta |
| 4 | 1 | 0.6613333 | Calidad Alta |
| 4 | 2 | 0.5500000 | Calidad Moderada |
| 4 | 3 | 0.5500000 | Calidad Moderada |
| 4 | 4 | 0.5593333 | Calidad Moderada |
| 4 | 5 | 0.7600000 | Calidad Alta |
| 5 | 1 | 0.6526667 | Calidad Alta |
| 5 | 2 | 0.5500000 | Calidad Moderada |
| 5 | 3 | 0.5500000 | Calidad Moderada |
| 5 | 4 | 0.5593333 | Calidad Moderada |
| 5 | 5 | 0.5500000 | Calidad Moderada |
| 6 | 1 | 0.7600000 | Calidad Alta |
| 6 | 2 | 0.6200000 | Calidad Moderada |
| 6 | 3 | 0.5733333 | Calidad Moderada |
| 6 | 4 | 0.5500000 | Calidad Moderada |
| 6 | 5 | 0.7553333 | Calidad Alta |
Se obtienen los resultados del indicador de calidad del agua para cada campaña según el punto de muestreo, para evidenciar el comportamiento se construye la siguiente figura:
# Crea una lista para almacenar las gráficas
lista_graficas <- list()
for(i in unique(indicadores$Punto)) {
lista_graficas[[i]] <- ggplot(subset(indicadores, Punto == i), aes(x = Campaña, y = Indicador, group = 1)) +
geom_line() +
geom_point() +
annotate(geom = "rect", xmin = -Inf, xmax = Inf, ymin = 0, ymax = 0.35, alpha = 0.1, fill = "red") + # Rectángulo rojo
annotate(geom = "rect", xmin = -Inf, xmax = Inf, ymin = 0.35, ymax = 0.65, alpha = 0.3, fill = "grey") + # Rectángulo gris
annotate(geom = "rect", xmin = -Inf, xmax = Inf, ymin = 0.65, ymax = 1, alpha = 0.1, fill = "green") + # Rectángulo verde
labs(title = paste("Punto", i),
x = "Campaña",
y = "Indicador") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5)) + # Centra el título
scale_y_continuous(limits = c(0, 1)) # Ajusta la escala del eje Y a valores entre 0 y 1
}
# Combina todas las gráficas en una sola imagen
grafica_final <- ggarrange(plotlist = lista_graficas, ncol = 2, nrow = 3)
# Muestra la gráfica final
print(grafica_final)
Finalmente, la figura representa la variación del indicador mostrada por
cada punto según las diferentes campañas. Como era de esperarse, el
comportamiento del indicador es estable en la mayoría de los puntos a lo
largo del tiempo. Sin embargo, resulta curioso el incremento en la
contaminación registrado en el punto 5 durante la campaña 5. Este
incremento podría resultar en una gran afectación medioambiental si se
tiene en cuenta que el caudal en este punto es casi 6 veces más grande
que en los puntos 1, 2 o 3. Sería valioso investigar a mayor profundidad
qué pudo causar esta variación tan significativa en el deterioro de la
calidad del agua.