1 Ejecución del plan de análisis

1.1 Preparación de la base de datos

1.1.1 librerias

library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)
library(knitr)
library(kableExtra)
library(anthro)
library(anthroplus)
library(scales)
library(gtsummary)
library(lubridate)
library(patchwork)
library(table1)
library(epiR)

1.1.2 cargar base de datos

df <- read_excel("base_epidemiologia_nutricional.xlsx")

1.1.3 Análisis exploratorio de la base de datos

nrow(df)
## [1] 90
colnames(df)
## [1] "Fecha_de_encuesta"   "ID"                  "Sexo"               
## [4] "Fecha_de_nacimiento" "Peso_kg"             "Talla_cm"           
## [7] "Hemoglobina"         "Hematocrito"         "Ingesta_hierro"
ncol(df)
## [1] 9
summary(df)
##  Fecha_de_encuesta                   ID            Sexo          
##  Min.   :2024-01-02 00:00:00   Min.   : 1.00   Length:90         
##  1st Qu.:2024-04-12 18:00:00   1st Qu.:23.25   Class :character  
##  Median :2024-07-25 00:00:00   Median :45.50   Mode  :character  
##  Mean   :2024-07-15 20:16:00   Mean   :45.50                     
##  3rd Qu.:2024-10-02 06:00:00   3rd Qu.:67.75                     
##  Max.   :2024-12-29 00:00:00   Max.   :90.00                     
##                                                                  
##  Fecha_de_nacimiento              Peso_kg         Talla_cm      Hemoglobina   
##  Min.   :2005-11-01 00:00:00   Min.   : 3.20   Min.   : 48.0   Min.   :10.10  
##  1st Qu.:2010-08-13 00:00:00   1st Qu.:13.43   1st Qu.: 90.2   1st Qu.:11.50  
##  Median :2019-04-08 12:00:00   Median :19.45   Median :104.7   Median :12.10  
##  Mean   :2016-07-21 10:24:00   Mean   :29.25   Mean   :116.8   Mean   :12.33  
##  3rd Qu.:2022-04-17 18:00:00   3rd Qu.:49.27   3rd Qu.:159.1   3rd Qu.:13.10  
##  Max.   :2024-07-27 00:00:00   Max.   :71.10   Max.   :181.4   Max.   :16.10  
##                                                                NA's   :5      
##   Hematocrito    Ingesta_hierro 
##  Min.   :26.40   Min.   : 2.50  
##  1st Qu.:32.65   1st Qu.: 7.80  
##  Median :34.70   Median :24.60  
##  Mean   :35.47   Mean   :21.53  
##  3rd Qu.:38.05   3rd Qu.:33.60  
##  Max.   :49.50   Max.   :42.30  
##  NA's   :3       NA's   :1

1.1.4 Eliminación de datos faltantes

sum(!complete.cases(df))
## [1] 9
df1 <- df[complete.cases(df), ]
nrow(df1)
## [1] 81

1.1.5 Cálculo y categorización de la edad

1.1.6 Calcular edad en días, meses y años al momento de la encuesta

df1 <- df1 %>%
  mutate(
    edad_dias  = as.numeric(difftime(Fecha_de_encuesta,
                                      Fecha_de_nacimiento, units = "days")),
    edad_meses = edad_dias / 30.4375,
    edad_anos  = edad_dias / 365.25,
    sexo_num   = ifelse(Sexo == "M", 1, 2),   # 1 = Masculino, 2 = Femenino (estándar anthro)
    grupo_edad = cut(
      edad_anos,
      breaks = c(0, 5, 10, 15, 19.1),
      labels = c("< 5 años", "5–9 años", "10–14 años", "15–19 años"),
      right  = FALSE
    )
  )
