# Chunk 1: Instalación de Paquetes
# NOTA: Esto solo necesitas correrlo UNA VEZ.
# Después de que se instalen, le pondremos un # al inicio de cada línea.
# install.packages("tidyverse") # Para manipular datos (dplyr) y graficar (ggplot2)
# install.packages("car") # Para la prueba de Levene (homocedasticidad)
# install.packages("dunn.test") # Para la prueba Post-Hoc si usamos Kruskal-Wallis
# Chunk 2: Cargar las bibliotecas
# Esto sí se corre siempre.
library(tidyverse) # Incluye ggplot2 (gráficos) y dplyr (manipulación)
## Warning: package 'tidyverse' was built under R version 4.4.3
## Warning: package 'ggplot2' was built under R version 4.4.3
## Warning: package 'tibble' was built under R version 4.4.3
## Warning: package 'tidyr' was built under R version 4.4.3
## Warning: package 'readr' was built under R version 4.4.3
## Warning: package 'purrr' was built under R version 4.4.3
## Warning: package 'dplyr' was built under R version 4.4.3
## Warning: package 'stringr' was built under R version 4.4.3
## Warning: package 'forcats' was built under R version 4.4.3
## Warning: package 'lubridate' was built under R version 4.4.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.6
## ✔ forcats 1.0.1 ✔ stringr 1.6.0
## ✔ ggplot2 4.0.1 ✔ tibble 3.3.0
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.2.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(car) # Para la prueba de Levene
## Warning: package 'car' was built under R version 4.4.3
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.4.3
##
## Attaching package: 'car'
##
## The following object is masked from 'package:dplyr':
##
## recode
##
## The following object is masked from 'package:purrr':
##
## some
library(dunn.test) # Para la prueba Post-Hoc de # Kruskal-Wallis
# Chunk 3: Cargar y transformar los datos
# 1. Cargar el archivo CSV
# read_csv() viene del paquete 'tidyverse' que ya cargamos
datos_wide <- read_csv("datos_imc.csv")
## Rows: 40 Columns: 4
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (4): Tuxpan, Tamazula, Zapotlan, Zapotiltic
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# 2. Transformar de formato ancho a formato largo
datos_long <- datos_wide %>%
pivot_longer(
cols = everything(), # Toma todas las columnas
names_to = "Municipio", # Crea una nueva columna para los nombres
values_to = "IMC" # Crea una nueva columna para los números
) %>%
mutate(Municipio = as.factor(Municipio)) # Convierte los nombres en una categoría
# 3. Inspeccionar los datos para ver si funcionó
print("Datos anchos (como el CSV):")
## [1] "Datos anchos (como el CSV):"
head(datos_wide) # 'head()' muestra las primeras 6 filas
## # A tibble: 6 × 4
## Tuxpan Tamazula Zapotlan Zapotiltic
## <dbl> <dbl> <dbl> <dbl>
## 1 56.9 58.6 50.5 51.5
## 2 40.8 43.2 41.3 32.3
## 3 35.0 55.4 44.9 40.7
## 4 50.8 55.2 44.7 36.8
## 5 41.3 49.0 37.1 38.3
## 6 40.3 34.7 39.7 55.4
print("Datos largos (transformados):")
## [1] "Datos largos (transformados):"
head(datos_long)
## # A tibble: 6 × 2
## Municipio IMC
## <fct> <dbl>
## 1 Tuxpan 56.9
## 2 Tamazula 58.6
## 3 Zapotlan 50.5
## 4 Zapotiltic 51.5
## 5 Tuxpan 40.8
## 6 Tamazula 43.2
[cite_start]Para cumplir con las instrucciones, primero evaluaremos el supuesto de normalidad. Esto es clave para decidir si usaremos una prueba paramétrica (ANOVA) o una no paramétrica (Kruskal-Wallis).
# Chunk 4: Pruebas de Normalidad
# --- Gráfica (Q-Q Plot) ---
# Usamos facet_wrap() para crear un gráfico separado para cada municipio
ggplot(datos_long, aes(sample = IMC)) +
stat_qq() +
stat_qq_line() +
facet_wrap(~ Municipio) +
labs(title = "Gráficos Q-Q de Normalidad por Municipio",
x = "Cuantiles Teóricos (Normal)",
y = "Cuantiles de la Muestra (IMC)") +
theme_bw() # Un tema visual limpio
# --- Formal (Shapiro-Wilk) ---
# Agrupamos por municipio y aplicamos la prueba a cada uno
resultados_shapiro <- datos_long %>%
group_by(Municipio) %>%
summarise(
estadistico_W = shapiro.test(IMC)$statistic,
p_valor = shapiro.test(IMC)$p.value
)
print("Resultados de la Prueba de Normalidad (Shapiro-Wilk):")
## [1] "Resultados de la Prueba de Normalidad (Shapiro-Wilk):"
print(resultados_shapiro)
## # A tibble: 4 × 3
## Municipio estadistico_W p_valor
## <fct> <dbl> <dbl>
## 1 Tamazula 0.957 0.129
## 2 Tuxpan 0.974 0.475
## 3 Zapotiltic 0.974 0.476
## 4 Zapotlan 0.938 0.0299
El segundo supuesto clave del ANOVA (aunque ya sepamos que no lo usaremos) es la homocedasticidad, que significa que las varianzas (la dispersión de los datos) son iguales en todos los grupos.
# Chunk 5: Pruebas de Homocedasticidad
# --- Gráfica (Boxplot) ---
ggplot(datos_long, aes(x = Municipio, y = IMC, fill = Municipio)) +
geom_boxplot() +
labs(title = "Distribución de IMC por Municipio (Boxplots)") +
theme_bw()
# --- Formal (Prueba de Levene) ---
# La función leveneTest() viene del paquete 'car' que ya cargamos
print("Resultados de la Prueba de Levene (Homocedasticidad):")
## [1] "Resultados de la Prueba de Levene (Homocedasticidad):"
leveneTest(IMC ~ Municipio, data = datos_long)
## Levene's Test for Homogeneity of Variance (center = median)
## Df F value Pr(>F)
## group 3 2.3917 0.07072 .
## 156
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
[cite_start]Para responder a la pregunta “¿Existe diferencia significativa entre el IMC de las muestras?”[cite: 22], debemos elegir la prueba estadística correcta.
La hipótesis nula (H₀) de Kruskal-Wallis es que las distribuciones de IMC son iguales en los cuatro municipios. * Si p-value < 0.05, rechazamos H₀ y concluimos que SÍ existe una diferencia significativa.
# Chunk 6: Prueba de Kruskal-Wallis
# Esta es la prueba principal para comparar los 4 grupos
print("Resultados de la Prueba de Kruskal-Wallis:")
## [1] "Resultados de la Prueba de Kruskal-Wallis:"
kruskal.test(IMC ~ Municipio, data = datos_long)
##
## Kruskal-Wallis rank sum test
##
## data: IMC by Municipio
## Kruskal-Wallis chi-squared = 4.2204, df = 3, p-value = 0.2386
La prueba de Kruskal-Wallis arrojó un p-valor de 0.2386, el cual es mayor a 0.05. Dado que no se encontró una diferencia estadísticamente significativa entre los grupos, no es necesario ni apropiado realizar un test Post-Hoc.
La respuesta a la pregunta “¿Cuál es la localidad diferente?” es que, según este análisis, ninguna localidad es significativamente diferente de las demás.
[cite_start]Ahora responderemos a la pregunta: “¿Cuáles son las localidades que mejor se correlacionan?”.
datos_wide).# Chunk 7: Matriz de Correlación de Spearman
# Cargamos la biblioteca 'psych' que tiene una gran función
# para matrices de correlación que incluye p-valores.
library(psych)
## Warning: package 'psych' was built under R version 4.4.3
##
## Attaching package: 'psych'
## The following object is masked from 'package:car':
##
## logit
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
print("Matriz de Correlación (Spearman) con p-valores:")
## [1] "Matriz de Correlación (Spearman) con p-valores:"
# Usamos corr.test() para obtener tanto los coeficientes (r)
# como los p-valores de la correlación.
matriz_corr <- corr.test(datos_wide, method = "spearman")
print(matriz_corr)
## Call:corr.test(x = datos_wide, method = "spearman")
## Correlation matrix
## Tuxpan Tamazula Zapotlan Zapotiltic
## Tuxpan 1.00 0.17 0.24 0.08
## Tamazula 0.17 1.00 -0.16 -0.38
## Zapotlan 0.24 -0.16 1.00 0.20
## Zapotiltic 0.08 -0.38 0.20 1.00
## Sample Size
## [1] 40
## Probability values (Entries above the diagonal are adjusted for multiple tests.)
## Tuxpan Tamazula Zapotlan Zapotiltic
## Tuxpan 0.00 0.84 0.67 0.84
## Tamazula 0.28 0.00 0.84 0.09
## Zapotlan 0.13 0.31 0.00 0.82
## Zapotiltic 0.61 0.01 0.21 0.00
##
## To see confidence intervals of the correlations, print with the short=FALSE option
Para responder a la última pregunta, crearemos un modelo de regresión lineal simple.
# Chunk 8: Modelo de Regresión Lineal
# Creamos el modelo: lm(Y ~ X, data)
# Usaremos Zapotiltic como 'Y' y Tamazula como 'X'
# Usamos los datos 'datos_wide'
modelo_regresion <- lm(Zapotiltic ~ Tamazula, data = datos_wide)
# 1. Ver los resultados del modelo (coeficientes, R-cuadrado, etc.)
print("Resumen del Modelo de Regresión:")
## [1] "Resumen del Modelo de Regresión:"
summary(modelo_regresion)
##
## Call:
## lm(formula = Zapotiltic ~ Tamazula, data = datos_wide)
##
## Residuals:
## Min 1Q Median 3Q Max
## -17.8216 -6.0027 0.8546 5.6331 16.3870
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 64.4861 7.1814 8.980 6.22e-11 ***
## Tamazula -0.3334 0.1533 -2.175 0.0359 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.987 on 38 degrees of freedom
## Multiple R-squared: 0.1107, Adjusted R-squared: 0.08734
## F-statistic: 4.732 on 1 and 38 DF, p-value: 0.0359
# 2. Análisis gráfico de los Residuos
# R nos da 4 gráficos para validar los supuestos del modelo
par(mfrow = c(2, 2)) # Prepara la ventana gráfica para 4 gráficos
plot(modelo_regresion)
par(mfrow = c(1, 1)) # Regresa la ventana a 1 solo gráfico
Basado en el análisis estadístico completo de los datos de IMC de los cuatro municipios, se llega a las siguientes conclusiones: