library(shiny)
library(dplyr)
## 
## Attachement du package : 'dplyr'
## Les objets suivants sont masqués depuis 'package:stats':
## 
##     filter, lag
## Les objets suivants sont masqués depuis 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
df <- readr::read_csv("enquete_menages_2024.csv", show_col_types = FALSE)

# Afficher les 10 premières lignes
head(df, 10)
## # A tibble: 10 × 16
##    id_menage region       milieu taille_menage sexe_chef age_chef revenu_mensuel
##        <dbl> <chr>        <chr>          <dbl> <chr>        <dbl>          <dbl>
##  1         1 Nouakchott   Urbain             5 Homme           42         520000
##  2         2 Hodh Charghi Rural              8 Homme           55          95000
##  3         3 Trarza       Rural              6 Femme           38         145000
##  4         4 Nouakchott   Urbain             4 Homme           35         680000
##  5         5 Hodh Gharbi  Rural              9 Homme           48          78000
##  6         6 Assaba       Rural              7 Homme           52         165000
##  7         7 Nouakchott   Urbain             3 Femme           31         380000
##  8         8 Tagant       Rural             10 Homme           58         110000
##  9         9 Inchiri      Rural              5 Homme           45         152000
## 10        10 Nouakchott   Urbain             4 Homme           29         495000
## # ℹ 9 more variables: jours_cereales <dbl>, jours_legumineuses <dbl>,
## #   jours_laitiers <dbl>, jours_viande <dbl>, jours_legumes_vitA <dbl>,
## #   jours_autres_legumes <dbl>, jours_oeufs <dbl>, jours_sucre_huile <dbl>,
## #   nb_groupes_hdds <dbl>
# Dimensions (lignes, colonnes)
dim(df)
## [1] 205  16
# Structure : types de variables (numérique, caractère, etc.)
str(df)
## spc_tbl_ [205 × 16] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ id_menage           : num [1:205] 1 2 3 4 5 6 7 8 9 10 ...
##  $ region              : chr [1:205] "Nouakchott" "Hodh Charghi" "Trarza" "Nouakchott" ...
##  $ milieu              : chr [1:205] "Urbain" "Rural" "Rural" "Urbain" ...
##  $ taille_menage       : num [1:205] 5 8 6 4 9 7 3 10 5 4 ...
##  $ sexe_chef           : chr [1:205] "Homme" "Homme" "Femme" "Homme" ...
##  $ age_chef            : num [1:205] 42 55 38 35 48 52 31 58 45 29 ...
##  $ revenu_mensuel      : num [1:205] 520000 95000 145000 680000 78000 165000 380000 110000 152000 495000 ...
##  $ jours_cereales      : num [1:205] 7 6 7 7 5 7 7 6 6 7 ...
##  $ jours_legumineuses  : num [1:205] 4 2 3 5 1 3 4 2 3 5 ...
##  $ jours_laitiers      : num [1:205] 5 1 2 6 0 3 4 1 4 5 ...
##  $ jours_viande        : num [1:205] 3 1 2 5 0 2 3 1 2 4 ...
##  $ jours_legumes_vitA  : num [1:205] 4 2 3 5 1 3 4 2 2 5 ...
##  $ jours_autres_legumes: num [1:205] 6 3 4 7 2 5 5 3 4 6 ...
##  $ jours_oeufs         : num [1:205] 2 0 1 3 0 1 2 0 1 3 ...
##  $ jours_sucre_huile   : num [1:205] 6 4 5 7 3 5 6 4 5 7 ...
##  $ nb_groupes_hdds     : num [1:205] 7 3 5 9 2 6 7 3 5 8 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   id_menage = col_double(),
##   ..   region = col_character(),
##   ..   milieu = col_character(),
##   ..   taille_menage = col_double(),
##   ..   sexe_chef = col_character(),
##   ..   age_chef = col_double(),
##   ..   revenu_mensuel = col_double(),
##   ..   jours_cereales = col_double(),
##   ..   jours_legumineuses = col_double(),
##   ..   jours_laitiers = col_double(),
##   ..   jours_viande = col_double(),
##   ..   jours_legumes_vitA = col_double(),
##   ..   jours_autres_legumes = col_double(),
##   ..   jours_oeufs = col_double(),
##   ..   jours_sucre_huile = col_double(),
##   ..   nb_groupes_hdds = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>
# 2) Valeurs manquantes
sum(is.na(df))
## [1] 0
colSums(is.na(df))
##            id_menage               region               milieu 
##                    0                    0                    0 
##        taille_menage            sexe_chef             age_chef 
##                    0                    0                    0 
##       revenu_mensuel       jours_cereales   jours_legumineuses 
##                    0                    0                    0 
##       jours_laitiers         jours_viande   jours_legumes_vitA 
##                    0                    0                    0 
## jours_autres_legumes          jours_oeufs    jours_sucre_huile 
##                    0                    0                    0 
##      nb_groupes_hdds 
##                    0
stats_base <- df %>%
  summarise(
    n = n(),

    # Revenu mensuel
    revenu_moy = mean(revenu_mensuel),
    revenu_med = median(revenu_mensuel),
    revenu_sd  = sd(revenu_mensuel),
    revenu_min = min(revenu_mensuel),
    revenu_q1  = as.numeric(quantile(revenu_mensuel, 0.25)),
    revenu_q3  = as.numeric(quantile(revenu_mensuel, 0.75)),
    revenu_max = max(revenu_mensuel),
    
    
   # Taille du ménage
    taille_moy = mean(taille_menage),
    taille_med = median(taille_menage),
    taille_sd  = sd(taille_menage),
    taille_min = min(taille_menage),
    taille_q1  = as.numeric(quantile(taille_menage, 0.25)),
    taille_q3  = as.numeric(quantile(taille_menage, 0.75)),
    taille_max = max(taille_menage)
  )