glimpse(df1)
## Rows: 81
## Columns: 14
## $ Fecha_de_encuesta   <dttm> 2024-08-31, 2024-09-09, 2024-05-14, 2024-06-23, 2…
## $ ID                  <dbl> 1, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1…
## $ Sexo                <chr> "F", "M", "F", "F", "F", "F", "F", "F", "M", "M", …
## $ Fecha_de_nacimiento <dttm> 2021-12-31, 2023-02-08, 2021-02-11, 2021-11-22, 2…
## $ Peso_kg             <dbl> 11.2, 13.6, 13.7, 12.6, 9.2, 12.6, 15.0, 19.4, 18.…
## $ Talla_cm            <dbl> 90.8, 72.0, 92.4, 91.6, 63.2, 92.0, 94.5, 100.5, 9…
## $ Hemoglobina         <dbl> 12.7, 10.8, 12.0, 11.6, 10.3, 11.4, 11.5, 11.1, 11…
## $ Hematocrito         <dbl> 37.1, 32.5, 38.2, 34.9, 26.4, 34.1, 30.8, 32.8, 37…
## $ Ingesta_hierro      <dbl> 25.6, 8.3, 20.1, 8.4, 5.4, 8.4, 8.4, 8.2, 7.7, 7.6…
## $ edad_dias           <dbl> 974, 579, 1188, 944, 305, 1005, 1127, 1644, 1766, …
## $ edad_meses          <dbl> 32.000000, 19.022587, 39.030801, 31.014374, 10.020…
## $ edad_anos           <dbl> 2.6666667, 1.5852156, 3.2525667, 2.5845311, 0.8350…
## $ sexo_num            <dbl> 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, 2, 1, 2, 2, 2,…
## $ grupo_edad          <fct> < 5 años, < 5 años, < 5 años, < 5 años, < 5 años, …

1.1.7 zcore menores de 5 años

# Subconjunto < 5 años
df_lt5 <- df1 %>% filter(edad_anos < 5)

# Calcular puntajes Z con anthro
# oedema = "n" (sin edema), medida de longitud/talla estándar
zscore_lt5 <- anthro_zscores(
  sex    = df_lt5$sexo_num,
  age    = df_lt5$edad_dias,
  weight = df_lt5$Peso_kg,
  lenhei = df_lt5$Talla_cm,
  is_age_in_month = FALSE
)

# Unir resultados
df_lt5 <- bind_cols(df_lt5, zscore_lt5) %>%
  rename(
    WAZ = zwei,   # Peso para la edad
    HAZ = zlen,   # Talla para la edad
    WHZ = zwfl    # Peso para la talla
  )

# Clasificación nutricional OMS
df_lt5 <- df_lt5 %>%
  mutate(
    estado_WAZ = case_when(
      WAZ < -3              ~ "Desnutrición severa",
      WAZ >= -3 & WAZ < -2  ~ "Desnutrición moderada",
      WAZ >= -2 & WAZ <= 2  ~ "Normal",
      WAZ > 2               ~ "Sobrepeso/Obesidad",
      TRUE ~ NA_character_
    ),
    estado_HAZ = case_when(
      HAZ < -3              ~ "Talla baja severa",
      HAZ >= -3 & HAZ < -2  ~ "Talla baja moderada",
      HAZ >= -2             ~ "Talla normal",
      TRUE ~ NA_character_
    ),
    estado_WHZ = case_when(
      WHZ < -3              ~ "Desnutrición aguda severa",
      WHZ >= -3 & WHZ < -2  ~ "Desnutrición aguda moderada",
      WHZ >= -2 & WHZ < 1   ~ "Normal",
      WHZ >= 1  & WHZ < 2   ~ "Riesgo de sobrepeso",
      WHZ >= 2              ~ "Sobrepeso/Obesidad",
      TRUE ~ NA_character_
    )
  )

1.1.8 zscore 5 a 19 años

# Subconjunto 5–19 años
df_5a19 <- df1 %>% filter(edad_anos >= 5 & edad_anos < 19.1)

# Calcular puntajes Z con anthroplus (BAZ = BMI-for-age Z-score, HAZ = height-for-age)
zscore_5a19 <- anthroplus_zscores(
  sex    = df_5a19$sexo_num,
  age    = df_5a19$edad_anos * 12,  # edad en meses
  weight = df_5a19$Peso_kg,
  height = df_5a19$Talla_cm
)

df_5a19 <- bind_cols(df_5a19, zscore_5a19) %>%
  rename(
    BAZ = zbfa,   # IMC para la edad
    HAZ = zhfa    # Talla para la edad
  )



