6  Sécurité alimentaire

Ce chapitre traite de la sécurité alimentaire des ménages des observatoires ruraux d’Alaotra et de Marovoay. Il aborde trois dimensions : la période de soudure et le stress alimentaire, l’alimentation de base hors et pendant la soudure, et les stratégies d’adaptation adoptées par les ménages.

WarningTravail de vérification en cours

Les résultats présentés ci-dessous sont provisoires, et sont susceptibles de faire l’objet de corrections.

Code
options(encoding = "UTF-8")

library(tidyverse)
library(haven)
library(gt)

# Loading observatories data
res_deb <- read_dta("data/ROS_MDG_microdata/2025/res_deb.dta")
# Loading food security data
res_sa <- read_dta("data/ROS_MDG_microdata/2025/res_sa.dta")
# Loading food security strategy data
res_ssa <- read_dta("data/ROS_MDG_microdata/2025/res_ssa.dta")

# Préparer la variable Observatory dans res_deb
res_deb <- res_deb %>%
  mutate(
    Observatory = case_when(
      j0 == 3  ~ "Marovoay",
      j0 == 21 ~ "Alaotra",
      TRUE     ~ as.character(j0)
    ),
    j4bis = case_when(
      str_starts(str_to_lower(j4), "bepako")          ~ "Bepako",
      str_starts(str_to_lower(j4), "ampijoroa")       ~ "Ampijoroa",
      str_starts(str_to_lower(j4), "maroala")          ~ "Maroala",
      str_starts(str_to_lower(j4), "madiromiongana")   ~ "Madiromiongana",
      TRUE ~ j4
    )
  )

source("utils/helpers_report.R")
source("utils/sites.R")
source("utils/downloadable_output.R")

# Add Site column
res_deb <- assign_site(res_deb)
res_deb <- res_deb %>% filter_for_profile()

res_deb_site <- res_deb |> expand_sites_for_profile()

# Pre-joined datasets for site-level downloads
sa_full  <- res_sa  %>% left_join(res_deb %>% select(j5, Observatory, Site, j4bis), by = "j5") %>% filter(!is.na(Observatory))
ssa_full <- res_ssa %>% left_join(res_deb %>% select(j5, Observatory, Site), by = "j5") %>% filter(!is.na(Observatory))

6.1 Disponibilité alimentaire

La sécurité alimentaire des ménages ruraux est étroitement liée au calendrier agricole et à la gestion des stocks.

Dans l’Alaotra, 100 % des ménages déclarent au moins un mois de soudure.

A Marovoay, 97.3 % des ménages déclarent au moins un mois de soudure.

6.1.1 Période de soudure

La période de soudure désigne les mois durant lesquels les stocks alimentaires du ménage sont insuffisants pour couvrir ses besoins.

Dans l’Alaotra, La soudure dure en moyenne 3.8 mois (médiane : 3).

A Marovoay, La soudure dure en moyenne 2.2 mois (médiane : 2).

6.1.1.1 Durée de la soudure par observatoire

Code
# T1 : Statistiques descriptives du nombre de mois de soudure par observatoire
soudure_stats <- res_sa %>%
  left_join(res_deb, by = "j5") %>%
  group_by(Observatory) %>%
  summarise(
    `Nombre de ménages` = n(),
    Minimum = min(sal2d, na.rm = TRUE),
    Médiane = median(sal2d, na.rm = TRUE),
    Moyenne = round(mean(sal2d, na.rm = TRUE), 1),
    Maximum = max(sal2d, na.rm = TRUE),
    `Écart-type` = round(sd(sal2d, na.rm = TRUE), 1),
    .groups = "drop"
  )

soudure_stats %>%
  gt() %>%
  tab_header(
    title = "Durée de la période de soudure par observatoire",
    subtitle = "Nombre de mois de soudure (sal2d)"
  ) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  )
Durée de la période de soudure par observatoire
Nombre de mois de soudure (sal2d)
Observatory Nombre de ménages Minimum Médiane Moyenne Maximum Écart-type
Alaotra 507 1 3 3.8 12 1.8
Marovoay 519 0 2 2.2 11 1.4
📥 Télécharger par hameau et par observatoire

6.1.1.2 Durée de la soudure par hameau et observatoire

📥 Télécharger par hameau et par observatoire

Durée moyenne de la soudure par hameau
📥 Télécharger par hameau et par observatoire

6.1.1.3 Distribution du nombre de mois de soudure

