cassionAnalyse de données

Leçon 2 sur 8

Unité · Mesurer un enfant

Du poids et de la taille au score z

La méthode LMS, la recherche dans la table de référence, les trois scores z et ce que chacun mesure. Calculé sur 930 enfants, il donne une moyenne de -0,67 et un écart-type de 1,22 — et ce second nombre est déjà un constat.

PythonR150 minNormes OMS de croissance de l'enfantEnquête SMART

Ce que dit un score z

Un score z répond à une seule question — à quelle distance cet enfant est-il de la médiane d’une population de référence en bonne santé, en écarts-types ?

Un score z poids-pour-taille de -2 signifie que cet enfant pèse ce que pèse un enfant situé à deux écarts-types sous la médiane, pour sa taille. Ce n’est un pourcentage de rien, et ce n’est pas comparable à un percentile sans conversion.

La référence est constituée par les normes OMS 2006 de croissance de l’enfant, bâties sur une étude multi-pays d’enfants élevés dans des conditions ne limitant pas la croissance — allaités, foyers non-fumeurs, soins adéquats. Cette construction est délibérée : les normes décrivent comment les enfants devraient grandir, non comment les enfants d’un lieu donné grandissent.

Trois scores z, trois questions

Score Compare Déficit détecté Récupérable ?
Poids-pour-taille (WHZ) Le poids à la taille Aigu — émaciation Oui, en semaines
Taille-pour-âge (HAZ) La taille à l’âge Chronique — retard de croissance Non
Poids-pour-âge (WAZ) Le poids à l’âge Les deux à la fois — insuffisance pondérale En partie

Le poids-pour-âge est celui dont il faut se méfier. Il mélange les deux déficits, si bien qu’un WAZ bas ne dit pas si l’enfant est émacié, en retard de croissance ou les deux, et la réponse programmatique diffère. Il survit en suivi de la croissance parce qu’il n’exige pas de toise, et il ne doit pas servir à classer la malnutrition aiguë.

Ce cours calcule le poids-pour-taille, car c’est sur lui que reposent les définitions de cas et les seuils IPC.

La méthode LMS

Les normes sont publiées sous forme de trois paramètres, par sexe, par mesure et par tranche de 0,1 cm de longueur ou de taille.

  • L — la puissance de Box-Cox qui normalise une distribution asymétrique
  • M — la médiane
  • S — le coefficient de variation
z = ((weight / M)^L - 1) / (L * S)
import pandas as pd

reference = pd.read_csv("who-2006-weight-for-lenhei.csv")
print(reference.head(3))
print(f"{len(reference)} rows: sex x standard x lenhei in 0.1 cm steps")
reference <- readr::read_csv("who-2006-weight-for-lenhei.csv")
nrow(reference)

2 404 lignes. Lisez la table ; ne réimplémentez pas l’interpolation d’après un manuel. R dispose du paquet officiel anthro ; Python n’a pas d’équivalent maintenu qui s’installe proprement, et c’est exactement pourquoi cette table est livrée ici.

La clé de recherche a trois parties

C’est la partie qui dérape, et le laboratoire du cours sur les jointures était bâti dessus.

def lookup_key(row):
    lying = row["measured_lying"] == "true"
    standard = "L" if row["age_months"] < 24 else "H"

    lenhei = row["height_cm"]
    if standard == "L" and not lying:
        lenhei += 0.7
    elif standard == "H" and lying:
        lenhei -= 0.7

    return row["sex"], standard, round(lenhei, 1)
lookup_key <- function(sex, age, height, lying) {
  standard <- if (age < 24) "L" else "H"
  lenhei <- height +
    if (standard == "L" && !lying) 0.7 else if (standard == "H" && lying) -0.7 else 0
  list(sex = sex, lorh = standard, lenhei = round(lenhei, 1))
}

Trois éléments de cette fonction sont des décisions, non de la mécanique.

Le standard suit l’âge, non la position. Un enfant de 30 mois mesuré couché est malgré tout évalué selon le standard de taille, avec l’ajustement appliqué.

L’ajustement porte sur la mesure, non sur le standard. Vous convertissez la mesure en celle que le standard attend.

L’arrondi est à une décimale, des deux côtés, en un seul endroit. Un flottant issu d’un ajustement n’est pas le même flottant que celui lu dans un CSV, ce qui est la jointure sur clé inexacte à laquelle le cours sur les jointures a consacré un laboratoire.

Le calcul

reference["key"] = list(zip(reference["sex"], reference["lorh"],
                            reference["lenhei"].round(1)))
lms = reference.set_index("key")[["l", "m", "s"]]

def whz(row):
    key = lookup_key(row)
    if key not in lms.index or pd.isna(row["weight_kg"]):
        return None
    l, m, s = lms.loc[key]
    return (((row["weight_kg"] / m) ** l) - 1) / (l * s)