# Clasificación por BAZ (IMC/edad)
df_5a19 <- df_5a19 %>%
  mutate(
    estado_BAZ = case_when(
      BAZ < -3              ~ "Delgadez severa",
      BAZ >= -3 & BAZ < -2  ~ "Delgadez",
      BAZ >= -2 & BAZ <= 1  ~ "Normal",
      BAZ > 1   & BAZ <= 2  ~ "Sobrepeso",
      BAZ > 2               ~ "Obesidad",
      TRUE ~ NA_character_
    ),
    estado_HAZ = case_when(
      HAZ < -3              ~ "Talla baja severa",
      HAZ >= -3 & HAZ < -2  ~ "Talla baja moderada",
      HAZ >= -2             ~ "Talla normal",
      TRUE ~ NA_character_
    )
  )

2 Resultados

2.1 Análisis descriptivo

table1 (~Peso_kg + Talla_cm + Hemoglobina + Hematocrito + Ingesta_hierro + edad_anos + Sexo, data = df1, caption = "Características nutricionales de la población en general")
Características nutricionales de la población en general
Overall
(N=81)
Peso_kg
Mean (SD) 29.3 (19.7)
Median [Min, Max] 19.4 [3.20, 71.1]
Talla_cm
Mean (SD) 117 (42.1)
Median [Min, Max] 103 [48.0, 181]
Hemoglobina
Mean (SD) 12.3 (1.30)
Median [Min, Max] 12.0 [10.1, 16.1]
Hematocrito
Mean (SD) 35.7 (4.20)
Median [Min, Max] 34.8 [26.4, 49.5]
Ingesta_hierro
Mean (SD) 21.7 (13.5)
Median [Min, Max] 25.1 [2.50, 42.3]
edad_anos
Mean (SD) 8.01 (6.43)
Median [Min, Max] 4.92 [0, 18.8]
Sexo
F 42 (51.9%)
M 39 (48.1%)
table1 (~Peso_kg + Talla_cm + Hemoglobina + Hematocrito + Ingesta_hierro + edad_anos | Sexo, data = df1, caption = "Características nutricionales de la población por sexo")
Características nutricionales de la población por sexo
F
(N=42)
M
(N=39)
Overall
(N=81)
Peso_kg
Mean (SD) 29.9 (20.1) 28.6 (19.4) 29.3 (19.7)
Median [Min, Max] 18.9 [4.90, 71.1] 20.4 [3.20, 66.4] 19.4 [3.20, 71.1]
Talla_cm
Mean (SD) 120 (41.6) 114 (43.0) 117 (42.1)
Median [Min, Max] 102 [48.7, 180] 106 [48.0, 181] 103 [48.0, 181]
Hemoglobina
Mean (SD) 12.3 (1.35) 12.3 (1.26) 12.3 (1.30)
Median [Min, Max] 12.0 [10.2, 15.6] 12.1 [10.1, 16.1] 12.0 [10.1, 16.1]
Hematocrito
Mean (SD) 35.3 (4.52) 36.1 (3.83) 35.7 (4.20)
Median [Min, Max] 34.1 [26.4, 45.1] 35.6 [31.4, 49.5] 34.8 [26.4, 49.5]
Ingesta_hierro
Mean (SD) 20.8 (13.1) 22.7 (14.1) 21.7 (13.5)
Median [Min, Max] 22.8 [4.80, 42.3] 25.1 [2.50, 41.9] 25.1 [2.50, 42.3]
edad_anos
Mean (SD) 8.26 (6.62) 7.74 (6.30) 8.01 (6.43)
Median [Min, Max] 4.71 [0.167, 18.6] 5.08 [0, 18.8] 4.92 [0, 18.8]
table1 (~Peso_kg + Talla_cm + Hemoglobina + Hematocrito + Ingesta_hierro + Sexo | grupo_edad, data = df1, caption = "Características nutricionales de la población por rangos de edad")
Características nutricionales de la población por rangos de edad
< 5 años
(N=41)
5–9 años
(N=9)
10–14 años
(N=14)
15–19 años
(N=17)
Overall
(N=81)
Peso_kg
Mean (SD) 13.0 (4.63) 24.4 (4.84) 44.9 (7.13) 58.3 (5.08) 29.3 (19.7)
Median [Min, Max] 13.4 [3.20, 20.4] 23.2 [18.4, 31.2] 46.8 [27.7, 53.9] 56.9 [52.1, 71.1] 19.4 [3.20, 71.1]
Talla_cm
Mean (SD) 80.7 (18.1) 121 (9.69) 152 (9.05) 174 (4.87) 117 (42.1)
Median [Min, Max] 90.8 [48.0, 103] 124 [106, 133] 152 [139, 168] 174 [166, 181] 103 [48.0, 181]
Hemoglobina
Mean (SD) 11.5 (0.790) 12.4 (0.902) 13.0 (1.50) 13.5 (1.02) 12.3 (1.30)
Median [Min, Max] 11.6 [10.1, 13.3] 12.0 [11.0, 13.9] 12.4 [10.9, 16.1] 13.5 [11.4, 15.6] 12.0 [10.1, 16.1]
Hematocrito
Mean (SD) 33.8 (2.80) 35.6 (3.07) 37.4 (5.93) 38.6 (3.79) 35.7 (4.20)
Median [Min, Max] 33.7 [26.4, 39.2] 35.0 [31.8, 40.5] 35.1 [31.4, 49.5] 38.6 [32.0, 44.6] 34.8 [26.4, 49.5]
Ingesta_hierro
Mean (SD) 13.4 (10.5) 27.4 (12.6) 26.3 (13.6) 34.8 (4.23) 21.7 (13.5)
Median [Min, Max] 8.00 [2.50, 41.9] 29.9 [6.40, 39.7] 30.2 [6.30, 41.4] 35.9 [27.6, 42.3] 25.1 [2.50, 42.3]
Sexo
F 22 (53.7%) 4 (44.4%) 5 (35.7%) 11 (64.7%) 42 (51.9%)
M 19 (46.3%) 5 (55.6%) 9 (64.3%) 6 (35.3%) 39 (48.1%)

