Leçon 5 sur 8
Unité · Faire coïncider les pièces
Rattacher un dénominateur de population
D'où vient un dénominateur, comment le joindre sans apparier sur un nom, et pourquoi les populations de bassins de desserte ne totalisent pas un district. Plus le taux de couverture au-dessus de 100 % et ce qu'il dit réellement.
Le numérateur est la moitié facile
Compter ce qu’a fait votre programme relève de la comptabilité. Décider par quoi le diviser relève de l’analyse, et c’est là qu’un taux de couverture se gagne ou se perd.
L’extraction vaccinale rend la chose concrète — elle livre target_population
dans le fichier, un chiffre par formation sanitaire, constant sur les douze mois.
C’est commode et c’est aussi l’estimation de quelqu’un, faite à un moment donné,
par une méthode donnée, et toute cette leçon consiste à ne pas la prendre pour un
fait au seul motif qu’elle est arrivée dans une colonne.
D’où vient réellement un dénominateur
Quatre sources, à peu près par ordre décroissant de fréquence des disputes.
- Une projection de recensement. L’institut national de statistique publie un recensement et un taux de croissance ; toute population de district que vous employez est une projection à partir de l’année du recensement. Dans une grande partie de ce secteur, ce recensement a dix ans ou davantage.
- Une base administrative de population. Les dénominateurs du ministère de la
santé par bassin de desserte, ce qu’est ici
target_population. Généralement dérivés de la projection par un coefficient — 3,5 % de la population pour les moins d’un an, 20 % pour les moins de cinq ans, 4 % pour les femmes enceintes. - Une cible de programme. Le nombre de personnes que le programme prévoyait d’atteindre. Dénominateur légitime pour « avons-nous fait ce que nous avions dit », jamais pour « quelle part de la population est couverte ».
- Une enquête. La plus défendable et la moins disponible, car une enquête donne une proportion avec un intervalle de confiance plutôt qu’un effectif.
Nommez la source dans la colonne. target_population_moh_2024 et
target_population_census_projection sont deux nombres différents, et dès que
deux d’entre eux se trouvent dans le même dossier sans libellé, quelqu’un en fera
la moyenne.
Joignez sur le code, jamais sur le nom
Le cours de nettoyage a défendu cet argument à propos des noms de lieux. Il vaut d’être répété ici parce qu’une base de population est l’endroit où une jointure sur nom fait le plus de dégâts : le dénominateur est la seule colonne où un appariement raté ne ressemble pas à un appariement raté, il ressemble à une formation sanitaire sans couverture.
population = pd.read_csv("admin-population-2024.csv") # admin2_pcode, year, pop_total, pop_under1
vax["admin2_pcode"] = vax["admin2_pcode"].astype("string").str.strip().str.upper()
with_denominator = vax.merge(
population.query("year == 2024"),
on="admin2_pcode", how="left", validate="many_to_one",
)
missing = with_denominator["pop_under1"].isna().sum()
assert missing == 0, f"{missing} rows have no population figure"
population <- read_csv("admin-population-2024.csv")
with_denominator <- vax |>
mutate(admin2_pcode = toupper(stringr::str_squish(admin2_pcode))) |>
left_join(filter(population, year == 2024),
by = "admin2_pcode", relationship = "many-to-one")
stopifnot(!any(is.na(with_denominator$pop_under1)))
L’assertion est la ligne importante. Une jointure à gauche qui n’apparie pas laisse un dénominateur manquant ; un dénominateur manquant rend un taux de couverture manquant ; et un taux de couverture manquant est exclu d’une moyenne, si bien que la moyenne du district devient discrètement la moyenne des seuls endroits qui se sont appariés.
La projection, et l’année que personne n’énonce
Une projection de recensement, c’est une population de base et un taux de croissance. Calculez-la au grand jour.
GROWTH = 0.024 # national annual growth rate, published with the census
CENSUS_YEAR = 2015
population["pop_2024"] = population["pop_census"] * (1 + GROWTH) ** (2024 - CENSUS_YEAR)
GROWTH <- 0.024
CENSUS_YEAR <- 2015
population <- population |>
mutate(pop_2024 = pop_census * (1 + GROWTH)^(2024 - CENSUS_YEAR))
Neuf ans à 2,4 % font un facteur de 1,24. Un quart de votre dénominateur est une hypothèse, et elle se compose : deux districts projetés depuis le même recensement au même taux national conserveront exactement leurs tailles relatives, ce qui est précisément ce qui ne se produit pas là où il y a eu des déplacements.
Aussi, lorsqu’un taux de couverture est contesté, la projection est en général la réponse honnête. Trois habitudes qui la maintiennent défendable.
- Écrivez l’année du recensement, le taux de croissance et sa source à côté du nombre.
- Utilisez la même projection pour tous les indicateurs d’un rapport. Deux indicateurs sur deux projections ne sont pas comparables, et personne ne le remarquera.
- Là où des déplacements ont eu lieu, dites que la projection n’en tient pas compte, et donnez le sens de l’erreur au lieu de prétendre la corriger.
Les bassins de desserte ne s’additionnent pas
Le bassin d’une formation sanitaire est la population qu’elle est censée desservir. Additionnez les bassins de toutes les formations d’un district et vous n’obtiendrez pas le district.
by_facility = vax.query("antigen == 'penta3' and period == '2024-01-01'")
print("sum of facility targets:", by_facility["target_population"].sum())
vax |>
filter(antigen == "penta3", period == "2024-01-01") |>
summarise(total = sum(target_population))
Ici cette somme vaut 11 774 pour le mois. Ce n’est un dénominateur de district utilisable que si les bassins partitionnent le district — sans chevauchement et sans trou — et ce n’est presque jamais le cas. Deux formations de part et d’autre d’une ville comptent toutes deux la ville. Une population située entre deux bassins est comptée deux fois ou pas du tout.
La conséquence est précise et fréquente : la couverture par formation sanitaire n’est pas fiable et la couverture au niveau du district l’est. Les gens traversent les limites de bassin pour se faire vacciner, si bien que le numérateur d’une formation inclut des enfants du dénominateur de sa voisine. Agrégez au niveau où la traversée se produit à l’intérieur de l’unité, et le bruit s’annule.
district = (
vax.query("antigen == 'penta3'")
.groupby("period")
.agg(doses=("doses_administered", "sum"),
target=("target_population", "sum"))
)
district["coverage"] = district["doses"] / district["target"]
district <- vax |>
filter(antigen == "penta3") |>
summarise(doses = sum(doses_administered),
target = sum(target_population), .by = period) |>
mutate(coverage = doses / target)
Une couverture supérieure à 100 %
Cela arrive constamment et ce n’est jamais un programme qui dépasse sa population. Quatre causes, dans l’ordre où il vaut la peine de les vérifier.
- Le dénominateur est trop petit. Une projection périmée, ou un coefficient de bassin qui suppose moins de moins d’un an qu’il n’y en a.
- Le numérateur inclut des gens de l’extérieur. Traversée de limites, ou une campagne qui a attiré des gens d’un district voisin.
- La granularité est fausse. Des doses comptées là où on voulait des enfants — un enfant recevant trois doses d’un antigène à trois doses reste un enfant.
- Une jointure a multiplié quelque chose. Tout ce qui est dans la leçon 1.
over = district[district["coverage"] > 1]
print(over)
district |> filter(coverage > 1)
Rapportez-le plutôt que de l’écrêter. Un taux de couverture plafonné à 100 % a jeté la preuve que le dénominateur est faux, et ce dénominateur faux est le constat.
Taux pour mille, et le piège de l’annualisation
district["per_1000"] = 1000 * district["doses"] / district["target"]
district <- district |> mutate(per_1000 = 1000 * doses / target)
Deux pièges logent au même endroit. D’abord, une couverture mensuelle n’est
pas une couverture annuelle, et la multiplier par douze suppose que chaque mois a
rapporté — ce que le cours de nettoyage a montré faux en août et septembre ici.
Ensuite, un taux pour mille exige que sa période figure dans le libellé :
doses_per_1000_under1_per_month est sans ambiguïté, rate ne l’est pas.
Écrivez le dénominateur
Tout indicateur que vous publiez devrait porter une fiche de référence.
| Champ | Valeur |
|---|---|
| Indicateur | Couverture penta3, district |
| Numérateur | Doses de penta3 administrées, formations ayant rapporté |
| Dénominateur | Nourrissons survivants, bassins du ministère sommés au district |
| Source | Estimations de population du ministère 2024, projetées du recensement 2015 à 2,4 % |
| Désagrégation | Mois, type de formation sanitaire |
| Réserve | Taux de complétude de 29 % en août ; couverture calculée sur les seules formations ayant rapporté |
Ce tableau prend deux minutes et règle la question définitivement. C’est le même geste que le fichier de définitions que le cours de fondamentaux écrit à côté d’une table de résultats, et c’est ce que le cours Conception d’indicateurs et cadre logique développera plus tard en fiche de référence complète.
La suite
Le dénominateur répond à « sur combien de personnes ». La leçon suivante répond à « sur combien de périodes » — construire un calendrier complet pour qu’une formation sanitaire n’ayant jamais rapporté en août apparaisse comme un trou plutôt que de ne pas apparaître du tout.