cassionData Analysis

Lesson 1 of 8

Unit · The ladder is not the source

Four fifths improved, half with service

82.3% of these households are on an improved source and 56.3% have at least basic drinking water service. The twenty-six points between the two are collection time, and they are the whole reason the ladder has rungs.

PythonR120 minSustainable Development Goals (SDG)Sphere Standards

The number most WASH reports give

Count the households on an improved source, divide by the households surveyed, and publish it as access.

import pandas as pd

households = pd.read_csv("wash-household-survey-2024.v1.csv")

IMPROVED = {                       # the JMP list, delivered water included
    "piped-into-dwelling", "piped-into-yard", "public-tap",
    "borehole", "protected-well", "protected-spring", "tanker-truck",
}
improved = households["water_source"].isin(IMPROVED)
print(f"improved source: {improved.mean():.1%} of {len(households)} households")
library(dplyr)

improved <- c("piped-into-dwelling", "piped-into-yard", "public-tap",
              "borehole", "protected-well", "protected-spring",
              "tanker-truck")

households |> summarise(improved = mean(water_source %in% improved), n = n())

82.3%. It is a correct calculation of a thing nobody asked about.

The ladder the SDG indicator actually uses

The JMP drinking water ladder has four rungs, and the source type only decides which two you are choosing between.

Rung Definition
Safely managed An improved source on premises, available when needed, and free from contamination
Basic An improved source, round trip 30 minutes or less including queueing
Limited An improved source, round trip more than 30 minutes
Unimproved An unprotected well or spring
Surface water River, dam, lake, pond, canal, irrigation channel

SDG indicator 6.1.1 is the safely managed rung. The humanitarian reporting line, and the one most programmes are measured on, is at least basic — safely managed plus basic.

def ladder(row):
    if row["water_source"] == "surface-water":
        return "surface water"
    if row["water_source"] not in IMPROVED:
        return "unimproved"
    minutes = row["round_trip_minutes"]
    return "basic" if minutes <= 30 else "limited"

households["service"] = households.apply(ladder, axis=1)
print(households["service"].value_counts(normalize=True).round(3))
households |>
  mutate(service = case_when(
    water_source == "surface-water" ~ "surface water",
    !water_source %in% improved ~ "unimproved",
    round_trip_minutes <= 30 ~ "basic",
    TRUE ~ "limited"
  )) |>
  count(service) |>
  mutate(share = n / sum(n))
Rung Households Share
Basic (including on premises) 1,352 56.3%
Limited 626 26.1%
Unimproved 326 13.6%
Surface water 99 4.1%

At least basic drinking water service: 56.3%. The source-type figure was 82.3%, and every one of the twenty-six points between them is a household on an improved source it takes more than half an hour to reach and return from.

Why the thirty minutes is in the definition

It is not administrative tidiness. A round trip over thirty minutes changes behaviour in ways that are measurable elsewhere in this same file:

  • households collect less water, so quantity falls below the Sphere minimum more often;
  • collection is done by women and girls, so the time comes out of school attendance and paid work;
  • households supplement from a nearer, worse source, so the recorded source is not the only source.

A definition that looks bureaucratic usually encodes a finding. Before arguing that a threshold is arbitrary, look for the thing it was set to separate.

The rung this survey cannot compute

Safely managed needs three conditions and this file supports one of them.

on_premises = (households["round_trip_minutes"] == 0)
tested = households["ecoli_cfu_100ml"].notna()

print(f"on premises: {on_premises.mean():.1%}")
print(f"water quality tested: {tested.mean():.1%}")
print(f"both: {(on_premises & tested).mean():.1%}")
households |> summarise(
  on_premises = mean(round_trip_minutes == 0),
  tested = mean(!is.na(ecoli_cfu_100ml))
)

27.7% of households have water on premises. Availability when needed is not asked. Freedom from contamination is tested on a third of the sample. So safely managed is not computable here, and the honest report says so rather than reporting on-premises as though it were the top rung.

That is the commonest way an SDG figure gets overstated: one of three conditions is measured, and the indicator is published under the name of all three.

Report the distribution, not the top rung

Drinking water service level, 2,403 households

  At least basic         56.3%   1,352
    of which on premises 27.7%     665
  Limited                26.1%     626
  Unimproved             13.6%     326
  Surface water           4.1%      99

  JMP ladder. Safely managed not computable: availability was not asked and
  water quality was tested on 33.4% of households.

Every rung, with counts. A report that gives only “56.3% have basic service” hides that a quarter of the population is one threshold away and would move with a nearer water point — which is exactly the group a programme can act on.

What comes next

Water has one ladder and two more are waiting. The next lesson does sanitation and hygiene, where the equivalent of the thirty-minute rule is a single boolean column that quietly halves a coverage figure.

Teach this lesson

The lesson as a slide deck, with the prose kept in the speaker notes rather than on the slide. Generated from this page, so it cannot fall out of step with it.

Start the slideshowRead the slides

The PDF needs no software and projects from any machine. The PowerPoint file is there to be edited — add your organisation's branding, cut a section for a shorter session, or merge two lessons into a workshop.