2.1.1 Prevalencia de malnutrición menores de 5 años

# WAZ
prev_WAZ <- df_lt5 %>%
  filter(!is.na(estado_WAZ)) %>%
  count(estado_WAZ) %>%
  mutate(Porcentaje = round(n / sum(n) * 100, 1))

kable(prev_WAZ, col.names = c("Estado Nutricional (WAZ)", "n", "%"),
      caption = "Clasificación por peso/edad — <5 años") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Clasificación por peso/edad —
Estado Nutricional (WAZ) n %
Desnutrición moderada 4 9.8
Normal 36 87.8
Sobrepeso/Obesidad 1 2.4
# WHZ
prev_WHZ <- df_lt5 %>%
  filter(!is.na(estado_WHZ)) %>%
  count(estado_WHZ) %>%
  mutate(Porcentaje = round(n / sum(n) * 100, 1))

kable(prev_WHZ, col.names = c("Estado Nutricional (WHZ)", "n", "%"),
      caption = "Clasificación por peso/talla — <5 años") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Clasificación por peso/talla —
Estado Nutricional (WHZ) n %
Normal 13 31.7
Riesgo de sobrepeso 2 4.9
Sobrepeso/Obesidad 26 63.4
#HAZ
prev_HAZ <- df_lt5 %>%
  mutate(
    estado_HAZ = factor(estado_HAZ,
                        levels = c("Talla baja severa",
                                   "Talla baja moderada",
                                   "Talla normal"))
  ) %>%                                    
  filter(!is.na(estado_HAZ)) %>%
  count(estado_HAZ) %>%
  mutate(Porcentaje = round(n / sum(n) * 100, 1))

kable(prev_HAZ,
      col.names = c("Estado Nutricional (HAZ)", "n", "%"),
      caption   = "Clasificación por talla/edad — <5 años") %>%
  kable_styling(latex_options = c("striped", "hover"), full_width = FALSE)
Clasificación por talla/edad —
Estado Nutricional (HAZ) n %
Talla baja severa 16 39.0
Talla baja moderada 3 7.3
Talla normal 22 53.7

2.1.2 Prevalencia de malnutrición niños y adolescentes de 5 a 19 años