Code
# G1 : Histogramme de la distribution du nombre de mois de soudure
res_sa %>%
  left_join(res_deb, by = "j5") %>%
  expand_sites_for_profile() %>%
  filter(!is.na(sal2d)) %>%
  mutate(sal2d = factor(sal2d)) %>%
  count(Observatory, sal2d) %>%
  mutate(pct = round(n / sum(n) * 100, 1), .by = Observatory) %>%
  ror_bar_v(x = sal2d, y_label = "% ménages", x_angle = 45)

📥 Télécharger par hameau et par observatoire

6.1.1.4 Calendrier de la soudure

📥 Télécharger par hameau et par observatoire
Code
# G2 : Graphique du calendrier de la soudure
calendrier_soudure %>%
  ror_bar_v(x = Mois, y_label = "% ménages en soudure", x_angle = 45)

📥 Télécharger par hameau et par observatoire

6.1.2 Stress alimentaire

Le stress alimentaire reflète les mois durant lesquels le ménage éprouve des difficultés à se nourrir correctement, que ce soit en quantité ou en qualité. Sa durée est généralement supérieure à celle de la soudure stricto sensu.

Dans l’Alaotra, La durée moyenne du stress alimentaire atteint 2.5 mois.

A Marovoay, La durée moyenne du stress alimentaire atteint 3.3 mois.

6.1.2.1 Durée du stress alimentaire par observatoire

Code
# T4 : Statistiques du stress alimentaire par observatoire
stress_stats <- res_sa %>%
  left_join(res_deb, by = "j5") %>%
  group_by(Observatory) %>%
  summarise(
    `Nombre de ménages` = n(),
    Minimum = min(sal15a, na.rm = TRUE),
    Médiane = median(sal15a, na.rm = TRUE),
    Moyenne = round(mean(sal15a, na.rm = TRUE), 1),
    Maximum = max(sal15a, na.rm = TRUE),
    `Écart-type` = round(sd(sal15a, na.rm = TRUE), 1),
    .groups = "drop"
  )

stress_stats %>%
  gt() %>%
  tab_header(
    title = "Durée du stress alimentaire par observatoire",
    subtitle = "Nombre de mois de stress alimentaire (sal15a)"
  ) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  )
Durée du stress alimentaire par observatoire
Nombre de mois de stress alimentaire (sal15a)
Observatory Nombre de ménages Minimum Médiane Moyenne Maximum Écart-type
Alaotra 507 0 2 2.5 12 1.6
Marovoay 519 0 3 3.3 12 2.0
📥 Télécharger par hameau et par observatoire

6.1.2.2 Calendrier du stress alimentaire

6.1.2.3 Comparaison soudure et stress alimentaire

Code
# G3 : Superposition soudure vs stress alimentaire
comparaison <- bind_rows(
  calendrier_soudure %>% mutate(Indicateur = "Soudure"),
  calendrier_stress %>% mutate(Indicateur = "Stress alimentaire")
)

comparaison %>%
  ror_bar_grouped(x = Mois, fill = Indicateur,
                  y_label = "% ménages", direction = "vertical",
                  x_angle = 45)
Figure 6.1: Comparaison soudure et stress alimentaire

6.1.3 Alimentation de base

Cette section compare les aliments de base consommés aux trois repas, hors et pendant la période de soudure. Le riz constitue la base alimentaire dans les deux observatoires, mais sa place relative varie selon la saison et le site. Les substitutions opérées pendant la soudure (manioc, patate douce, maïs) témoignent des stratégies d’adaptation alimentaire des ménages.

Code
# Définir les labels des aliments
alim_labels <- c(
  "1" = "Riz", "2" = "Maïs", "3" = "Patate douce",
  "4" = "Manioc", "5" = "Pain/beignet/galettes", "6" = "Pomme de terre",
  "7" = "Taro", "8" = "Blé/farine de blé", "9" = "Millet/sorgho",
  "11" = "Autre céréale", "12" = "Igname",
  "14" = "Autre racine/tubercule", "15" = "Pâte alimentaire",
  "23" = "Banane", "24" = "Fruit à pain",
  "25" = "Boisson chaude", "26" = "Lait", "27" = "Fruit sauvage",
  "28" = "Rien", "29" = "Brèdes", "30" = "Légumineuse seule",
  "31" = "Légumineuse+Céréale", "32" = "Céréale+Légumes",
  "33" = "Mélange tubercules", "34" = "Tubercule+Céréale",
  "35" = "Tubercule+Légumes", "36" = "Autres mélanges"
)

