Lesson 7 of 8
Unit · Judgement
Baselines, targets, and what they make people do
Two numbers that turn an indicator into a commitment. Four ways to set a target, the baseline measured six months after the programme started, and the fact that every target changes the behaviour of the people being measured.
An indicator with a target is a different object
On its own, an indicator is a measurement. Put a baseline and a target beside it and it becomes a commitment, a performance judgement and — this is the part people underestimate — an instruction to everyone whose work it measures.
This lesson is about setting both honestly, and about the behaviour each one creates.
What a baseline has to be
A baseline is the value of the same indicator, computed the same way, before the intervention. Every word in that sentence is load-bearing.
- Same indicator. A baseline from a survey and an endline from routine data are not comparable. This is the commonest baseline failure and it is usually discovered at the evaluation.
- Same way. Same denominator, same age bands, same recall period. Version the reference sheet at baseline and keep it.
- Before. A baseline collected in month six measures a population the programme has already been working with.
baseline = {
"indicator": "penta3_coverage_percent_monthly",
"value": 61.4,
"source": "DHIS2, 2023 monthly mean over reporting facilities",
"collected": "2024-01",
"reference_sheet_version": "2.1",
"note": "Computed on the same denominator as the target. 2023 reporting "
"completeness was 71%, so the baseline is a lower bound.",
}
baseline <- list(
indicator = "penta3_coverage_percent_monthly",
value = 61.4,
source = "DHIS2, 2023 monthly mean over reporting facilities",
reference_sheet_version = "2.1"
)
The reference_sheet_version field is what makes a baseline survive three years.
Without it, the endline analyst has a number and no way to know what it meant.
The baseline you did not collect
Frequently there isn’t one, because the programme started before anyone thought about measurement. Three honest options, in order of preference:
- Reconstruct from routine data. Usually possible and usually the best answer. Say which months and what the reporting completeness was.
- Use a comparable external estimate — a DHS or MICS round, a previous SMART survey — and state the difference in method explicitly.
- Declare it unavailable and set a target on a trajectory instead, so performance is judged on the direction rather than on a distance from a number nobody has.
What you must not do is retrofit a baseline from the first period of programme data and present it as a pre-intervention value. An evaluator will find it, and the finding will be about honesty rather than about method.
Four ways to set a target
| Method | Basis | Best when |
|---|---|---|
| Normative | A standard says so — Sphere 15 L/person/day, 90% coverage | The standard is the point of the programme |
| Historical | Best recent performance, or best comparable district | Routine data exists and is trusted |
| Capacity | What the resources can deliver, costed | Constraints are the binding factor |
| Negotiated | What the donor and government agreed | Honest to name this as what it is |
Most real targets are the fourth, presented as the first. That is not necessarily wrong — a negotiated target is a legitimate commitment — but writing “negotiated” in the sheet changes the review conversation from “you failed” to “we agreed a number that assumed X, and X did not happen”.
Whichever method, write down the assumption the target rests on. A coverage target of 85% assumes the outreach budget, the vehicle and the vaccine supply. All three are assumptions from lesson 1, and when the target is missed they are the analysis.
Milestones, not just an endpoint
A single target three years out gives you nothing to manage against for two and a half of them.
import numpy as np
baseline_value, target_value, quarters = 61.4, 85.0, 12
trajectory = np.linspace(baseline_value, target_value, quarters + 1)[1:]
print([round(v, 1) for v in trajectory])
baseline_value <- 61.4; target_value <- 85.0; quarters <- 12
round(seq(baseline_value, target_value, length.out = quarters + 1)[-1], 1)
A straight line is a placeholder, not a plan. Two adjustments make it realistic:
- Front-load nothing. Programmes are slow to start. A trajectory flat for two quarters and steeper afterwards is more honest and less punishing at the first review.
- Respect seasonality. In an agricultural or malaria context, comparing Q3 to Q2 is comparing two different worlds. Set milestones against the same quarter of the previous year.
Every target changes behaviour
This is the part that belongs in an M&E course rather than a management one, because you are the person who will see it in the data first.
When a number is used to judge, the people being judged optimise the number. Sometimes that is exactly what you wanted. Often it is not, and the ways it goes wrong are predictable:
- Cream-skimming. A cure rate target encourages admitting the least severe cases, which raises the rate and reduces the programme’s value.
- Boundary effects. A target of 85% produces a suspicious number of reported values between 85% and 87%, and almost none at 84%.
- Effort reallocation. Resources move from unmeasured activities to measured ones, including from things that matter more.
- Definition drift. The definition quietly widens until the target is met. This is the one that looks like data quality and is not.
Pair every target with an indicator that would move in the opposite direction if it were being gamed. A cure rate target beside a mean admission severity; a coverage target beside the reporting rate; a caseload target beside the verification factor.
watch = pd.DataFrame({
"target_indicator": ["cure_rate_percent", "penta3_coverage_percent"],
"gaming_risk": ["admit less severe cases", "widen the catchment definition"],
"partner_indicator": ["mean_muac_at_admission_mm", "reporting_rate_percent"],
})
watch <- tibble::tribble(
~target_indicator, ~gaming_risk, ~partner_indicator,
"cure_rate_percent", "admit less severe cases", "mean_muac_at_admission_mm",
"penta3_coverage_percent", "widen the catchment definition", "reporting_rate_percent"
)
Write that table when the target is set, not when the number looks too good. It takes ten minutes and it is the difference between noticing in March and noticing at the evaluation.
Look for the boundary effect
Once a target exists, it is worth checking whether the distribution knows about it.
reported_rates = performance["cure_rate_percent"]
near = reported_rates.between(85, 87).sum()
just_below = reported_rates.between(82, 84).sum()
print(f"{near} sites just above target, {just_below} just below")
c(just_above = sum(dplyr::between(performance$cure_rate_percent, 85, 87)),
just_below = sum(dplyr::between(performance$cure_rate_percent, 82, 84)))
A pile-up immediately above a threshold with a hole immediately below it is one of the most reliable signals in performance data. It is the same logic as the digit preference check in the DQA course, and it deserves the same care in wording: it is a pattern that warrants a question, not a conclusion about anyone.
Revising a target
Targets get revised. Do it in the open.
version 1.0 -> 1.1
changed 2026-07-28
from 85% by Q12
to 78% by Q12
reason Outreach budget cut by 40% in Q3; the original target assumed the
full outreach schedule. Trajectory recomputed from Q5 actuals.
approved Programme manager and donor focal point, 2026-07-25
A revised target with a reason and an approval is a management decision. A target quietly edited in a spreadsheet is the finding that ends a partnership.
What comes next
You have an indicator, a baseline and a target. The final lesson is what happens when somebody external applies the OECD DAC criteria to all three — what an evaluator asks, which of your numbers survive the question, and how to have built the evidence before they arrive.