Cargar datos al ambiente de trabajo

Antes de proceder con el análisis estadístico, cargamos los datos al ambiente de trabajo de RStudio utilizando el comando read.csv(). El código a continuación lee los datos del archivo fisicoquimica2024.csv y los almacena en un objeto llamado fisqui. Además, se convierte la variable fecha al tipo Date.

Si recibe un mensaje de error al intentar cargar los datos, asegúrese de que el archivo fisicoquimica2024.csv se encuentra en el directorio de trabajo de RStudio.

# leer datos
fisqui <- read.csv("fisicoquimica2024.csv", header = TRUE, sep = ",")
head(fisqui)
##      fecha sitio posicion porcO TporcO concO TconcO cond1 Tcond1 cond2 Tcond2
## 1 20240315  maga    orizq  60.5   26.4 4.186   26.4 256.9   26.4 253.2   26.5
## 2 20240315  maga    orizq  58.8   26.4 4.730   26.4 259.8   26.4 256.0   26.4
## 3 20240315  maga    orizq  59.5   26.4 4.760   26.4 259.8   26.4 256.0   26.4
## 4 20240315  maga    mitad  64.9   26.4 5.250   26.4    NA   26.4    NA   26.4
## 5 20240315  maga    mitad  65.5   26.4 5.230   26.4 259.3   26.4 255.8   26.4
## 6 20240315  maga    mitad  65.8   26.4 5.170   26.4 259.1   26.4 255.3   26.4
##   salinidad Tsalinidad
## 1       0.1       26.4
## 2       0.1       26.4
## 3       0.1       26.4
## 4       0.1       26.4
## 5       0.1       26.4
## 6       0.1       26.4
# Convert fecha to Date type
fisqui$fecha <- as.Date(as.character(fisqui$fecha), format = "%Y%m%d")

Análisis exploratorio de datos de la variable porcO (porcentaje de saturación de oxígeno)

Un primer análisis global nos sirve de control de calidad de los datos. Vamos a calcular la media, mediana, desviación estándar, mínimo y máximo de la variable porcO. Si en el mínimo o máximo encontramos valores extremos, es posible que haya errores en la medición o en la entrada de datos. En ese caso, es recomendable revisar los datos crudos y corregir los errores o eliminar datos sobre los que tenemos evidencia de error de medición.

# Análisis exploratorio de datos
summary(fisqui$porcO)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   58.80   66.45   71.00   71.84   79.10   81.90

Estadísticas de la variable porcO por grupos por fecha y posición.

A continuación, calculamos la media y el error estándar de la variable porcO agrupando por fecha y posición en el río. Estos valores nos permiten visualizar la tendencia central (media) y dispersión (error estándar) de la variable porcO en función de la fecha y la posición en el río.

Los datos corresponden a tres fechas de mediciones en tres posiciones diferentes en el río: orizq = orilla izquierda, mitad = centro del río, order = orilla derecha.

El código primero crea una función llamada calc_stats que calcula la media y el error estándar de un vector numérico (la variable porcO). Luego, se aplica esta función a la variable porcO agrupando por fecha y posición; se convierte el resultado en un data frame llamado result_df y finalmente se crea una tabla utilizando el paquete gt.

# Function to calculate mean and standard error
calc_stats <- function(x) {
    mean_val <- mean(x, na.rm = TRUE)
    se_val <- sd(x, na.rm = TRUE) / sqrt(sum(!is.na(x)))
    return(c(mean = mean_val, se = se_val))
}

# Calculate statistics
stats_porcO <- by(fisqui$porcO, list(fisqui$fecha, fisqui$posicion), calc_stats)

# Convert to data frame
result <- do.call(rbind, stats_porcO)
result_df <- data.frame(
    fecha = rep(dimnames(stats_porcO)[[1]], each = length(dimnames(stats_porcO)[[2]])),
    posicion = rep(dimnames(stats_porcO)[[2]], times = length(dimnames(stats_porcO)[[1]])),
    mean_porcO = result[, "mean"],
    se_porcO = result[, "se"]
)


# If you have the gt package installed, you can create a gt table like this:
library(gt)
library(webshot2)
# Create gt table
tabla_gt <- gt(result_df) %>%
  fmt_number(
    columns = c("mean_porcO", "se_porcO"),
    decimals = 2
  ) %>%
  cols_label(
    fecha = "Fecha",
    posicion = "Posición",
    mean_porcO = "Media % O",
    se_porcO = "Error Estándar % O"
  )
tabla_gt
Fecha Posición Media % O Error Estándar % O
2024-03-15 mitad 65.40 0.26
2024-03-15 order 80.27 0.28
2024-03-15 orizq 71.13 0.15
2024-04-19 mitad 66.63 0.27
2024-04-19 order 78.70 0.76
2024-04-19 orizq 70.90 0.06
2024-08-30 mitad 59.60 0.49
2024-08-30 order 80.73 0.58
2024-08-30 orizq 73.17 1.53
# save the table as an html file
gtsave(tabla_gt, "tabla_porcO.html")

Gráfica de la media de porcO en función de la fecha y la posición.