prev_BAZ <- df_5a19 %>%
  mutate(
    estado_BAZ = factor(estado_BAZ,
                        levels = c("Delgadez severa",
                                   "Delgadez",
                                   "Normal",
                                   "Sobrepeso",
                                   "Obesidad"))
  ) %>%
  filter(!is.na(estado_BAZ)) %>%
  count(estado_BAZ) %>%
  mutate(Porcentaje = round(n / sum(n) * 100, 1))

kable(prev_BAZ,
      col.names = c("Estado Nutricional (BAZ)", "n", "%"),
      caption   = "Clasificación por IMC/edad — 5 a 19 años") %>%
  kable_styling(latex_options = c("striped", "hover"), full_width = FALSE)
Clasificación por IMC/edad — 5 a 19 años
Estado Nutricional (BAZ) n %
Delgadez severa 1 2.5
Delgadez 1 2.5
Normal 33 82.5
Sobrepeso 4 10.0
Obesidad 1 2.5

2.1.3 Clasificación de anemia por puntos de corte OMS

df1 <- df1 %>%
  mutate(
    # Puntos de corte hemoglobina (g/dL) según OMS 2011
    corte_hb = case_when(
      edad_anos < 5                          ~ 11.0,
      edad_anos >= 5  & edad_anos < 12       ~ 11.5,
      edad_anos >= 12 & edad_anos < 15       ~ 12.0,
      edad_anos >= 15 & Sexo == "F"          ~ 12.0,
      edad_anos >= 15 & Sexo == "M"          ~ 13.0,
      TRUE ~ NA_real_
    ),
    anemia = case_when(
      is.na(Hemoglobina) ~ NA_character_,
      Hemoglobina < corte_hb ~ "Anemia",
      TRUE ~ "Sin anemia"
    ),
    # Clasificar severidad
    severidad_anemia = case_when(
      is.na(Hemoglobina) ~ NA_character_,
      edad_anos < 5 & Hemoglobina < 7.0  ~ "Anemia severa",
      edad_anos < 5 & Hemoglobina < 10.0 ~ "Anemia moderada",
      edad_anos < 5 & Hemoglobina < 11.0 ~ "Anemia leve",
      edad_anos >= 5 & Hemoglobina < 8.0 ~ "Anemia severa",
      edad_anos >= 5 & Hemoglobina < 11.0 ~ "Anemia moderada",
      Hemoglobina >= corte_hb ~ "Sin anemia",
      TRUE ~ "Anemia leve"
    )
  )

2.1.4 Prevalencia global de anemia

prev_an <- df1 %>%
  filter(!is.na(anemia)) %>%
  count(anemia) %>%
  mutate(Porcentaje = round(n / sum(n) * 100, 1))

kable(prev_an, col.names = c("Estado", "n", "%"),
      caption = "Prevalencia global de anemia") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Prevalencia global de anemia
Estado n %
Anemia 18 22.2
Sin anemia 63 77.8

2.1.5 Gráfico: Anemia por grupo de edad

df1 %>%
  filter(!is.na(anemia)) %>%
  ggplot(aes(x = grupo_edad, fill = anemia)) +
  geom_bar(position = "fill") +
  facet_wrap(~Sexo, labeller = labeller(Sexo = c("F" = "Femenino", "M" = "Masculino"))) +
  scale_y_continuous(labels = percent_format()) +
  scale_fill_manual(values = c("Anemia" = "#E74C3C", "Sin anemia" = "#2ECC71")) +
  labs(
    title = "Prevalencia de anemia por grupo de edad y sexo",
    x = "Grupo de edad", y = "Proporción", fill = "Estado"
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1))
Prevalencia de anemia por grupo de edad y sexo

Prevalencia de anemia por grupo de edad y sexo

2.1.6 Prevalencia de anemia por grupo de edad y sexo

table1(~grupo_edad + Sexo | anemia , data=df1, caption = "Prevalencia de anemia según grupo de edad y sexo")
Prevalencia de anemia según grupo de edad y sexo
Anemia
(N=18)
Sin anemia
(N=63)
Overall
(N=81)
grupo_edad
< 5 años 12 (66.7%) 29 (46.0%) 41 (50.6%)
5–9 años 1 (5.6%) 8 (12.7%) 9 (11.1%)
10–14 años 2 (11.1%) 12 (19.0%) 14 (17.3%)
15–19 años 3 (16.7%) 14 (22.2%) 17 (21.0%)
Sexo
F 9 (50.0%) 33 (52.4%) 42 (51.9%)
M 9 (50.0%) 30 (47.6%) 39 (48.1%)

