16 de mayo de 2025
Un hidrogeólogo analiza la calidad del agua subterránea en tres acuíferos diferentes midiendo los niveles de pH en múltiples pozos. La pregunta principal es:
¿Existen diferencias significativas en el pH entre los acuíferos?
Aplicar un análisis de varianza de un factor (ANOVA) para determinar si las medias de pH en los tres grupos presentan diferencias estadísticamente significativas.
Este análisis se llevará a cabo por dos vías:
1. Cálculo manual de los elementos fundamentales del ANOVA. (pdf
adjunto) 2. Verificación de resultados mediante el software
R.
Los resultados obtenidos permitirán evaluar si las diferencias observadas en los niveles de pH pueden atribuirse a una variación real entre los acuíferos o si podrían ser producto del azar.
if (!require(readxl)) install.packages("readxl", dependencies = TRUE)
if (!require(dplyr)) install.packages("dplyr", dependencies = TRUE)
if (!require(tidyr)) install.packages("tidyr", dependencies = TRUE)
if (!require(writexl)) install.packages("writexl", dependencies = TRUE)
library(readxl)
library(dplyr)
library(tidyr)
library(writexl)
Los valores de pH medidos en los tres grupos de acuíferos se cargan desde un archivo Excel. Asegúrate de que el archivo datos_ph_acuiferos.xlsx esté en el mismo directorio que este archivo R Markdown.
# Ruta al archivo Excel (asumiendo que está en el mismo directorio)
ruta_archivo_excel <- "datos_ph_acuiferos.xlsx"
# Cargar los datos desde la primera hoja del archivo Excel
datos <- read_excel(ruta_archivo_excel, sheet = 1) # Puedes especificar el nombre de la hoja si es diferente
# Mostrar los datos cargados
cat("Datos cargados desde Excel:\n")
## Datos cargados desde Excel:
print(datos)
## # A tibble: 10 × 3
## `Grupo 1` `Grupo 2` `Grupo 3`
## <chr> <chr> <chr>
## 1 7.0 6.5 7.5
## 2 6.9 6.4 7.4
## 3 7.2 6.7 7.6
## 4 7.1 6.6 7.5
## 5 6.8 6.3 7.3
## 6 7.0 6.5 7.6
## 7 6.9 6.6 7.4
## 8 7.1 6.4 7.5
## 9 6.8 6.7 7.6
## 10 7.2 6.6 7.7
Para el análisis ANOVA, es más conveniente tener los datos en un formato “largo”, donde cada observación está en una fila.
datos_largos <- datos %>%
pivot_longer(cols = everything(), names_to = "Grupo", values_to = "Valor_temp") %>%
mutate(Valor = as.numeric(Valor_temp)) %>% # Convertir a numérico
filter(!is.na(Valor)) %>% # Eliminar filas donde la conversión a numérico falló (resultando en NA) o donde originalmente había NAs
select(-Valor_temp) # Eliminar la columna temporal
cat("\nDatos en formato largo (después de la conversión a numérico):\n")
##
## Datos en formato largo (después de la conversión a numérico):
print(datos_largos)
## # A tibble: 30 × 2
## Grupo Valor
## <chr> <dbl>
## 1 Grupo 1 7
## 2 Grupo 2 6.5
## 3 Grupo 3 7.5
## 4 Grupo 1 6.9
## 5 Grupo 2 6.4
## 6 Grupo 3 7.4
## 7 Grupo 1 7.2
## 8 Grupo 2 6.7
## 9 Grupo 3 7.6
## 10 Grupo 1 7.1
## # ℹ 20 more rows
str(datos_largos) # Verifica que 'Valor' sea ahora numérico (num o dbl)
## tibble [30 × 2] (S3: tbl_df/tbl/data.frame)
## $ Grupo: chr [1:30] "Grupo 1" "Grupo 2" "Grupo 3" "Grupo 1" ...
## $ Valor: num [1:30] 7 6.5 7.5 6.9 6.4 7.4 7.2 6.7 7.6 7.1 ...
# Si después de as.numeric() ves muchos NAs en la columna Valor,
# significa que los datos originales en Excel no eran fácilmente convertibles a números.
# Revisa tu archivo Excel cuidadosamente.
Calculamos estadísticas descriptivas básicas para cada grupo.
resumen_grupo <- datos_largos %>%
group_by(Grupo) %>%
summarise(
N_i = n(), # Número de observaciones por grupo
T_i = sum(Valor), # Suma total de los valores por grupo
Y_i = mean(Valor) # Media de los valores por grupo
)
N_total <- sum(resumen_grupo$N_i) # Número total de observaciones
T_total <- sum(resumen_grupo$T_i) # Suma total de todos los valores
Y_total <- T_total / N_total # Media general de todos los valores
cat("\nResumen por grupo:\n")
##
## Resumen por grupo:
print(resumen_grupo)
## # A tibble: 3 × 4
## Grupo N_i T_i Y_i
## <chr> <int> <dbl> <dbl>
## 1 Grupo 1 10 70 7
## 2 Grupo 2 10 65.3 6.53
## 3 Grupo 3 10 75.1 7.51
cat("\nTotales generales:\n")
##
## Totales generales:
cat("N_total:", N_total, "\n")
## N_total: 30
cat("T_total:", T_total, "\n")
## T_total: 210.4
cat("Y_total:", Y_total, "\n")
## Y_total: 7.013333
Se realizan los cálculos para la Suma de Cuadrados.
# Suma de Cuadrados Total (SST)
sst_parte1 <- sum((datos_largos$Valor)^2)
sst_parte2 <- (T_total^2) / N_total
SST <- sst_parte1 - sst_parte2
# Suma de Cuadrados del Tratamiento (Entre grupos) (SSA)
SSA <- sum((resumen_grupo$T_i^2) / resumen_grupo$N_i) - sst_parte2
# Suma de Cuadrados del Error (Dentro de grupos) (SSE)
SSE <- SST - SSA
cat("\nSuma de Cuadrados:\n")
##
## Suma de Cuadrados:
cat("SST (Total):", SST, "\n")
## SST (Total): 5.294667
cat("SSA (Tratamiento/Entre grupos):", SSA, "\n")
## SSA (Tratamiento/Entre grupos): 4.804667
cat("SSE (Error/Dentro de grupos):", SSE, "\n")
## SSE (Error/Dentro de grupos): 0.49
Calculamos los grados de libertad, cuadrados medios y el estadístico F.
K <- nrow(resumen_grupo) # Número de grupos
df_SSA <- K - 1 # Grados de libertad para SSA
df_SSE <- N_total - K # Grados de libertad para SSE
df_SST <- N_total - 1 # Grados de libertad para SST
MSA <- SSA / df_SSA # Cuadrado Medio del Tratamiento
MSE <- SSE / df_SSE # Cuadrado Medio del Error
F_value <- MSA / MSE # Estadístico F
cat("\nEstadísticos ANOVA:\n")
##
## Estadísticos ANOVA:
cat("Grados de libertad SSA (df_SSA):", df_SSA, "\n")
## Grados de libertad SSA (df_SSA): 2
cat("Grados de libertad SSE (df_SSE):", df_SSE, "\n")
## Grados de libertad SSE (df_SSE): 27
cat("Grados de libertad SST (df_SST):", df_SST, "\n")
## Grados de libertad SST (df_SST): 29
cat("Cuadrado Medio Tratamiento (MSA):", MSA, "\n")
## Cuadrado Medio Tratamiento (MSA): 2.402333
cat("Cuadrado Medio Error (MSE):", MSE, "\n")
## Cuadrado Medio Error (MSE): 0.01814815
cat("Valor F calculado:", F_value, "\n")
## Valor F calculado: 132.3735
Se construye la tabla ANOVA resumen.
anova_tabla <- data.frame(
Fuente = c("Tratamiento (Entre grupos)", "Error (Dentro de grupos)", "Total"),
`Suma de Cuadrados` = c(SSA, SSE, SST),
`Grados de Libertad` = c(df_SSA, df_SSE, df_SST),
`Cuadrado Medio` = c(MSA, MSE, NA),
`F` = c(F_value, NA, NA)
)
cat("\nTabla ANOVA:\n")
##
## Tabla ANOVA:
print(anova_tabla)
## Fuente Suma.de.Cuadrados Grados.de.Libertad
## 1 Tratamiento (Entre grupos) 4.804667 2
## 2 Error (Dentro de grupos) 0.490000 27
## 3 Total 5.294667 29
## Cuadrado.Medio F
## 1 2.40233333 132.3735
## 2 0.01814815 NA
## 3 NA NA
Presentamos el resumen de los grupos incluyendo los totales generales.
resumen_final <- resumen_grupo %>%
add_row(Grupo = "Total", N_i = N_total, T_i = T_total, Y_i = Y_total)
cat("\nResumen final de grupos (con totales):\n")
##
## Resumen final de grupos (con totales):
print(resumen_final)
## # A tibble: 4 × 4
## Grupo N_i T_i Y_i
## <chr> <int> <dbl> <dbl>
## 1 Grupo 1 10 70 7
## 2 Grupo 2 10 65.3 6.53
## 3 Grupo 3 10 75.1 7.51
## 4 Total 30 210. 7.01
Se realiza el contraste de hipótesis para determinar si existen diferencias significativas entre las medias de los grupos. H0: µ1 = µ2 = µ3 (Las medias de pH son iguales en los tres grupos de acuíferos) H1: Al menos una media es diferente
# Chunk del ANOVA General (el que ya tenías)
alpha <- 0.05 # Nivel de significancia
# Asumimos que F_value, df_SSA, df_SSE ya han sido calculados previamente
# y datos_largos (con columnas 'Valor' y 'Grupo') existe.
p_valor_anova <- pf(F_value, df1 = df_SSA, df2 = df_SSE, lower.tail = FALSE)
cat("\n--- Contraste de Hipótesis ANOVA General ---\n")
##
## --- Contraste de Hipótesis ANOVA General ---
cat("H0: µ_Grupo1 = µ_Grupo2 = µ_Grupo3 (Las medias de pH son iguales en los tres grupos)\n")
## H0: µ_Grupo1 = µ_Grupo2 = µ_Grupo3 (Las medias de pH son iguales en los tres grupos)
cat("H1: Al menos una media de pH es diferente\n")
## H1: Al menos una media de pH es diferente
cat("Estadístico F calculado:", round(F_value, 4), "\n")
## Estadístico F calculado: 132.3735
cat("Grados de libertad: (", df_SSA, ",", df_SSE, ")\n")
## Grados de libertad: ( 2 , 27 )
cat("Valor p del ANOVA:", round(p_valor_anova, 5), "\n")
## Valor p del ANOVA: 0
cat("Nivel de significancia (alpha):", alpha, "\n")
## Nivel de significancia (alpha): 0.05
decision_anova <- if (p_valor_anova < alpha) {
"❌ Se rechaza la hipótesis nula del ANOVA: hay diferencias significativas en los niveles de pH entre al menos dos grupos de acuíferos."
} else {
"✅ No se rechaza la hipótesis nula del ANOVA: no hay evidencia suficiente para afirmar que existen diferencias significativas en los niveles de pH entre los grupos de acuíferos."
}
cat("Decisión ANOVA:", decision_anova, "\n")
## Decisión ANOVA: ❌ Se rechaza la hipótesis nula del ANOVA: hay diferencias significativas en los niveles de pH entre al menos dos grupos de acuíferos.
# Chunk para Pruebas Post-Hoc (Tukey HSD) si el ANOVA es significativo
if (p_valor_anova < alpha) {
cat("\n--- Pruebas Post-Hoc (Comparaciones Múltiples Tukey HSD) ---\n")
cat("Dado que el ANOVA general fue significativo, procedemos a realizar comparaciones pareadas para identificar qué grupos específicos difieren.\n\n")
# Para usar TukeyHSD, necesitamos un objeto 'aov'
# Asegúrate de que 'datos_largos' tiene 'Valor' (numérico) y 'Grupo' (factor)
# Si 'Grupo' no es factor, conviértelo: datos_largos$Grupo <- as.factor(datos_largos$Grupo)
if (!is.factor(datos_largos$Grupo)) {
datos_largos$Grupo <- as.factor(datos_largos$Grupo)
cat("Nota: La columna 'Grupo' ha sido convertida a factor para el análisis aov.\n")
}
modelo_aov <- aov(Valor ~ Grupo, data = datos_largos)
tukey_resultados <- TukeyHSD(modelo_aov)
cat("Resultados de la Prueba Tukey HSD:\n")
print(tukey_resultados)
cat("\nInterpretación de los resultados de Tukey HSD:\n")
cat("Cada fila representa una comparación entre dos grupos:\n")
cat(" - 'diff': La diferencia observada entre las medias de los dos grupos.\n")
cat(" - 'lwr' y 'upr': El intervalo de confianza inferior y superior para la diferencia de medias.\n")
cat(" - 'p adj': El valor p ajustado para la comparación. Si 'p adj' <", alpha, ", la diferencia entre ese par de grupos es estadísticamente significativa.\n\n")
# Interpretación detallada de cada par:
# Asumiendo que los nombres de los grupos son "Grupo 1", "Grupo 2", "Grupo 3"
# y que TukeyHSD los ordena alfabéticamente o por aparición si son factores.
# Verificamos los nombres reales desde el output de TukeyHSD
comparaciones <- rownames(tukey_resultados$Grupo) # $Grupo es el nombre por defecto para un factor
p_adj_valores <- tukey_resultados$Grupo[, "p adj"]
diferencias_medias <- tukey_resultados$Grupo[, "diff"]
cat("Desglose de comparaciones pareadas específicas (H0: µ_i = µ_j vs H1: µ_i ≠ µ_j):\n")
for (i in 1:length(comparaciones)) {
par_grupos <- strsplit(comparaciones[i], "-")[[1]]
cat(paste0(" - Comparación ", par_grupos[2], " vs. ", par_grupos[1], ":\n"))
cat(paste0(" Diferencia de medias (", par_grupos[2], " - ", par_grupos[1], "): ", round(diferencias_medias[i], 4), "\n"))
cat(paste0(" Valor p ajustado: ", round(p_adj_valores[i], 5), "\n"))
if (p_adj_valores[i] < alpha) {
cat(paste0(" Decisión: ❌ Se rechaza H0. Hay una diferencia significativa entre ", par_grupos[1], " y ", par_grupos[2], " (p < ", alpha, ").\n"))
} else {
cat(paste0(" Decisión: ✅ No se rechaza H0. No hay diferencia significativa entre ", par_grupos[1], " y ", par_grupos[2], " (p >= ", alpha, ").\n"))
}
}
} else {
cat("\n--- Pruebas Post-Hoc (Comparaciones Múltiples) ---\n")
cat("Dado que el ANOVA general no fue significativo, no se realizan pruebas post-hoc detalladas.\n")
cat("No hay evidencia suficiente para afirmar que alguna de las medias de los grupos sea diferente.\n")
}
##
## --- Pruebas Post-Hoc (Comparaciones Múltiples Tukey HSD) ---
## Dado que el ANOVA general fue significativo, procedemos a realizar comparaciones pareadas para identificar qué grupos específicos difieren.
##
## Nota: La columna 'Grupo' ha sido convertida a factor para el análisis aov.
## Resultados de la Prueba Tukey HSD:
## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = Valor ~ Grupo, data = datos_largos)
##
## $Grupo
## diff lwr upr p adj
## Grupo 2-Grupo 1 -0.47 -0.619376 -0.320624 1e-07
## Grupo 3-Grupo 1 0.51 0.360624 0.659376 0e+00
## Grupo 3-Grupo 2 0.98 0.830624 1.129376 0e+00
##
##
## Interpretación de los resultados de Tukey HSD:
## Cada fila representa una comparación entre dos grupos:
## - 'diff': La diferencia observada entre las medias de los dos grupos.
## - 'lwr' y 'upr': El intervalo de confianza inferior y superior para la diferencia de medias.
## - 'p adj': El valor p ajustado para la comparación. Si 'p adj' < 0.05 , la diferencia entre ese par de grupos es estadísticamente significativa.
##
## Desglose de comparaciones pareadas específicas (H0: µ_i = µ_j vs H1: µ_i ≠ µ_j):
## - Comparación Grupo 1 vs. Grupo 2:
## Diferencia de medias (Grupo 1 - Grupo 2): -0.47
## Valor p ajustado: 0
## Decisión: ❌ Se rechaza H0. Hay una diferencia significativa entre Grupo 2 y Grupo 1 (p < 0.05).
## - Comparación Grupo 1 vs. Grupo 3:
## Diferencia de medias (Grupo 1 - Grupo 3): 0.51
## Valor p ajustado: 0
## Decisión: ❌ Se rechaza H0. Hay una diferencia significativa entre Grupo 3 y Grupo 1 (p < 0.05).
## - Comparación Grupo 2 vs. Grupo 3:
## Diferencia de medias (Grupo 2 - Grupo 3): 0.98
## Valor p ajustado: 0
## Decisión: ❌ Se rechaza H0. Hay una diferencia significativa entre Grupo 3 y Grupo 2 (p < 0.05).
if (!require(knitr)) install.packages("knitr", dependencies = TRUE)
## Cargando paquete requerido: knitr
library(knitr)
cat("\n## Datos Originales en Formato Largo\n")
##
## ## Datos Originales en Formato Largo
cat("Estos son los datos individuales de pH para cada muestra y grupo, utilizados para los cálculos.\n")
## Estos son los datos individuales de pH para cada muestra y grupo, utilizados para los cálculos.
kable(datos_largos, caption = "Datos Originales de pH por Grupo")
| Grupo | Valor |
|---|---|
| Grupo 1 | 7.0 |
| Grupo 2 | 6.5 |
| Grupo 3 | 7.5 |
| Grupo 1 | 6.9 |
| Grupo 2 | 6.4 |
| Grupo 3 | 7.4 |
| Grupo 1 | 7.2 |
| Grupo 2 | 6.7 |
| Grupo 3 | 7.6 |
| Grupo 1 | 7.1 |
| Grupo 2 | 6.6 |
| Grupo 3 | 7.5 |
| Grupo 1 | 6.8 |
| Grupo 2 | 6.3 |
| Grupo 3 | 7.3 |
| Grupo 1 | 7.0 |
| Grupo 2 | 6.5 |
| Grupo 3 | 7.6 |
| Grupo 1 | 6.9 |
| Grupo 2 | 6.6 |
| Grupo 3 | 7.4 |
| Grupo 1 | 7.1 |
| Grupo 2 | 6.4 |
| Grupo 3 | 7.5 |
| Grupo 1 | 6.8 |
| Grupo 2 | 6.7 |
| Grupo 3 | 7.6 |
| Grupo 1 | 7.2 |
| Grupo 2 | 6.6 |
| Grupo 3 | 7.7 |
cat("\n## Resumen de Muestras y Totales\n")
##
## ## Resumen de Muestras y Totales
cat("Estadísticas descriptivas por grupo y totales generales.\n")
## Estadísticas descriptivas por grupo y totales generales.
cat("N_i: Número de observaciones, T_i: Suma de valores, Y_i: Media de valores.\n")
## N_i: Número de observaciones, T_i: Suma de valores, Y_i: Media de valores.
kable(resumen_final, caption = "Resumen de Muestras (Parciales y Totales)")
| Grupo | N_i | T_i | Y_i |
|---|---|---|---|
| Grupo 1 | 10 | 70.0 | 7.000000 |
| Grupo 2 | 10 | 65.3 | 6.530000 |
| Grupo 3 | 10 | 75.1 | 7.510000 |
| Total | 30 | 210.4 | 7.013333 |
cat("\n## Tabla ANOVA\n")
##
## ## Tabla ANOVA
cat("Resultados del Análisis de Varianza (ANOVA) de un factor.\n")
## Resultados del Análisis de Varianza (ANOVA) de un factor.
kable(anova_tabla, caption = "Tabla Resumen del ANOVA", digits = 4) # 'digits' para redondear
| Fuente | Suma.de.Cuadrados | Grados.de.Libertad | Cuadrado.Medio | F |
|---|---|---|---|---|
| Tratamiento (Entre grupos) | 4.8047 | 2 | 2.4023 | 132.3735 |
| Error (Dentro de grupos) | 0.4900 | 27 | 0.0181 | NA |
| Total | 5.2947 | 29 | NA | NA |
# --- INICIO DEL CHUNK: contraste-anova-y-tukey ---
# Asumimos que F_value, df_SSA, df_SSE, datos_largos ya existen.
alpha <- 0.05 # Nivel de significancia
# ANOVA General
p_valor_anova <- pf(F_value, df1 = df_SSA, df2 = df_SSE, lower.tail = FALSE)
hipotesis_anova_H0_texto <- "H0: µ_Grupo1 = µ_Grupo2 = µ_Grupo3 (Las medias de pH son iguales en los tres grupos de acuíferos)"
hipotesis_anova_H1_texto <- "H1: Al menos una media de pH es diferente entre los grupos"
cat("\n## Contraste de Hipótesis ANOVA General\n")
##
## ## Contraste de Hipótesis ANOVA General
cat(hipotesis_anova_H0_texto, "\n")
## H0: µ_Grupo1 = µ_Grupo2 = µ_Grupo3 (Las medias de pH son iguales en los tres grupos de acuíferos)
cat(hipotesis_anova_H1_texto, "\n\n")
## H1: Al menos una media de pH es diferente entre los grupos
cat("Estadístico F calculado:", round(F_value, 4), "\n")
## Estadístico F calculado: 132.3735
cat("Grados de libertad: (", df_SSA, ",", df_SSE, ")\n")
## Grados de libertad: ( 2 , 27 )
cat("Valor p del ANOVA:", round(p_valor_anova, 5), "\n")
## Valor p del ANOVA: 0
cat("Nivel de significancia (alpha):", alpha, "\n")
## Nivel de significancia (alpha): 0.05
decision_anova <- if (p_valor_anova < alpha) {
"❌ Se rechaza la H0 del ANOVA: Hay diferencias significativas en los niveles de pH entre al menos dos grupos."
} else {
"✅ No se rechaza la H0 del ANOVA: No hay evidencia suficiente para afirmar diferencias significativas entre los grupos."
}
cat("Decisión ANOVA:", decision_anova, "\n")
## Decisión ANOVA: ❌ Se rechaza la H0 del ANOVA: Hay diferencias significativas en los niveles de pH entre al menos dos grupos.
# Preparar para la hoja de Interpretación de Excel
interpretacion_lista <- list(
list(Componente = "ANOVA General - Hipótesis Nula (H0)", Detalle = hipotesis_anova_H0_texto),
list(Componente = "ANOVA General - Hipótesis Alternativa (H1)", Detalle = hipotesis_anova_H1_texto),
list(Componente = "ANOVA General - Estadístico F", Detalle = round(F_value, 4)),
list(Componente = "ANOVA General - Grados de Libertad", Detalle = paste0("(", df_SSA, ", ", df_SSE, ")")),
list(Componente = "ANOVA General - Valor p", Detalle = round(p_valor_anova, 5)),
list(Componente = "ANOVA General - Nivel de Significancia (alpha)", Detalle = alpha),
list(Componente = "ANOVA General - Decisión", Detalle = decision_anova)
)
# Tukey HSD (si ANOVA es significativo)
resultados_tukey_df <- NULL # Inicializar
if (p_valor_anova < alpha) {
cat("\n## Pruebas Post-Hoc (Comparaciones Múltiples Tukey HSD)\n")
cat("Dado que el ANOVA general fue significativo, procedemos a realizar comparaciones pareadas.\n")
hipotesis_tukey_H0_texto <- "H0_par: µ_i = µ_j (Las medias de los dos grupos comparados son iguales)"
hipotesis_tukey_H1_texto <- "H1_par: µ_i ≠ µ_j (Las medias de los dos grupos comparados son diferentes)"
cat(hipotesis_tukey_H0_texto, "\n")
cat(hipotesis_tukey_H1_texto, "\n\n")
if (!is.factor(datos_largos$Grupo)) {
datos_largos$Grupo <- as.factor(datos_largos$Grupo)
}
modelo_aov <- aov(Valor ~ Grupo, data = datos_largos)
tukey_resultados_obj <- TukeyHSD(modelo_aov)
# Convertir TukeyHSD a un dataframe más manejable para kable y Excel
resultados_tukey_df <- as.data.frame(tukey_resultados_obj$Grupo)
resultados_tukey_df$Comparacion <- rownames(resultados_tukey_df)
resultados_tukey_df <- resultados_tukey_df[, c("Comparacion", "diff", "lwr", "upr", "p adj")]
colnames(resultados_tukey_df) <- c("Comparacion", "Diferencia_Medias", "IC_Inferior_95%", "IC_Superior_95%", "P_Valor_Ajustado")
cat("Resultados de la Prueba Tukey HSD:\n")
kable(resultados_tukey_df, caption = "Resultados de las Comparaciones Pareadas Tukey HSD", digits = 4)
interpretacion_lista <- append(interpretacion_lista, list(
list(Componente = "Tukey HSD - Hipótesis Nula (H0_par)", Detalle = hipotesis_tukey_H0_texto),
list(Componente = "Tukey HSD - Hipótesis Alternativa (H1_par)", Detalle = hipotesis_tukey_H1_texto),
list(Componente = "Tukey HSD - Resultados Detallados", Detalle = "Ver la hoja 'Resultados Tukey HSD' o la tabla anterior en este documento.")
))
} else {
cat("\n## Pruebas Post-Hoc (Comparaciones Múltiples Tukey HSD)\n")
cat("Dado que el ANOVA general no fue significativo, no se realizan pruebas post-hoc detalladas.\n")
interpretacion_lista <- append(interpretacion_lista, list(
list(Componente = "Tukey HSD", Detalle = "No se realizaron pruebas post-hoc ya que el ANOVA general no fue significativo.")
))
}
##
## ## Pruebas Post-Hoc (Comparaciones Múltiples Tukey HSD)
## Dado que el ANOVA general fue significativo, procedemos a realizar comparaciones pareadas.
## H0_par: µ_i = µ_j (Las medias de los dos grupos comparados son iguales)
## H1_par: µ_i ≠ µ_j (Las medias de los dos grupos comparados son diferentes)
##
## Resultados de la Prueba Tukey HSD:
# Convertir la lista de interpretación a un data.frame para Excel
interpretacion_final_df <- do.call(rbind, lapply(interpretacion_lista, data.frame, stringsAsFactors = FALSE))
# --- FIN DEL CHUNK: contraste-anova-y-tukey ---
# --- INICIO DEL CHUNK: exportar-a-excel-completo ---
# Asumimos que datos_largos, resumen_final, anova_tabla,
# interpretacion_final_df, y resultados_tukey_df (si existe) ya están creados.
hojas_excel <- list(
"Datos Originales" = datos_largos,
"Resumen Muestras y Totales" = resumen_final,
"Tabla ANOVA" = anova_tabla,
"Interpretacion Contraste" = interpretacion_final_df # Usamos el df completo
)
# Añadir la hoja de Tukey HSD solo si existe y no es NULL
if (!is.null(resultados_tukey_df)) {
hojas_excel[["Resultados Tukey HSD"]] <- resultados_tukey_df
}
# Ruta para el archivo de salida
ruta_salida_excel <- "resultados_completos_anova_ph_v2.xlsx"
write_xlsx(hojas_excel, path = ruta_salida_excel)
cat("\n## Exportación a Excel\n")
##
## ## Exportación a Excel
cat("Resultados completos exportados exitosamente a:", ruta_salida_excel, "\n")
## Resultados completos exportados exitosamente a: resultados_completos_anova_ph_v2.xlsx
cat("El archivo Excel contiene las siguientes hojas:\n")
## El archivo Excel contiene las siguientes hojas:
for (nombre_hoja in names(hojas_excel)) {
cat("- ", nombre_hoja, "\n")
}
## - Datos Originales
## - Resumen Muestras y Totales
## - Tabla ANOVA
## - Interpretacion Contraste
## - Resultados Tukey HSD
# --- FIN DEL CHUNK: exportar-a-excel-completo ---
#INTERPRETACIONES
Se busca determinar si existen diferencias significativas en los niveles de pH de agua subterránea provenientes de tres acuíferos distintos. El análisis de estos datos se realizó utilizando dos métodos distintos: uno manual y otro mediante el uso del software estadístico R.
El objetivo es comparar las medias de pH de los tres grupos y evaluar si hay evidencia estadística suficiente para afirmar que al menos uno de ellos difiere significativamente de los demás en cuanto a su nivel promedio de pH.
| Elemento analizado | Cálculo manual | Resultado en R | Coinciden |
|---|---|---|---|
| Suma de cuadrados (tratamiento) | 4.8 | 4.80466666666689 | Sí |
| Suma de cuadrados (total) | 5.294 | 5.29466666666713 | Sí |
| Suma de cuadrados (error dentro de grupos) | 0.49 | 0.490000000000237 | Sí |
| Estadístico F (Fisher) | 132.244898 | 132.373469387697 | Sí |
| Grados de libertad (tratamiento) | 2 | 2 | Sí |
| Grados de libertad (error dentro de grupos) | 27 | 27 | Sí |
| Conclusión | Rechaza H₀ | Rechaza H₀ | Sí |
Dado que el valor de F es considerablemente alto, se concluyó que hay diferencias significativas entre los acuíferos.
El valor del p-valor confirma que las diferencias entre los grupos no se deben al azar. Por lo tanto, también en este análisis se rechaza la hipótesis nula (H₀).
La coincidencia entre los resultados demuestra que el procedimiento manual se aplicó correctamente, y que el software R confirma de manera más automatizada y precisa estos mismos resultados.
En este caso, los dos métodos dieron resultados muy similares. Las
pequeñas diferencias observadas pueden explicarse por:
- El software R trabaja con mayor cantidad de cifras
decimales que el cálculo manual promedio.
- El redondeo decimal que ocurre en cálculos realizados a mano.
A pesar de estas mínimas discrepancias, los valores obtenidos por ambos métodos no están significativamente alejados entre sí.
Conclusión final: Ambos métodos permitieron identificar que existen diferencias significativas en los niveles de pH entre los tres acuíferos evaluados.