Usaremos la librería ggplot2 para crear una gráfica de puntos y líneas que muestre la media de la variable porcO en función de la fecha y la posición en el río. Esta gráfica nos permite visualizar la tendencia de la variable porcO a lo largo del tiempo y en diferentes posiciones en el río.

# Gráfica de la media de porcO en función de la fecha y la posición
library(ggplot2)
library(dplyr)


# Assuming 'data' is your dataframe
fisqui %>%
  group_by(fecha, posicion) %>%
  summarise(
    porcO = mean(porcO, na.rm = TRUE),
    se_porcO = sd(porcO, na.rm = TRUE) / sqrt(n()),
    .groups = 'drop'
  ) %>%
  ggplot(aes(x = fecha, y = porcO, color = posicion)) +
  geom_point() +
  geom_line() +
  labs(x = "Fecha", y = "Porcentaje Oxígeno", color = "Posición") +
  theme_minimal()

# save the plot as an image
ggsave("plot_porcO.png")

Prueba de hipótesis para la variable porcO.

Para evaluar si existen diferencias significativas en el porcentaje de saturación de oxígeno (porcO) en función de la fecha y la posición en el río, realizamos un análisis de varianza (ANOVA). El ANOVA nos permite determinar si las diferencias observadas en la media de porcO son estadísticamente significativas o si podrían deberse al azar.

# create data.frame with values of porcO fecha y posicion
porcO <- fisqui %>%
  select(porcO, fecha, posicion)

# modelo lineal
modelo1 <- aov(porcO ~ fecha + posicion, data = porcO)

# resultados del ANOVA
summary(modelo1)
##             Df Sum Sq Mean Sq F value Pr(>F)
## fecha        1   40.2   40.16   0.750  0.396
## posicion     2    6.2    3.11   0.058  0.944
## Residuals   23 1232.2   53.57

Los resultados del ANOVA nos indican si existen diferencias significativas en el porcentaje de saturación de oxígeno en función de la fecha y la posición en el río. Si el valor p es menor que 0.05, podemos concluir que hay diferencias significativas en la media de porcO entre los grupos analizados. En nuestro caso, el valor p es 0.396 para la fecha y 0.944 para la posición, lo que sugiere que no existen diferencias significativas en el porcentaje de saturación de oxígeno en función de la fecha y la posición en el río.

ANOVA de porcO en función de la fecha solamente

Como el valor más bajo de p lo obtuvo la fecha, se procede a realizar un ANOVA de porcO en función de la fecha solamente.

modelo2 <- aov(porcO ~ fecha, data = porcO)
summary(modelo2)
##             Df Sum Sq Mean Sq F value Pr(>F)
## fecha        1   40.2   40.16   0.811  0.377
## Residuals   25 1238.4   49.54

El valor p obtenido para la fecha es 0.377, lo que sugiere que no existen diferencias significativas en el porcentaje de saturación de oxígeno en función de la fecha de muestreo.

Prueba de supuestos del ANOVA

Antes de concluir sobre los resultados del ANOVA, es importante verificar si se cumplen los supuestos del análisis. Uno de los supuestos clave es la homogeneidad de varianzas entre los grupos. Para evaluar este supuesto, realizamos una prueba de Bartlett. La prueba de Bartlet nos permite determinar si las varianzas de los grupos son iguales o diferentes. Si el valor p es menor que 0.05, rechazamos la hipótesis nula de homogeneidad de varianzas.

# test asumption of homogeneity of variances
bartlett.test(porcO ~ fecha, data = porcO)
## 
##  Bartlett test of homogeneity of variances
## 
## data:  porcO by fecha
## Bartlett's K-squared = 7.3956, df = 2, p-value = 0.02478

El valor p obtenido para la prueba de Bartlett es 0.02478, lo que sugiere que las varianzas de los grupos son diferentes. Por lo tanto, no se cumple el supuesto de homogeneidad de varianzas para el ANOVA.

Alternativa al ANOVA: test de Kruskal-Wallis

Dado que no se cumple el supuesto de homogeneidad de varianzas para el ANOVA, podemos utilizar una alternativa no paramétrica, como el test de Kruskal-Wallis, para evaluar si existen diferencias significativas en el porcentaje de saturación de oxígeno en función de la fecha de muestreo. Si el valor de p es menor que 0.05, podemos concluir que existen diferencias significativas en el porcentaje de saturación de oxígeno en función de la fecha de muestreo.

# test de Kruskal-Wallis
kruskal.test(porcO ~ fecha, data = porcO)
## 
##  Kruskal-Wallis rank sum test
## 
## data:  porcO by fecha
## Kruskal-Wallis chi-squared = 23.157, df = 2, p-value = 9.365e-06

El valor p obtenido para el test de Kruskal-Wallis es \(9.37 * 10^{-6}\), lo que sugiere que existen diferencias significativas en el porcentaje de saturación de oxígeno en función de la fecha de muestreo.

Discusión y conclusiones

Aquí deben resumir lo hayado en el análisis estadístico y discutir las implicaciones de los resultados obtenidos en el análisis. Deben buscar alguna referencia sobre el porcentaje de saturación de oxígeno en ríos y comparar sus resultados con la literatura para evaluar si los valores obtenidos son indicativos de un río saludable o no.