stats_base
## # A tibble: 1 × 15
##       n revenu_moy revenu_med revenu_sd revenu_min revenu_q1 revenu_q3
##   <int>      <dbl>      <dbl>     <dbl>      <dbl>     <dbl>     <dbl>
## 1   205    254156.     155000   184829.      68000    112000    450000
## # ℹ 8 more variables: revenu_max <dbl>, taille_moy <dbl>, taille_med <dbl>,
## #   taille_sd <dbl>, taille_min <dbl>, taille_q1 <dbl>, taille_q3 <dbl>,
## #   taille_max <dbl>
seuil_usd_ppp <- 2.15
ppa_mru_par_usd <- 600

seuil_mru_jour <- seuil_usd_ppp * ppa_mru_par_usd
seuil_mru_jour
## [1] 1290
df_odd1 <- df %>%
mutate(
# Urbain = Nouakchott uniquement (selon ta consigne)
milieu_def = ifelse(region == "Nouakchott",
"Urbain (Nouakchott)",
"Rural (Autres régions)"),


# Revenu par tête et pauvreté
revenu_par_tete = revenu_mensuel / taille_menage,
revenu_par_tete_jour_mru = revenu_par_tete / 30,
revenu_par_tete_jour_usd_ppp = revenu_par_tete_jour_mru / ppa_mru_par_usd,
menage_pauvre = ifelse(revenu_par_tete_jour_usd_ppp < seuil_usd_ppp, 1, 0)


)

head(df_odd1, 5)
## # A tibble: 5 × 21
##   id_menage region       milieu taille_menage sexe_chef age_chef revenu_mensuel
##       <dbl> <chr>        <chr>          <dbl> <chr>        <dbl>          <dbl>
## 1         1 Nouakchott   Urbain             5 Homme           42         520000
## 2         2 Hodh Charghi Rural              8 Homme           55          95000
## 3         3 Trarza       Rural              6 Femme           38         145000
## 4         4 Nouakchott   Urbain             4 Homme           35         680000
## 5         5 Hodh Gharbi  Rural              9 Homme           48          78000
## # ℹ 14 more variables: jours_cereales <dbl>, jours_legumineuses <dbl>,
## #   jours_laitiers <dbl>, jours_viande <dbl>, jours_legumes_vitA <dbl>,
## #   jours_autres_legumes <dbl>, jours_oeufs <dbl>, jours_sucre_huile <dbl>,
## #   nb_groupes_hdds <dbl>, milieu_def <chr>, revenu_par_tete <dbl>,
## #   revenu_par_tete_jour_mru <dbl>, revenu_par_tete_jour_usd_ppp <dbl>,
## #   menage_pauvre <dbl>
tab_milieu_def <- df_odd1 %>%
  group_by(milieu_def) %>%
  summarise(
    menages_total = n(),
    menages_pauvres = sum(menage_pauvre),
    taux_pauvrete = menages_pauvres / menages_total,
    taux_pauvrete_pct = paste0(round(100 * taux_pauvrete, 2), "%"),
    .groups = "drop"
  ) %>%
  arrange(desc(taux_pauvrete))

