cassionData Analysis

Back to the lessonLesson 1 of 8Enrolment and its denominator

109% enrolled, 97% enrolled

The same deck as the downloads, rendered as a page. Start the slideshow to present it full screen — arrow keys or a click advance one slide, Escape leaves.

Slides · PDFSlides · PowerPoint

  1. Slide 1 / 20

    What this lesson covers

    • Two ratios, one register
    • Why a ratio can exceed 100%
    • The denominator is a projection
    • Which one to report
    • What the ratios cannot tell you
    • What comes next
    Speaker notes
    Two ratios from one register. The gross is 109.2% and the net is 97.4%, both are correct, and the twelve points between them are children who are in school at the wrong age rather than children who are missing.
  2. Slide 2 / 20

    Two ratios, one register — In Python (cont.)

    import pandas as pd
    
    enrolment = pd.read_csv("school-enrolment-2024.v1.csv")
    population = pd.read_csv("school-age-population-2024.v1.csv")
    
    current = enrolment[enrolment["school_year"] == 2024]
    primary = current[current["grade"].between(1, 6)]
    
    denominator = population.loc[
        (population["reference_year"] == 2024)
        & population["age_years"].between(6, 11),
        "projected_population",
    ].sum()
    
    gross = len(primary) / denominator
    net = len(primary[primary["age_years"].between(6, 11)]) / denominator
  3. Slide 3 / 20

    Two ratios, one register — In Python (cont.)

    
    print(f"gross enrolment ratio: {gross:.1%}")
    print(f"net enrolment ratio:   {net:.1%}")
  4. Slide 4 / 20

    Two ratios, one register — In R

    library(dplyr)
    
    primary <- enrolment |> filter(school_year == 2024, between(grade, 1, 6))
    denominator <- population |>
      filter(reference_year == 2024, between(age_years, 6, 11)) |>
      summarise(n = sum(projected_population)) |> pull(n)
    
    tibble(
      gross = nrow(primary) / denominator,
      net = sum(between(primary$age_years, 6, 11)) / denominator
    )
  5. Slide 5 / 20

    Two ratios, one register

    RatioNumeratorDenominatorValue
    GrossAll primary enrolees, any ageChildren aged 6–11109.2%
    NetPrimary enrolees aged 6–11Children aged 6–1197.4%
  6. Slide 6 / 20

    Two ratios, one register

    • The numerators differ; the denominator is identical — That is the whole definition, and it is why the two ratios are…
    Speaker notes
    The numerators differ; the denominator is identical. That is the whole definition, and it is why the two ratios are not two estimates of one thing.
  7. Slide 7 / 20

    Why a ratio can exceed 100%

    • Over-age and under-age enrolment — Children outside the official age range are in the numerator and not in the…
    • A denominator that is too small — The population file is a projection, not a count, and a projection that undershoots…
    • Double counting — A child enrolled at two schools appears twice
    Speaker notes
    A gross ratio above 100% is not an error. Three things produce it and only one is a defect. Over-age and under-age enrolment. Children outside the official age range are in the numerator and not in the denominator. This is the dominant cause here and it is a real feature of the system, not a data problem. A denominator that is too small. The population file is a projection, not a count, and a projection that undershoots inflates every ratio built on it. Double counting. A child enrolled at two schools appears twice. This one is a defect, and this register has it.
  8. Slide 8 / 20

    Why a ratio can exceed 100% — In Python

    duplicates = current.duplicated(subset=["student_id", "school_year"], keep=False)
    print(f"student-years appearing more than once: {duplicates.sum()}")
    
    unique = current.drop_duplicates(subset=["student_id", "school_year"])
    unique_primary = unique[unique["grade"].between(1, 6)]
    print(f"gross ratio after deduplication: {len(unique_primary) / denominator:.1%}")
  9. Slide 9 / 20

    Why a ratio can exceed 100% — In R

    enrolment |> filter(school_year == 2024) |>
      count(student_id) |> filter(n > 1) |> nrow()
    Speaker notes
    Twelve students appear twice, once under each school, because a transfer was recorded as a new enrolment rather than a move. Deduplicate on student and year before either ratio, and note that the effect here is small — the point is not the size, it is that a register which double-counts is wrong about who exists.
  10. Slide 10 / 20

    The denominator is a projection — In Python

    CENSUS_YEAR, GROWTH = 2015, 0.021
    factor = (1 + GROWTH) ** (2024 - CENSUS_YEAR)
    print(f"nine years compounded at {GROWTH:.1%}: factor {factor:.3f}")
    print(f"so about {1 - 1 / factor:.0%} of the denominator is an assumption")
  11. Slide 11 / 20

    The denominator is a projection — In R

    (1 + 0.021)^(2024 - 2015)
  12. Slide 12 / 20

    The denominator is a projection

    • A factor of 1.21, so roughly a sixth of the denominator was never counted — This is the immunisation denominator from…
    Speaker notes
    A factor of 1.21, so roughly a sixth of the denominator was never counted. This is the immunisation denominator from the public health course, in a different sector: a census base, a growth assumption, and nine years of compounding. The consequence is specific. If the projection is 5% too low, the gross ratio falls from 109.2% to about 104% and the net from 97.4% to about 93%. Neither conclusion changes, but a report claiming primary enrolment rose two points between years may be reporting the growth rate rather than the schools.
  13. Slide 13 / 20

    The denominator is a projection — In Python

    for error in (-0.05, 0.0, 0.05):
        adjusted = denominator * (1 + error)
        print(f"projection {error:+.0%}: gross {len(primary) / adjusted:.1%}, "
              f"net {len(primary[primary['age_years'].between(6, 11)]) / adjusted:.1%}")
  14. Slide 14 / 20

    The denominator is a projection — In R

    # Vary the denominator and see which conclusions survive.
  15. Slide 15 / 20

    The denominator is a projection

    • Show the sensitivity rather than the point estimate — where the denominator is projected
    Speaker notes
    Show the sensitivity rather than the point estimate where the denominator is projected. It costs three lines and it is the difference between a ratio and a ratio you can defend.
  16. Slide 16 / 20

    Which one to report

    • Net enrolment answers "are children of school age in school" — It is the SDG 4.1 framing and the right ratio for a…
    • Gross enrolment answers "how much primary schooling is being delivered" — It is the right ratio for a capacity question…
    • The gap between them is the finding — and it is the reason to report both: twelve points of over-age enrolment is a…
    Speaker notes
    Neither, alone. Net enrolment answers "are children of school age in school". It is the SDG 4.1 framing and the right ratio for a coverage question. It cannot exceed 100%, which makes it the safer number to publish. Gross enrolment answers "how much primary schooling is being delivered". It is the right ratio for a capacity question — teachers, classrooms, textbooks — because an over-age child needs a desk exactly as much as an in-age one. The gap between them is the finding, and it is the reason to report both: twelve points of over-age enrolment is a statement about repetition and late entry that neither ratio makes on its own.
  17. Slide 17 / 20

    Which one to report — Example

    Primary enrolment, 2024, four districts
    
      Gross enrolment ratio       109.2%   1,052 enrolees / 963 children aged 6-11
      Net enrolment ratio          97.4%     938 in-age enrolees / same denominator
      Over-age share of enrolment  36.4%   above the official age for their grade
    
      Denominator is a projection from the 2015 census at 2.1% a year. A 5%
      error in it moves the gross ratio by about five points and changes no
      conclusion.
      12 student-years were recorded twice after transfers and are deduplicated.
  18. Slide 18 / 20

    What the ratios cannot tell you

    • Neither is attendance — A child enrolled and never present is in both numerators
    • Neither is completion — Enrolment is a stock at a point in the year; whether those children finish is a cohort question…
    • Neither is learning — A system can enrol every child of school age and teach none of them, and the last unit is the…
    Speaker notes
    Neither is attendance. A child enrolled and never present is in both numerators. The next unit is that distinction, and it is worth more than either ratio. Neither is completion. Enrolment is a stock at a point in the year; whether those children finish is a cohort question and the third unit. Neither is learning. A system can enrol every child of school age and teach none of them, and the last unit is the instrument that would notice.
  19. Slide 19 / 20

    What comes next

    • Twelve points of the gap between the two ratios is over-age enrolment.
    Speaker notes
    Twelve points of the gap between the two ratios is over-age enrolment. The next lesson is who those children are, why being behind is the strongest predictor in this register, and how repetition makes it compound.
  20. Slide 20 / 20

    Where this goes next

    Read the full lesson, with runnable code Back to the lesson