2.1.7 Prevalencia de suficiente ingesta de hierro

# Recomendaciones OMS/IOM de ingesta de hierro (mg/día)
df1 <- df1 %>%
  mutate(
    rec_hierro = case_when(
      edad_anos < 1                          ~ 11,
      edad_anos >= 1  & edad_anos < 4        ~ 7,
      edad_anos >= 4  & edad_anos < 9        ~ 10,
      edad_anos >= 9  & edad_anos < 14       ~ 8,
      edad_anos >= 14 & Sexo == "F"          ~ 15,
      edad_anos >= 14 & Sexo == "M"          ~ 11,
      TRUE ~ NA_real_
    ),
    adecuacion_hierro = case_when(
      is.na(Ingesta_hierro) ~ NA_character_,
      Ingesta_hierro >= rec_hierro ~ "Adecuada",
      TRUE ~ "Inadecuada"
    )
  )

prev_hierro <- df1 %>%
  filter(!is.na(adecuacion_hierro)) %>%
  count(adecuacion_hierro) %>%
  mutate(Porcentaje = round(n / sum(n) * 100, 1))

kable(prev_hierro, col.names = c("Adecuación de ingesta", "n", "%"),
      caption = "Adecuación de la ingesta de hierro") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Adecuación de la ingesta de hierro
Adecuación de ingesta n %
Adecuada 57 70.4
Inadecuada 24 29.6

2.2 Análisis inferencial

2.2.1 Análisis de independencia entre

df_lt5 %>%
  select(estado_WHZ, estado_HAZ, Sexo) %>%
  tbl_summary(
    by = Sexo,
    label = list(
      estado_WHZ ~ "Estado nutricional (WHZ)",
      estado_HAZ     ~ "Talla para la edad (HAZ)"
    ),
    missing = "no"
  ) %>%
  add_p(test = list(all_categorical() ~ "fisher.test")) %>%
  add_overall() %>%
  bold_labels() %>%
  modify_caption("Estado nutricional por sexo — Menores de 5 años")
Estado nutricional por sexo — Menores de 5 años
Characteristic Overall
N = 41
1
F
N = 22
1
M
N = 19
1
p-value2
Estado nutricional (WHZ)


0.9
    Normal 13 (32%) 8 (36%) 5 (26%)
    Riesgo de sobrepeso 2 (4.9%) 1 (4.5%) 1 (5.3%)
    Sobrepeso/Obesidad 26 (63%) 13 (59%) 13 (68%)
Talla para la edad (HAZ)


0.049
    Talla baja moderada 3 (7.3%) 0 (0%) 3 (16%)
    Talla baja severa 16 (39%) 7 (32%) 9 (47%)
    Talla normal 22 (54%) 15 (68%) 7 (37%)
1 n (%)
2 Fisher’s exact test
df_5a19 %>%
  select(estado_BAZ, Sexo) %>%
  tbl_summary(
    by = Sexo,
    label = list(
      estado_BAZ ~ "Estado nutricional (BAZ)"
    ),
    missing = "no"
  ) %>%
  add_p(test = list(all_categorical() ~ "fisher.test")) %>%
  add_overall() %>%
  bold_labels() %>%
  modify_caption("Estado nutricional por sexo — 5 a 19 años")
Estado nutricional por sexo — 5 a 19 años
Characteristic Overall
N = 40
1
F
N = 20
1
M
N = 20
1
p-value2
Estado nutricional (BAZ)


0.008
    Delgadez 1 (2.5%) 0 (0%) 1 (5.0%)
    Delgadez severa 1 (2.5%) 0 (0%) 1 (5.0%)
    Normal 33 (83%) 20 (100%) 13 (65%)
    Obesidad 1 (2.5%) 0 (0%) 1 (5.0%)
    Sobrepeso 4 (10%) 0 (0%) 4 (20%)
1 n (%)
2 Fisher’s exact test

2.2.2 Asociación entre ingesta de hierro y hemoglobina