6.1.3.1 Alimentation hors soudure

Code
# T6 : Aliment principal aux 3 repas hors soudure, par observatoire
alim_hors <- res_sa %>%
  left_join(res_deb, by = "j5") %>%
  select(Observatory, sal1a, sal1b, sal1c) %>%
  pivot_longer(
    cols = c(sal1a, sal1b, sal1c),
    names_to = "repas_var",
    values_to = "aliment_code"
  ) %>%
  mutate(
    Repas = case_when(
      repas_var == "sal1a" ~ "Petit-déjeuner",
      repas_var == "sal1b" ~ "Déjeuner",
      repas_var == "sal1c" ~ "Dîner"
    ),
    Aliment = alim_labels[as.character(aliment_code)]
  ) %>%
  filter(!is.na(Aliment)) %>%
  count(Observatory, Repas, Aliment) %>%
  group_by(Observatory, Repas) %>%
  mutate(pct = round(n / sum(n) * 100, 1)) %>%
  ungroup() %>%
  filter(pct >= 2) %>%
  arrange(Observatory, Repas, desc(pct))

alim_hors %>%
  select(Observatory, Repas, Aliment, pct) %>%
  obs_gt() %>%
  tab_header(
    title = "Alimentation de base hors soudure par observatoire",
    subtitle = "Aliments représentant au moins 2% des réponses"
  ) %>%
  cols_label(Repas = "Repas", Aliment = "Aliment", pct = "%") %>%
  fmt_number(columns = pct, decimals = 1) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  ) %>%
  tab_options(row_group.font.weight = "bold")
Alimentation de base hors soudure par observatoire
Aliments représentant au moins 2% des réponses
Repas Aliment %
Alaotra
Déjeuner Riz 93.5
Déjeuner Manioc 4.0
Dîner Riz 99.6
Petit-déjeuner Riz 97.8
Marovoay
Déjeuner Riz 95.2
Déjeuner Maïs 2.5
Dîner Riz 99.6
Petit-déjeuner Riz 89.9
Petit-déjeuner Rien 2.7
Petit-déjeuner Boisson chaude 2.3

6.1.3.2 Alimentation pendant la soudure

Code
# T7 : Aliment principal aux 3 repas pendant la soudure
alim_pendant <- res_sa %>%
  left_join(res_deb, by = "j5") %>%
  select(Observatory, sal2a, sal2b, sal2c) %>%
  pivot_longer(
    cols = c(sal2a, sal2b, sal2c),
    names_to = "repas_var",
    values_to = "aliment_code"
  ) %>%
  mutate(
    Repas = case_when(
      repas_var == "sal2a" ~ "Petit-déjeuner",
      repas_var == "sal2b" ~ "Déjeuner",
      repas_var == "sal2c" ~ "Dîner"
    ),
    Aliment = alim_labels[as.character(aliment_code)]
  ) %>%
  filter(!is.na(Aliment)) %>%
  count(Observatory, Repas, Aliment) %>%
  group_by(Observatory, Repas) %>%
  mutate(pct = round(n / sum(n) * 100, 1)) %>%
  ungroup() %>%
  filter(pct >= 2) %>%
  arrange(Observatory, Repas, desc(pct))

alim_pendant %>%
  select(Observatory, Repas, Aliment, pct) %>%
  obs_gt() %>%
  tab_header(
    title = "Alimentation de base pendant la soudure par observatoire",
    subtitle = "Aliments représentant au moins 2% des réponses"
  ) %>%
  cols_label(Repas = "Repas", Aliment = "Aliment", pct = "%") %>%
  fmt_number(columns = pct, decimals = 1) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  ) %>%
  tab_options(row_group.font.weight = "bold")
Alimentation de base pendant la soudure par observatoire
Aliments représentant au moins 2% des réponses
Repas Aliment %
Alaotra
Déjeuner Riz 52.6
Déjeuner Manioc 27.4
Déjeuner Maïs 16.7
Dîner Riz 98.0
Petit-déjeuner Riz 92.0
Petit-déjeuner Rien 3.6
Marovoay
Déjeuner Riz 60.8
Déjeuner Maïs 20.7
Déjeuner Manioc 11.5
Déjeuner Patate douce 4.6
Dîner Riz 92.5
Dîner Manioc 2.6
Dîner Maïs 2.4
Petit-déjeuner Riz 55.7
Petit-déjeuner Rien 25.3
Petit-déjeuner Manioc 6.1
Petit-déjeuner Boisson chaude 3.6
Petit-déjeuner Maïs 3.4
Petit-déjeuner Patate douce 2.8