tab_milieu_def
## # A tibble: 2 × 5
##   milieu_def       menages_total menages_pauvres taux_pauvrete taux_pauvrete_pct
##   <chr>                    <int>           <dbl>         <dbl> <chr>            
## 1 Rural (Autres r…           143             128         0.895 89.51%           
## 2 Urbain (Nouakch…            62               0         0     0%
tab_milieu_def_pop <- df_odd1 %>%
  group_by(milieu_def) %>%
  summarise(
    pop_total = sum(taille_menage),
    pop_pauvre = sum(menage_pauvre * taille_menage),
    taux_pauvrete_population = pop_pauvre / pop_total,
    taux_pauvrete_population_pct = paste0(round(100 * taux_pauvrete_population, 2), "%"),
    .groups = "drop"
  ) %>%
  arrange(desc(taux_pauvrete_population))

tab_milieu_def_pop
## # A tibble: 2 × 5
##   milieu_def  pop_total pop_pauvre taux_pauvrete_popula…¹ taux_pauvrete_popula…²
##   <chr>           <dbl>      <dbl>                  <dbl> <chr>                 
## 1 Rural (Aut…      1160       1085                  0.935 93.53%                
## 2 Urbain (No…       261          0                  0     0%                    
## # ℹ abbreviated names: ¹​taux_pauvrete_population, ²​taux_pauvrete_population_pct
tab_region <- df_odd1 %>%
  group_by(region) %>%
  summarise(
    menages_total = n(),
    menages_pauvres = sum(menage_pauvre),
    taux_pauvrete = menages_pauvres / menages_total,
    taux_pauvrete_pct = paste0(round(100 * taux_pauvrete, 2), "%"),
    .groups = "drop"
  ) %>%
  arrange(desc(taux_pauvrete))

tab_region
## # A tibble: 7 × 5
##   region       menages_total menages_pauvres taux_pauvrete taux_pauvrete_pct
##   <chr>                <int>           <dbl>         <dbl> <chr>            
## 1 Assaba                  30              30           1   100%             
## 2 Hodh Charghi            21              21           1   100%             
## 3 Hodh Gharbi             21              21           1   100%             
## 4 Inchiri                 20              20           1   100%             
## 5 Tagant                  21              21           1   100%             
## 6 Trarza                  30              15           0.5 50%              
## 7 Nouakchott              62               0           0   0%
ordre_regions <- tab_region %>% arrange(desc(taux_pauvrete)) %>% pull(region)

tab_region_plot <- df_odd1 %>%
  group_by(region, milieu_def) %>%
  summarise(
    taux_pauvrete = mean(menage_pauvre),
    .groups = "drop"
  ) %>%
  mutate(region = factor(region, levels = ordre_regions))