shapiro.test(df1$Hematocrito)
## 
##  Shapiro-Wilk normality test
## 
## data:  df1$Hematocrito
## W = 0.94185, p-value = 0.001116
shapiro.test(df1$Hemoglobina)
## 
##  Shapiro-Wilk normality test
## 
## data:  df1$Hemoglobina
## W = 0.96187, p-value = 0.01651
shapiro.test(df1$Ingesta_hierro)
## 
##  Shapiro-Wilk normality test
## 
## data:  df1$Ingesta_hierro
## W = 0.83816, p-value = 5.741e-08
# Correlación de spearman 
cor_test <- cor.test(df1$Ingesta_hierro, df1$Hemoglobina,
                     method = "spearman", exact = FALSE)

cat("Correlación de spearman (Ingesta hierro vs Hemoglobina):\n")
## Correlación de spearman (Ingesta hierro vs Hemoglobina):
cat("  rho =", round(cor_test$estimate, 3), "\n")
##   rho = 0.762
cat(" p-valor =", ifelse(cor_test$p.value < 0.001, "< 0.001", 
                          round(cor_test$p.value, 4)), "\n")
##  p-valor = < 0.001
df1 %>%
  ggplot(aes(x = Ingesta_hierro, y = Hemoglobina, color = grupo_edad)) +
  geom_point(alpha = 0.7, size = 2.5) +
  geom_smooth(method = "lm", se = TRUE, color = "black", linetype = "dashed") +
  geom_hline(yintercept = 11.5, color = "red", linetype = "dotted") +
  annotate("text", x = 35, y = 11.2, label = "Corte anemia (ref.)", size = 3) +
  labs(
    title = "Ingesta de hierro vs Hemoglobina",
    x = "Ingesta de hierro (mg/día)",
    y = "Hemoglobina (g/dL)",
    color = "Grupo de edad"
  ) +
  theme_minimal()
Relación entre ingesta de hierro y hemoglobina

Relación entre ingesta de hierro y hemoglobina

2.2.3 Asociación entre ingesta de hierro y hematocrito

# Correlación de spearman 
cor_test <- cor.test(df1$Ingesta_hierro, df1$Hematocrito,
                     method = "spearman", exact = FALSE)

cat("Correlación de spearman (Ingesta hierro vs Hematocrito):\n")
## Correlación de spearman (Ingesta hierro vs Hematocrito):
cat("  rho =", round(cor_test$estimate, 3), "\n")
##   rho = 0.542
cat(" p-valor =", ifelse(cor_test$p.value < 0.001, "< 0.001", 
                          round(cor_test$p.value, 4)), "\n")
##  p-valor = < 0.001
df1 %>%
  ggplot(aes(x = Ingesta_hierro, y = Hematocrito, color = Sexo)) +
  geom_point(alpha = 0.7, size = 2.5) +
  geom_smooth(method = "lm", se = TRUE, color = "black", linetype = "dashed") +
  labs(
    title = "Ingesta de hierro vs Hematocrito",
    x = "Ingesta de hierro (mg/día)",
    y = "Hematocrito (%)",
    color = "Grupo de edad"
  ) +
  theme_minimal()
Relación entre ingesta de hierro y hematocrito

Relación entre ingesta de hierro y hematocrito

2.2.4 Regresión logística: Predictores de anemia

# Codificar anemia como binaria
df_modelo <- df1 %>%
  mutate(anemia_bin = ifelse(anemia == "Anemia", 1, 0)) %>%
  filter(!is.na(anemia_bin), !is.na(Ingesta_hierro))

modelo <- glm(anemia_bin ~ edad_anos + Sexo + Ingesta_hierro,
              data = df_modelo, family = binomial(link = "logit"))

summary(modelo)
## 
## Call:
## glm(formula = anemia_bin ~ edad_anos + Sexo + Ingesta_hierro, 
##     family = binomial(link = "logit"), data = df_modelo)
## 
## Coefficients:
##                 Estimate Std. Error z value Pr(>|z|)   
## (Intercept)     0.001116   0.562158   0.002  0.99842   
## edad_anos       0.142682   0.078347   1.821  0.06858 . 
## SexoM           0.218092   0.605835   0.360  0.71886   
## Ingesta_hierro -0.137756   0.042368  -3.251  0.00115 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 85.812  on 80  degrees of freedom
## Residual deviance: 67.878  on 77  degrees of freedom
## AIC: 75.878
## 
## Number of Fisher Scoring iterations: 5
# Extraer coeficientes
coefs <- summary(modelo)$coefficients