6.1.3.3 Comparaison de l’alimentation au déjeuner : hors vs pendant soudure

Code
# G4 : Comparaison hors soudure vs pendant soudure au déjeuner (top 5 aliments)
comp_dejeuner <- res_sa %>%
  left_join(res_deb, by = "j5") %>%
  select(Observatory, sal1b, sal2b) %>%
  pivot_longer(
    cols = c(sal1b, sal2b),
    names_to = "periode",
    values_to = "aliment_code"
  ) %>%
  mutate(
    Période = if_else(periode == "sal1b", "Hors soudure", "Pendant soudure"),
    Aliment = alim_labels[as.character(aliment_code)]
  ) %>%
  filter(!is.na(Aliment)) %>%
  count(Observatory, Période, Aliment) %>%
  group_by(Observatory, Période) %>%
  mutate(pct = round(n / sum(n) * 100, 1)) %>%
  ungroup()

# Garder le top 5 des aliments les plus fréquents
top_aliments <- comp_dejeuner %>%
  group_by(Aliment) %>%
  summarise(total = sum(n), .groups = "drop") %>%
  slice_max(total, n = 5) %>%
  pull(Aliment)

comp_dejeuner %>%
  filter(Aliment %in% top_aliments) %>%
  ror_bar_grouped(x = Aliment, fill = Période,
                  y_label = "% ménages", direction = "horizontal")

6.1.3.4 Changement d’aliment de base au déjeuner entre hors et pendant soudure

Code
# T8 : Matrice de transition simplifiée (déjeuner)
transition <- res_sa %>%
  left_join(res_deb, by = "j5") %>%
  mutate(
    Hors_soudure = alim_labels[as.character(sal1b)],
    Pendant_soudure = alim_labels[as.character(sal2b)]
  ) %>%
  filter(!is.na(Hors_soudure) & !is.na(Pendant_soudure)) %>%
  count(Observatory, Hors_soudure, Pendant_soudure) %>%
  group_by(Observatory) %>%
  mutate(pct = round(n / sum(n) * 100, 1)) %>%
  ungroup() %>%
  filter(pct >= 1) %>%
  arrange(Observatory, desc(pct))

transition %>%
  select(Observatory, Hors_soudure, Pendant_soudure, n, pct) %>%
  obs_gt() %>%
  tab_header(
    title = "Changement d'aliment de base au déjeuner",
    subtitle = "Transitions hors soudure → pendant soudure (≥ 1%)"
  ) %>%
  cols_label(
    Hors_soudure = "Hors soudure",
    Pendant_soudure = "Pendant soudure",
    pct = "%"
  ) %>%
  cols_hide(n) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  ) %>%
  tab_options(row_group.font.weight = "bold")
Changement d'aliment de base au déjeuner
Transitions hors soudure → pendant soudure (≥ 1%)
Hors soudure Pendant soudure %
Alaotra
Riz Riz 52.2
Riz Manioc 23.4
Riz Maïs 15.3
Manioc Manioc 3.6
Riz Patate douce 1.2
Riz Autres mélanges 1.0
Marovoay
Riz Riz 60.6
Riz Maïs 18.1
Riz Manioc 9.7
Riz Patate douce 4.2
Maïs Maïs 2.2
Manioc Manioc 1.6
Riz Rien 1.0

6.2 Stratégies de sécurité alimentaire

Face à l’insécurité alimentaire, les ménages déploient un éventail de stratégies d’adaptation dont la sévérité varie : réduction des portions, substitution d’aliments, endettement, cueillette sauvage, voire décapitalisation. Chaque stratégie est évaluée sur une échelle de fréquence : 0 = Jamais, 1 = Rarement, 2 = Quelquefois, 3 = Souvent.

6.2.1 Fréquence des stratégies d’adaptation

Code
# G5 : Barres horizontales empilées — profil Likert des stratégies
strat_plot <- strat_data %>%
  mutate(
    Fréquence = factor(Fréquence, levels = c("Souvent", "Quelquefois", "Rarement", "Jamais"))
  )

