All work samples Case study · Education research

Nine survey rounds. One history per student.

For an education nonprofit in India, I turned nine rounds of student surveys, each exported differently and in two languages, into one longitudinal dataset. Every student is followed across years under a permanent ID, every answer is harmonised, every blank is explained, and every reported figure is rebuilt independently.

9survey rounds joined
~19ksurvey records
3studies, one method
Same student, matched across rounds First seen this round

Illustrative pattern, not real records

Illustrative structure, not real records

The panel, in three dimensions

Students × rounds × measures

Each layer is one survey round and each point a student in it. The bright threads are students matched from round to round, so a change in a score is a change in the same person, not a change in who was surveyed.

  • 01Paired change within each school year, every student compared with herself
  • 02Tracked cohorts across three years, with summer gains and losses kept apart
  • 03Ordinal mixed models for the direction of Likert answers
The pipeline

From messy exports to figures you can check

Every step is a script, run in order, so the whole dataset can be rebuilt from the raw files and a new round added without starting again.

01

Raw exports

Nine rounds, changing headers, answer labels in English and Hindi

02

Crosswalks

Every header and answer label mapped to one item code and one value

03

Cleaning

Typos, impossible values and skipped counts handled by rule and logged

04

Matching

Records joined into students on name, parents, school and class; doubtful pairs decided by people

05

Panel

One row per student per round, under a permanent ID that never changes

06

Analysis

Scales, English scores, paired change and ordinal models

07

Independent check

Every reported figure rebuilt in Stata, with no shared code

RPythonStataExcel crosswalksReproducible, numbered scripts
Record linkage

Same student, or her sister?

The surveys carried no student number. Records were joined with rules that forgive a spelling variant but never let two sisters become one person, and doubtful pairs were decided by the client's own team. Each student now has a permanent ID that later rounds can carry on the form.

Invented, masked examples. No real record is shown.

Invented answers for illustration

Missing data, kept honest

Every blank has a reason

A 98 left in an answer column quietly drags an average off its scale. Here the answer stays blank and its reason sits beside it as one letter, the same letters in all three studies, and as a missing value in Stata. Averages stay right and nothing is lost.

aNo response eDon't know dPrefer not to say fDid not understand the question uNot an option on the form
What the client received

A dataset they can keep building on

Clean data and a panel

Each round cleaned on its own, then joined into one history per student, in CSV and labelled Stata files.

Codebooks and crosswalks

Every question, code and missing reason documented, with a combined codebook across the three studies.

Independent verification

Stata do-files that rebuild the reports' figures from the delivered data, with no shared code.

Reports and dashboards

Findings written for funders and for general readers, with every figure traceable to a table.

Ready for the next round

Frozen IDs and step-by-step notes, so a new round joins the same students without starting again.

Privacy by design

Files that hold names and phone numbers are marked for the team only, and the analysis files that can be shared carry IDs instead.

Have survey data that needs to become evidence?

Whether it is one round or ten, I can help you clean it, join it and make every number checkable.