# Construir tabla completa
cbind(
  Logit = coef(modelo),
  OR    = exp(coef(modelo)),
  exp(confint(modelo))
) %>%
  round(3) %>%
  as.data.frame() %>%
  tibble::rownames_to_column("Variable") %>%
  filter(Variable != "(Intercept)") %>%
  mutate(
    Variable = recode(Variable,
      "edad_anos"      = "Edad (años)",
      "SexoM"          = "Sexo masculino",
      "Ingesta_hierro" = "Ingesta de hierro (mg/día)"
    ),
    # p-valor
    p_valor = coefs[-1, 4],
    p_valor = ifelse(p_valor < 0.001, "< 0.001", round(p_valor, 4))
  ) %>%
  rename("IC 2.5%" = `2.5 %`, "IC 97.5%" = `97.5 %`) %>%
  select(Variable, Logit, OR, `IC 2.5%`, `IC 97.5%`, p_valor) %>%
  kable(caption = "Regresión logística — Logit, OR") %>%
  kable_styling(latex_options = c("striped", "hold_position"), full_width = FALSE)
Regresión logística — Logit, OR
Variable Logit OR IC 2.5% IC 97.5% p_valor
Edad (años) 0.143 1.153 1.000 1.369 0.0686
Sexo masculino 0.218 1.244 0.373 4.134 0.7189
Ingesta de hierro (mg/día) -0.138 0.871 0.791 0.938 0.0011

2.2.5 Asociación entre adecuación de hierro y anemia

tabla_2x2 <- table(
  df1$adecuacion_hierro,
  df1$anemia
)

tabla_2x2
##             
##              Anemia Sin anemia
##   Adecuada        7         50
##   Inadecuada     11         13

2.2.6 Prueba exacta de Fisher

fisher_anemia <- fisher.test(tabla_2x2)

fisher_anemia
## 
##  Fisher's Exact Test for Count Data
## 
## data:  tabla_2x2
## p-value = 0.002364
## alternative hypothesis: true odds ratio is not equal to 1
## 95 percent confidence interval:
##  0.04563354 0.58703127
## sample estimates:
## odds ratio 
##   0.170107

2.2.7 OR e IC95%

epi.2by2(
  tabla_2x2,
  method = "cohort.count",
  conf.level = 0.95
)
##              Outcome+    Outcome-      Total                 Inc risk *
## Exposure+           7          50         57      12.28 (5.08 to 23.68)
## Exposure-          11          13         24     45.83 (25.55 to 67.18)
## Total              18          63         81     22.22 (13.73 to 32.83)
## 
## Point estimates and 95% CIs:
## -------------------------------------------------------------------
## Inc risk ratio                                 0.27 (0.12, 0.61)
## Inc odds ratio                                 0.17 (0.05, 0.51)
## Attrib risk in the exposed *                   -33.55 (-55.23, -11.87)
## Attrib fraction in the exposed (%)            -273.21 (-732.23, -67.14)
## Attrib risk in the population *                -23.61 (-45.51, -1.72)
## Attrib fraction in the population (%)         -106.25 (-104.64, -86.05)
## E-value                                        6.93 (NA, 2.68)
## -------------------------------------------------------------------
## Uncorrected chi2 test that OR = 1: chi2(1) = 11.000 Pr>chi2 = <0.001
## Fisher exact test that OR = 1: Pr>chi2 = 0.002
## Wald confidence limits
## CI: confidence interval
## * Outcomes per 100 population units

2.2.8 Reexpresión del OR tomando como exposición la ingesta inadecuada de hierro

OR <- (11*50)/(13*7)

IC95_inf <- 1/0.58703127
IC95_sup <- 1/0.04563354

data.frame(
  OR = round(OR,2),
  IC95_inf = round(IC95_inf,2),
  IC95_sup = round(IC95_sup,2),
  p_valor = round(fisher_anemia$p.value,3)
)
##     OR IC95_inf IC95_sup p_valor
## 1 6.04      1.7    21.91   0.002