ggplot(strat_plot, aes(x = pct, y = reorder(Stratégie, pct), fill = Fréquence)) +
  geom_col(position = "stack") +
  facet_wrap(~Observatory) +
  labs(
    title = "Profil de fréquence des stratégies d'adaptation",
    x = "% de ménages",
    y = NULL,
    fill = "Fréquence"
  ) +
  scale_fill_manual(values = c(
    "Souvent" = "#d62728", "Quelquefois" = "#ff7f0e",
    "Rarement" = "#ffbb78", "Jamais" = "#aec7e8"
  )) +
  theme_ror() +
  theme(
    plot.title = element_text(face = "bold", size = 12),
    axis.text.y = element_text(size = 8)
  )

6.2.2 Sources d’endettement et d’emprunt alimentaire

Sources d’endettement alimentaire
📥 Télécharger par hameau et par observatoire

Sources d’emprunt d’aliments de base
📥 Télécharger par hameau et par observatoire
Code
# G6 : Top 5 des stratégies les plus fréquentes
top5 <- strat_resume %>%
  slice_head(n = 5) %>%
  pivot_longer(cols = where(is.numeric), names_to = "Observatory", values_to = "pct")
Code
top5 %>%
  make_bar_obs(x = Stratégie, y_label = "% ménages")

6.3 Indice synthétique de stratégies d’adaptation (CSI simplifié)

Un score simplifié est calculé en sommant les fréquences de toutes les stratégies (0 à 3) pour chaque ménage. Plus le score est élevé, plus le ménage recourt intensément à des stratégies d’adaptation.

Code
# T12 : Score CSI simplifié par observatoire et hameau
csi <- res_ssa %>%
  left_join(res_deb, by = "j5") %>%
  mutate(
    csi_score = rowSums(across(all_of(strat_vars), ~replace_na(., 0)))
  )

csi_hameau <- csi %>%
  group_by(Observatory, j4bis) %>%
  summarise(
    n_hh = n(),
    mean_csi = round(mean(csi_score, na.rm = TRUE), 1),
    .groups = "drop"
  )

# Ajouter lignes "Ensemble"
csi_combined <- csi_hameau %>%
  group_by(Observatory) %>%
  summarise(
    j4bis = "Ensemble",
    mean_csi = round(weighted.mean(mean_csi, n_hh), 1),
    n_hh = sum(n_hh),
    .groups = "drop"
  ) %>%
  bind_rows(csi_hameau, .) %>%
  arrange(Observatory, j4bis == "Ensemble", j4bis)

csi_combined %>%
  obs_gt() %>%
  tab_header(
    title = "Score CSI simplifié par hameau et observatoire",
    subtitle = "Somme des fréquences des stratégies (0–3 par stratégie)"
  ) %>%
  cols_label(j4bis = "Hameau", n_hh = "Nb ménages", mean_csi = "Score CSI moyen") %>%
  tab_style(
    style = list(cell_text(weight = "bold"), cell_fill(color = "#F0F0F0")),
    locations = cells_body(rows = j4bis == "Ensemble")
  ) %>%
  tab_options(row_group.font.weight = "bold") %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  )
Score CSI simplifié par hameau et observatoire
Somme des fréquences des stratégies (0–3 par stratégie)
Hameau Nb ménages Score CSI moyen
Alaotra
Ambatoharanana 31 7.2
Ambatomanga 68 8.6
Ambodivoara 58 8.3
Ambohidrony 52 9.0
Analamiranga 46 8.5
Avaradrano 90 6.8
Feramanga Atsimo 89 10.1
Mangabe 73 8.5
Ensemble 507 8.4
Marovoay
Ampijoroa 143 9.6
Bepako 123 9.1
Madiromiongana 137 9.3
Maroala 116 10.0
Ensemble 519 9.5
Code
# G7 : Distribution du score CSI par observatoire
ggplot(csi, aes(x = Observatory, y = csi_score, fill = Observatory)) +
  geom_boxplot(show.legend = FALSE) +
  labs(
    title = "Distribution du score CSI simplifié par observatoire",
    x = "Observatoire",
    y = "Score CSI"
  ) +
  theme_ror() +
  theme(plot.title = element_text(face = "bold", size = 12))

6.4 Évolution de la sécurité alimentaire (1995–2025)

La durée de la période de soudure (sal2d, en mois) est disponible pour un nombre significatif de campagnes. On retrace ici son évolution pour les deux observatoires.

Code
sa_trends |> make_trend_plot(y_var = soudure_moy, y_label = "Durée moyenne soudure (mois)", gap_year = 2015)

Évolution de la durée moyenne de soudure (mois/ménage)
Code
sa_trends |> make_trend_plot(y_var = pct_soudure, y_label = "% ménages en soudure", gap_year = 2015)

Évolution du pourcentage de ménages en soudure