Leçon 3 sur 8
Unité · Qui est un cas
Les définitions de cas, et la clause que tout le monde oublie
Malnutrition aiguë sévère, modérée et globale, les seuils dont le secteur a convenu, et la clause des œdèmes qui rend fausse toute implémentation en « décompte sous le seuil ».
Les définitions
Trois termes, et ils s’emboîtent.
| Terme | Score z poids-taille | PB | Œdèmes |
|---|---|---|---|
| MAS — malnutrition aiguë sévère | sous -3 | sous 115 mm | présents |
| MAM — malnutrition aiguë modérée | -3 à moins de -2 | 115 à moins de 125 mm | — |
| MAG — malnutrition aiguë globale | sous -2 | sous 125 mm | présents |
La MAG est la MAS plus la MAM. Ce n’est pas une affection distincte, c’est la charge totale de malnutrition aiguë, et c’est le chiffre auquel se réfèrent les phases IPC et le seuil d’urgence de 15 %.
Deux points structurels avant tout code.
Chaque ligne est à elle seule une définition complète. Un enfant est en MAS par le poids-pour-taille, ou par le PB, ou par les œdèmes — les critères sont des alternatives, non des exigences cumulatives. La leçon 4 porte entièrement sur l’ampleur du désaccord entre les deux premiers.
La colonne des œdèmes est un OU, non un ET. Un enfant présentant des œdèmes bilatéraux prenant le godet est sévère quoi que disent ses mesures. Cette clause est un terme d’une expression booléenne, et c’est le terme le plus souvent omis.
L’implémentation fausse
# WRONG: the definition everybody writes first
sam_wrong = (smart["whz"] < -3).sum()
# WRONG
sum(smart$whz < -3, na.rm = TRUE)
Elle est fausse de deux façons à la fois. Elle écarte les enfants œdémateux, et le
na.rm ou une comparaison propageant les valeurs nulles écarte silencieusement les
enfants sans score z — si bien que le numérateur et le dénominateur diffèrent tous
deux de ce que le libellé prétend.
L’implémentation juste
import pandas as pd
analysable = smart[smart["whz"].between(-5, 5)].copy()
oedema = analysable["oedema"] == True
analysable["sam"] = (analysable["whz"] < -3) | oedema
analysable["mam"] = (analysable["whz"].between(-3, -2, inclusive="left")) & ~oedema
analysable["gam"] = analysable["sam"] | analysable["mam"]
n = len(analysable)
for label in ["sam", "mam", "gam"]:
print(f"{label.upper():4} {analysable[label].sum():>4} / {n} "
f"{analysable[label].mean():.1%}")
analysable <- smart |> filter(between(whz, -5, 5))
analysable <- analysable |>
mutate(sam = whz < -3 | oedema,
mam = whz >= -3 & whz < -2 & !oedema,
gam = sam | mam)
analysable |> summarise(across(c(sam, mam, gam), list(n = sum, rate = mean)), n = n())
852 enfants analysables : MAG 14,9 %, MAS 3,8 %.
Trois détails de ce code portent le résultat.
La MAM exclut explicitement les œdèmes. Un enfant œdémateux dont le score z
tombe dans la bande modérée est sévère et non modéré, et sans le & ~oedema il
serait compté dans les deux — si bien que MAS plus MAM dépasserait la MAG.
Les bornes sont semi-ouvertes. -3 <= z < -2. Un enfant exactement à -3,0 est
sévère. Se tromper ici déplace une poignée d’enfants et c’est le genre de point sur
lequel deux analystes découvrent leur désaccord au pire moment.
Le dénominateur est énoncé. 852, non 930 — la différence est faite des enfants sans score z calculable et de ceux hors des bornes de signalement, et la leçon 2 exigeait de rapporter ces trois groupes séparément.
Vérifiez que les parties totalisent le tout
assert (analysable["sam"] & analysable["mam"]).sum() == 0, "a child is both"
assert analysable["gam"].sum() == analysable["sam"].sum() + analysable["mam"].sum()
stopifnot(sum(analysable$sam & analysable$mam) == 0,
sum(analysable$gam) == sum(analysable$sam) + sum(analysable$mam))
Deux assertions, et elles attrapent l’erreur des œdèmes, celle des bornes et toute modification future qui casserait l’emboîtement. Exécutez-les à chaque fois.
Les définitions par le PB, sur le registre
Le registre de dépistage a le PB et les œdèmes, sans poids ni taille, si bien qu’il ne soutient que les définitions fondées sur le PB.
muac = pd.read_csv("muac-screening-artibonite-2024.v1.csv")
measured = muac[muac["muac_mm"].notna()].copy()
oed = measured["oedema"] == True
measured["sam"] = (measured["muac_mm"] < 115) | oed
measured["gam"] = (measured["muac_mm"] < 125) | oed
print(f"n = {len(measured):,} GAM {measured['gam'].mean():.1%} "
f"SAM {measured['sam'].mean():.1%}")
muac |>
filter(!is.na(muac_mm)) |>
summarise(n = n(),
gam = mean(muac_mm < 125 | oedema),
sam = mean(muac_mm < 115 | oedema))
Nommez la mesure dans l’indicateur. gam_muac_percent et gam_whz_percent
sont deux indicateurs différents que l’on appelle tous deux « MAG », et la règle du
cours sur la conception d’indicateurs consistant à mettre la mesure dans le nom
n’est pas ici du pédantisme — la leçon suivante montre les deux en désaccord sur
les trois quarts des cas sévères.
Ce qu’une définition ne dit pas
Trois choses que la définition de cas laisse délibérément de côté, et que quelqu’un supposera.
L’âge. Les définitions s’appliquent aux enfants de 6 à 59 mois. En dessous de six mois, les normes et les définitions diffèrent ; au-dessus de 59 mois, elles ne s’appliquent pas. Vérifiez la plage d’âge avant de classer.
out_of_scope = ~analysable["age_months"].between(6, 59)
print(f"{out_of_scope.sum()} children outside 6-59 months")
sum(!between(analysable$age_months, 6, 59), na.rm = TRUE)
L’admission. Une définition de cas dit qui est malnutri. Savoir s’il est
admis dépend du protocole du programme, qui peut employer un critère, les deux, ou
le PB pour le dépistage communautaire et le poids-pour-taille au site. Le champ
admission_criterion du registre enregistre ce que le site a saisi, non tout ce
que l’enfant remplissait.
La gravité à l’intérieur du sévère. Une MAS avec complications exige des soins hospitaliers ; sans complications, ambulatoires. La définition ne les distingue pas, et le test de l’appétit et les signes cliniques qui le font ne figurent pas dans un jeu de données anthropométrique.
Une définition de cas est une règle de classification, non une décision thérapeutique. Confondre les deux produit une charge de cas qui ne correspond aux admissions d’aucun programme et une discussion que les données ne peuvent pas trancher.
La suite
Vous savez classer un enfant par l’une ou l’autre mesure. La leçon suivante place les deux mesures sur les mêmes enfants et constate qu’elles divergent sur les trois quarts des cas sévères — et que ce désaccord a une cause qui tient en un nombre.