ggplot(tab_region_plot, aes(x = region, y = taux_pauvrete, fill = milieu_def)) +
  geom_col() +
  scale_y_continuous(labels = function(x) paste0(round(100*x, 0), "%")) +
  labs(
    title = "Disparités géographiques de la pauvreté (ODD 1)",
    subtitle = "Taux de pauvreté par région (Urbain = Nouakchott uniquement)",
    x = "Région",
    y = "Taux de pauvreté",
    fill = "Milieu (définition)"
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Méthode du cours : FCS = somme(jours_i * poids_i)
# Poids standardisés (PAM) : céréales=2, légumineuses=3, laitiers=4, viande/poisson=4,
# VitA=1, autres légumes=1, oeufs=1, sucre/huile=0.5
calc_fcs <- function(j_cereales, j_legumineuses, j_laitiers, j_viande,
                     j_vitA, j_autres_legumes, j_oeufs, j_sucre_huile) {
  (j_cereales * 2) +
    (j_legumineuses * 3) +
    (j_laitiers * 4) +
    (j_viande * 4) +
    (j_vitA * 1) +
    (j_autres_legumes * 1) +
    (j_oeufs * 1) +
    (j_sucre_huile * 0.5)
}
# 2) Ajouter FCS + classer FCS
# -----------------------------
df_fcs <- df %>%
  mutate(
    fcs = calc_fcs(
      jours_cereales,
      jours_legumineuses,
      jours_laitiers,
      jours_viande,
      jours_legumes_vitA,
      jours_autres_legumes,
      jours_oeufs,
      jours_sucre_huile
    ),
    categorie_fcs = case_when(
      fcs <= 21 ~ "Pauvre",
      fcs <= 35 ~ "Limite",
      TRUE      ~ "Acceptable"
    )
  )
head(df_fcs %>% select(fcs, categorie_fcs), 10)
## # A tibble: 10 × 2
##      fcs categorie_fcs
##    <dbl> <chr>        
##  1  73   Acceptable   
##  2  33   Limite       
##  3  49.5 Acceptable   
##  4  91.5 Acceptable   
##  5  17.5 Pauvre       
##  6  54.5 Acceptable   
##  7  68   Acceptable   
##  8  33   Limite       
##  9  54.5 Acceptable   
## 10  82.5 Acceptable
# Tableau clair : effectifs + proportions
tab_fcs <- df_fcs %>%
  group_by(categorie_fcs) %>%
  summarise(n = n(), .groups = "drop") %>%
  mutate(
    proportion = n / sum(n),
    proportion_pct = paste0(round(100 * proportion, 2), "%")
  ) %>%
  arrange(desc(proportion))

tab_fcs
## # A tibble: 3 × 4
##   categorie_fcs     n proportion proportion_pct
##   <chr>         <int>      <dbl> <chr>         
## 1 Acceptable      161      0.785 78.54%        
## 2 Limite           22      0.107 10.73%        
## 3 Pauvre           22      0.107 10.73%
# Indicateur 2.1.1 : % ménages avec un FCS acceptable
pct_acceptable <- df_fcs %>%
  summarise(
    pct_fcs_acceptable = mean(categorie_fcs == "Acceptable") * 100
  )

pct_acceptable
## # A tibble: 1 × 1
##   pct_fcs_acceptable
##                <dbl>
## 1               78.5
objectif_2030 <- 80

decision <- df_fcs %>%
  summarise(
    pct_fcs_acceptable = mean(categorie_fcs == "Acceptable") * 100,
    objectif_2030 = objectif_2030,
    atteint = ifelse(pct_fcs_acceptable >= objectif_2030, "Oui", "Non")
  )

decision
## # A tibble: 1 × 3
##   pct_fcs_acceptable objectif_2030 atteint
##                <dbl>         <dbl> <chr>  
## 1               78.5            80 Non
ggplot(df_fcs, aes(x = categorie_fcs)) +
  geom_bar() +
  labs(
    title = "ODD 2 — Répartition des ménages selon le FCS",
    x = "Catégorie FCS",
    y = "Nombre de ménages"
  ) +
  theme_minimal()

df_hdds <- df %>%
  mutate(
    hdds = nb_groupes_hdds,
    classe_hdds = case_when(
      hdds <= 3 ~ "Faible (0-3)",
      hdds <= 5 ~ "Modéré (4-5)",
      TRUE      ~ "Élevé (6+)"
    )
  )
tab_hdds <- df_hdds %>%
  group_by(classe_hdds) %>%
  summarise(n = n(), .groups = "drop") %>%
  mutate(proportion = n / sum(n))

tab_hdds
## # A tibble: 3 × 3
##   classe_hdds      n proportion
##   <chr>        <int>      <dbl>
## 1 Faible (0-3)    44      0.215
## 2 Modéré (4-5)    52      0.254
## 3 Élevé (6+)     109      0.532
ggplot(df_hdds, aes(x = hdds)) +
  geom_histogram(binwidth = 1) +
  labs(title = "Distribution de l'HDDS (nb_groupes_hdds)",
       x = "HDDS (nombre de groupes)", y = "Effectif") +
  theme_minimal()

ggplot(tab_hdds, aes(x = classe_hdds, y = proportion)) +
  geom_col() +
  scale_y_continuous(labels = function(x) paste0(round(100*x, 0), "%")) +
  labs(title = "Répartition des ménages par niveau de diversité alimentaire (HDDS)",
       x = "Classe HDDS", y = "Proportion") +
  theme_minimal()

df_all <- df %>%
mutate(
milieu_def = ifelse(region == "Nouakchott",
"Urbain (Nouakchott)",
"Rural (Autres régions)"),


# ODD1 : pauvreté
revenu_par_tete = revenu_mensuel / taille_menage,
revenu_par_tete_jour_mru = revenu_par_tete / 30,
revenu_par_tete_jour_usd_ppp = revenu_par_tete_jour_mru / ppa_mru_par_usd,
menage_pauvre = ifelse(revenu_par_tete_jour_usd_ppp < seuil_usd_ppp, 1, 0),

# ODD2 : FCS
fcs = calc_fcs(
  jours_cereales,
  jours_legumineuses,
  jours_laitiers,
  jours_viande,
  jours_legumes_vitA,
  jours_autres_legumes,
  jours_oeufs,
  jours_sucre_huile
)


)

head(df_all %>% select(region, milieu_def, menage_pauvre, fcs), 10)
## # A tibble: 10 × 4
##    region       milieu_def             menage_pauvre   fcs
##    <chr>        <chr>                          <dbl> <dbl>
##  1 Nouakchott   Urbain (Nouakchott)                0  73  
##  2 Hodh Charghi Rural (Autres régions)             1  33  
##  3 Trarza       Rural (Autres régions)             1  49.5
##  4 Nouakchott   Urbain (Nouakchott)                0  91.5
##  5 Hodh Gharbi  Rural (Autres régions)             1  17.5
##  6 Assaba       Rural (Autres régions)             1  54.5
##  7 Nouakchott   Urbain (Nouakchott)                0  68  
##  8 Tagant       Rural (Autres régions)             1  33  
##  9 Inchiri      Rural (Autres régions)             1  54.5
## 10 Nouakchott   Urbain (Nouakchott)                0  82.5
# Corrélation globale (pauvre = 0/1) et FCS

cor_global <- cor(df_all$menage_pauvre, df_all$fcs)
cor_global
## [1] -0.8674232
# Corrélation par milieu

cor_par_milieu <- df_all %>%
group_by(milieu_def) %>%
summarise(correlation = cor(menage_pauvre, fcs), n = n(), .groups = "drop")
## Warning: There was 1 warning in `summarise()`.
## ℹ In argument: `correlation = cor(menage_pauvre, fcs)`.
## ℹ In group 2: `milieu_def = "Urbain (Nouakchott)"`.
## Caused by warning in `cor()`:
## ! l'écart type est nul
cor_par_milieu
## # A tibble: 2 × 3
##   milieu_def             correlation     n
##   <chr>                        <dbl> <int>
## 1 Rural (Autres régions)      -0.573   143
## 2 Urbain (Nouakchott)         NA        62
# Boxplot du FCS selon pauvreté et milieu

ggplot(df_all, aes(x = as.factor(menage_pauvre), y = fcs, fill = milieu_def)) +
geom_boxplot(position = "dodge") +
labs(
title = "Relation entre pauvreté monétaire (ODD1) et sécurité alimentaire (FCS)",
subtitle = "Comparaison Urbain (Nouakchott) vs Rural (autres régions)",
x = "Ménage pauvre (0=Non, 1=Oui)",
y = "FCS",
fill = "Milieu"
) +
theme_minimal()

tab_fcs_pauvre_milieu <- df_all %>%
group_by(milieu_def, menage_pauvre) %>%
summarise(
n = n(),
fcs_moy = mean(fcs),
fcs_med = median(fcs),
fcs_min = min(fcs),
fcs_max = max(fcs),
.groups = "drop"
) %>%
arrange(milieu_def, menage_pauvre)

tab_fcs_pauvre_milieu
## # A tibble: 3 × 7
##   milieu_def             menage_pauvre     n fcs_moy fcs_med fcs_min fcs_max
##   <chr>                          <dbl> <int>   <dbl>   <dbl>   <dbl>   <dbl>
## 1 Rural (Autres régions)             0    15    68      68      68      68  
## 2 Rural (Autres régions)             1   128    40.0    37      17.5    54.5
## 3 Urbain (Nouakchott)                0    62    84.7    82.5    68      91.5
# Séparer FCS par milieu

fcs_urbain <- df_all %>% filter(milieu_def == "Urbain (Nouakchott)") %>% pull(fcs)
fcs_rural  <- df_all %>% filter(milieu_def == "Rural (Autres régions)") %>% pull(fcs)

# t-test (indicatif)

t.test(fcs_urbain, fcs_rural)
## 
##  Welch Two Sample t-test
## 
## data:  fcs_urbain and fcs_rural
## t = 28.319, df = 202.32, p-value < 2.2e-16
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  38.84038 44.65375
## sample estimates:
## mean of x mean of y 
##  84.70161  42.95455
# Wilcoxon (robuste)

wilcox.test(fcs_urbain, fcs_rural)
## 
##  Wilcoxon rank sum test with continuity correction
## 
## data:  fcs_urbain and fcs_rural
## W = 8858.5, p-value < 2.2e-16
## alternative hypothesis: true location shift is not equal to 0
fcs_pauvres   <- df_all %>% filter(menage_pauvre == 1) %>% pull(fcs)
fcs_nonpauves <- df_all %>% filter(menage_pauvre == 0) %>% pull(fcs)

t.test(fcs_pauvres, fcs_nonpauves)
## 
##  Welch Two Sample t-test
## 
## data:  fcs_pauvres and fcs_nonpauves
## t = -27.408, df = 201.19, p-value < 2.2e-16
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -44.40908 -38.44796
## sample estimates:
## mean of x mean of y 
##  40.01953  81.44805
wilcox.test(fcs_pauvres, fcs_nonpauves)
## 
##  Wilcoxon rank sum test with continuity correction
## 
## data:  fcs_pauvres and fcs_nonpauves
## W = 0, p-value < 2.2e-16
## alternative hypothesis: true location shift is not equal to 0
taux_pauvrete_population <- function(data) {
sum(data$menage_pauvre * data$taille_menage) / sum(data$taille_menage)
}
ui <- fluidPage(
titlePanel("ODD 17 — Dashboard : Pauvreté (ODD 1) & Sécurité alimentaire (ODD 2)"),

sidebarLayout(
sidebarPanel(
selectInput(
inputId = "grp",
label = "Choisir le sous-groupe :",
choices = c(
"Global" = "global",
"Milieu (Nouakchott vs reste)" = "milieu_def",
"Région" = "region",
"Sexe du chef" = "sexe_chef"
)
),
hr(),
h4("Indicateurs clés"),
verbatimTextOutput("kpi")
),

mainPanel(
  tabsetPanel(
    tabPanel("Pauvreté",
             tableOutput("tab_pov"),
             plotOutput("plot_pov")),
    tabPanel("FCS",
             tableOutput("tab_fcs"),
             plotOutput("plot_fcs")),
    tabPanel("Relation pauvreté – FCS",
             tableOutput("tab_rel"),
             plotOutput("plot_rel"))
  )
)

)
)
library(dplyr)
library(ggplot2)
library(shiny)

# Paramètres ODD1 (seuil international)

seuil_usd_ppp <- 2.15
ppa_mru_par_usd <- 600

# Fonction FCS (poids WFP/PAM)

calc_fcs <- function(j_cereales, j_legumineuses, j_laitiers, j_viande,
j_vitA, j_autres_legumes, j_oeufs, j_sucre_huile) {
(j_cereales * 2) +
(j_legumineuses * 3) +
(j_laitiers * 4) +
(j_viande * 4) +
(j_vitA * 1) +
(j_autres_legumes * 1) +
(j_oeufs * 1) +
(j_sucre_huile * 0.5)
}

# Table intégrée : pauvreté + FCS + sous-groupes

df_all <- df %>%
mutate(
# Ta règle : Urbain = Nouakchott uniquement
milieu_def = ifelse(region == "Nouakchott", "Urbain (Nouakchott)", "Rural (Autres régions)"),


# Pauvreté monétaire (ODD1)
revenu_par_tete = revenu_mensuel / taille_menage,
revenu_par_tete_jour_usd_ppp = (revenu_par_tete / 30) / ppa_mru_par_usd,
menage_pauvre = ifelse(revenu_par_tete_jour_usd_ppp < seuil_usd_ppp, 1, 0),

# Sécurité alimentaire (ODD2)
fcs = calc_fcs(
  jours_cereales,
  jours_legumineuses,
  jours_laitiers,
  jours_viande,
  jours_legumes_vitA,
  jours_autres_legumes,
  jours_oeufs,
  jours_sucre_huile
),
categorie_fcs = case_when(
  fcs <= 21 ~ "Pauvre",
  fcs <= 35 ~ "Limite",
  TRUE ~ "Acceptable"
),

# Variables catégorielles utiles
sexe_chef = as.factor(sexe_chef)


)

# Indicateur pauvreté "population" : pop pauvre / pop totale

taux_pauvrete_population <- function(data) {
sum(data$menage_pauvre * data$taille_menage) / sum(data$taille_menage)
}
library(dplyr)
library(ggplot2)
library(shiny)

ui <- fluidPage(
titlePanel("ODD 17 — Dashboard : Pauvreté (ODD1) & Sécurité alimentaire (ODD2)"),

sidebarLayout(
sidebarPanel(
selectInput(
"grp", "Sous-groupe :",
choices = c(
"Global" = "global",
"Milieu (Nouakchott vs reste)" = "milieu_def",
"Région" = "region",
"Sexe du chef" = "sexe_chef"
)
),
hr(),
h4("Indicateurs clés"),
verbatimTextOutput("kpi")
),


mainPanel(
  tabsetPanel(
    tabPanel("Pauvreté",
             tableOutput("tab_pov"),
             plotOutput("plot_pov")),
    tabPanel("FCS",
             tableOutput("tab_fcs"),
             plotOutput("plot_fcs")),
    tabPanel("Relation pauvreté–FCS",
             tableOutput("tab_rel"),
             plotOutput("plot_rel"))
  )
)


)
)

server <- function(input, output, session) {

output$kpi <- renderText({
tp <- taux_pauvrete_population(df_all)
pct_acc <- mean(df_all$categorie_fcs == "Acceptable") * 100
paste0(
"Taux de pauvreté (population) = ", round(100 * tp, 2), "%\n",
"% FCS acceptable = ", round(pct_acc, 2), "%\n",
"N ménages = ", nrow(df_all), " | Population = ", sum(df_all$taille_menage)
)
})

# ---- Pauvreté : tableau

output$tab_pov <- renderTable({
if (input$grp == "global") {
data.frame(
pop_total = sum(df_all$taille_menage),
pop_pauvre = sum(df_all$menage_pauvre * df_all$taille_menage),
taux_pauvrete_population = round(taux_pauvrete_population(df_all), 4)
)
} else {
df_all %>%
group_by(.data[[input$grp]]) %>%
summarise(
pop_total = sum(taille_menage),
pop_pauvre = sum(menage_pauvre * taille_menage),
taux = pop_pauvre / pop_total,
.groups = "drop"
) %>%
arrange(desc(taux))
}
})

# ---- Pauvreté : graphique

output$plot_pov <- renderPlot({
if (input$grp == "global") {
tmp <- data.frame(
statut = c("Non pauvre", "Pauvre"),
population = c(
sum((1 - df_all$menage_pauvre) * df_all$taille_menage),
sum(df_all$menage_pauvre * df_all$taille_menage)
)
)
ggplot(tmp, aes(x = statut, y = population)) +
geom_col() +
labs(title = "Population pauvre vs non pauvre (global)", x = "", y = "Population") +
theme_minimal()
} else {
tmp <- df_all %>%
group_by(.data[[input$grp]]) %>%
summarise(taux = taux_pauvrete_population(cur_data()), .groups = "drop")
ggplot(tmp, aes(x = .data[[input$grp]], y = taux)) +
geom_col() +
scale_y_continuous(labels = function(x) paste0(round(100 * x, 0), "%")) +
labs(title = "Taux de pauvreté (population) par sous-groupe", x = "", y = "Taux") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
}
})

# ---- FCS : tableau

output$tab_fcs <- renderTable({
df_all %>%
count(categorie_fcs) %>%
mutate(pct = round(100 * n / sum(n), 2)) %>%
arrange(desc(n))
})

# ---- FCS : graphique

output$plot_fcs <- renderPlot({
tmp <- df_all %>%
count(categorie_fcs) %>%
mutate(pct = n / sum(n))
ggplot(tmp, aes(x = categorie_fcs, y = pct)) +
geom_col() +
scale_y_continuous(labels = function(x) paste0(round(100 * x, 0), "%")) +
labs(title = "Distribution des catégories FCS", x = "Catégorie", y = "Proportion") +
theme_minimal()
})

# ---- Relation pauvreté–FCS : tableau

output$tab_rel <- renderTable({
df_all %>%
group_by(milieu_def, menage_pauvre) %>%
summarise(
n = n(),
fcs_moy = round(mean(fcs), 2),
fcs_med = round(median(fcs), 2),
.groups = "drop"
) %>%
arrange(milieu_def, menage_pauvre)
})

# ---- Relation pauvreté–FCS : graphique

output$plot_rel <- renderPlot({
ggplot(df_all, aes(x = as.factor(menage_pauvre), y = fcs, fill = milieu_def)) +
geom_boxplot(position = "dodge") +
labs(
title = "FCS selon la pauvreté (0/1) et le milieu",
x = "Ménage pauvre (0=Non, 1=Oui)",
y = "FCS",
fill = "Milieu"
) +
theme_minimal()
})

}

shinyApp(ui, server)
Shiny applications not supported in static R Markdown documents
library(dplyr)

# Modèle : expliquer FCS par facteurs socio-économiques

modele_fcs <- lm(
fcs ~ revenu_par_tete + taille_menage + milieu_def + age_chef + sexe_chef,
data = df_all
)

summary(modele_fcs)
## 
## Call:
## lm(formula = fcs ~ revenu_par_tete + taille_menage + milieu_def + 
##     age_chef + sexe_chef, data = df_all)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -21.9241  -5.2857  -0.9032   5.7569  22.0934 
## 
## Coefficients:
##                                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                    9.125e+01  9.835e+00   9.279  < 2e-16 ***
## revenu_par_tete               -1.776e-06  4.847e-05  -0.037 0.970805    
## taille_menage                 -5.301e+00  1.352e+00  -3.921 0.000121 ***
## milieu_defUrbain (Nouakchott)  1.862e+01  4.249e+00   4.381 1.91e-05 ***
## age_chef                      -1.894e-01  3.796e-01  -0.499 0.618410    
## sexe_chefHomme                 4.984e+00  1.685e+00   2.958 0.003473 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 7.61 on 199 degrees of freedom
## Multiple R-squared:  0.8949, Adjusted R-squared:  0.8923 
## F-statistic: 338.9 on 5 and 199 DF,  p-value: < 2.2e-16
# Qualité du modèle : R², R² ajusté, RMSE

rmse <- sqrt(mean(residuals(modele_fcs)^2))
data.frame(
R2 = summary(modele_fcs)$r.squared,
R2_adj = summary(modele_fcs)$adj.r.squared,
RMSE = rmse
)
##          R2    R2_adj     RMSE
## 1 0.8949027 0.8922621 7.498262