smart["whz"] = smart.apply(whz, axis=1)
print(f"{smart['whz'].notna().sum()} of {len(smart)} computable")
# In R, use the official package rather than the table:
# anthro::anthro_zscores(sex = ..., age = ..., weight = ..., lenhei = ..., measure = ...)

864 sur 930 calculables. Les 66 restants se répartissent en trois groupes et la distinction compte.

  • Poids ou âge manquant — 32 enfants, et ce sont des données manquantes.
  • Taille hors de la plage de référence — le standard de longueur va de 45,0 à 110,0 cm et celui de taille de 65,0 à 120,0 cm. Un enfant hors de cette plage est réellement inclassable.
  • Une mesure dans la mauvaise unité — quatre tailles enregistrées en mètres, que le laboratoire du cours sur les jointures a trouvées par anti-jointure. Celles-là sont récupérables.

Rapportez les trois séparément. « 66 enfants exclus » masque le fait que certains étaient des erreurs corrigeables.

Le signalement — deux règles, deux réponses

Les scores z extrêmes sont exclus avant toute prévalence, et il existe deux conventions.

  • Valeurs aberrantes OMS — bornes fixes, exclure les z hors de -5 à +5. Absolu, comparable entre enquêtes.
  • Valeurs aberrantes SMART — relatif, exclure les observations à plus de 3 ET de la moyenne de l’enquête elle-même. S’adapte à l’enquête, et la réduit davantage quand elle est plus bruitée.
who_flagged = smart["whz"].between(-5, 5)

mean, sd = smart["whz"].mean(), smart["whz"].std()
smart_flagged = smart["whz"].between(mean - 3 * sd, mean + 3 * sd)

print(f"WHO flags keep {who_flagged.sum()}, SMART flags keep {smart_flagged.sum()}")
smart <- smart |>
  mutate(who_ok = between(whz, -5, 5),
         smart_ok = between(whz, mean(whz, na.rm = TRUE) - 3 * sd(whz, na.rm = TRUE),
                            mean(whz, na.rm = TRUE) + 3 * sd(whz, na.rm = TRUE)))

Elles excluent des enfants différents et donnent des taux légèrement différents. Dites laquelle vous avez employée ; un rapport de plausibilité SMART l’exige, et deux enquêtes employant des règles différentes ne sont pas directement comparables.

L’écart-type est déjà un constat

analysable = smart.loc[who_flagged, "whz"]
print(f"n = {len(analysable)}, mean = {analysable.mean():.2f}, "
      f"sd = {analysable.std():.2f}")
smart |> filter(who_ok) |> summarise(n = n(), mean = mean(whz), sd = sd(whz))

852 enfants, moyenne -0,67, écart-type 1,22.

La moyenne n’a rien de remarquable — une population un peu sous la médiane de référence, ce qui est normal dans ce secteur. L’écart-type, si. Une enquête bien mesurée produit un écart-type de poids-pour-taille compris entre environ 0,8 et 1,2, car l’écart-type de la population de référence vaut 1 par construction et les populations réelles ne sont que légèrement plus dispersées.

1,22 se situe à la limite de l’acceptable, et un écart-type au-dessus de la plage signifie l’une de trois choses — une erreur de mesure qui gonfle la dispersion, une population réellement hétérogène, ou un problème de saisie. C’est le nombre le plus informatif d’un rapport de plausibilité, et la leçon 5 apprend à le lire correctement.

Remarquez aussi ce qu’il fait à la prévalence. Une distribution plus large place davantage d’enfants au-delà d’un seuil fixe, si bien qu’un écart-type gonflé fait monter la MAG sans qu’aucun enfant ne soit plus malnutri.

Enregistrez les scores z avec leurs entrées

smart[["child_id", "cluster", "team", "age_months", "sex", "weight_kg",
       "height_cm", "measured_lying", "oedema", "whz"]].to_csv(
    "outputs/smart_with_zscores.csv", index=False)
readr::write_csv(smart, here::here("outputs", "smart_with_zscores.csv"))

Gardez les entrées à côté du résultat. Quand quelqu’un conteste une prévalence, la discussion ne porte presque jamais sur l’arithmétique — elle porte sur l’ajustement, la règle de signalement ou les enfants exclus, et les trois ne sont récupérables que si les entrées ont voyagé avec le résultat.

La suite

Vous avez un score z pour chaque enfant analysable. L’unité suivante en fait une classification — les définitions de cas de la malnutrition aiguë sévère et modérée, et le signe clinique qui prime sur les deux.

Animer cette leçon

La leçon en diaporama, la prose étant reléguée dans les notes du présentateur plutôt que projetée. Produit à partir de cette page, dont il ne peut donc pas s'écarter.

Lancer le diaporamaLire les diapositives

Le PDF ne requiert aucun logiciel et se projette depuis n'importe quel poste. Le fichier PowerPoint est fait pour être modifié : appliquez la charte de votre organisation, retirez une section pour une séance plus courte, ou fusionnez deux leçons en atelier.