River
Y CombinatorBacked by Y Combinator
FREE TEMPLATE

Data Cleaning Documentation Template

The numbered exclusion cascade, the variable register with the denominators that actually apply, and the codebook generated from both.

Free download  ·  No account needed

Case Exclusion Cascade

[Study name], [wave or extract]

Raw file [file name as received]
Received [date]
Analytic file [file name after cleaning]
Prepared by [name]

Step  ID   Rule as executed                        Removed  Remaining
0          [raw file as received]                        —    [N raw]
1     E1   [rule, in syntax, threshold visible]     [count]    [count]
2     E2   [rule, in syntax, threshold visible]     [count]    [count]
3     E3   [rule, in syntax, threshold visible]     [count]    [count]
4     E4   [rule, in syntax, threshold visible]     [count]    [count]
5     E5   [rule that defines the analytic sample]  [count]    [count]
—          [analytic file]                               —  [N analytic]
—          Reconciliation: sum removed              [total]  [N analytic]
—          Share of raw file excluded          [per cent]

Every row carries the rule, the count, who decided, the date, and whether a later analyst may reverse it. If the removed column does not sum to the difference, rows left for a reason nobody wrote down.

Reasons, not just counts

Rows lost because an institution left the study are not attrition. The cascade records the mechanism, because the mechanism is what the limitation note is written from.

The pack is eight files, one standing rule and eight prompts. Four sheets carry the arithmetic: the exclusion cascade, the variable register, the transformation register and the outlier decision log. Four documents carry the argument: the cleaning log, the codebook, the known limitation note, and a page on which facts stop being recoverable and when. The rule is that a decision is a rule plus a row count, never a description.

Every sheet ships filled in for one illustrative workforce survey. Six numbered exclusions take 4,812 raw responses down to 3,465 analysed, and the removed column sums to 1,347, which is exactly the difference. On one variable, 1,547 of 3,465 rows carry no value, a 44.6 per cent missingness rate that is simply wrong: 1,422 of those rows were never asked the question. On the denominator that applies it is 6.1 per cent. Forty-one cells holding 999 moved the same variable's mean from 27.2 hours to 6.4.

Observational reporting standards ask you to report numbers of individuals at each stage of study with the reasons at each stage. A template with a Description column produces none of that, because a description contains no arithmetic. Open the pack in River and the cascade gets written as the rules run, or download the documents and sheets and fill them in yourself. Hand the analytic file to the results section writer, the methods section, and the reproducibility record that checks the code against it. More research packs sit alongside this one.

Every sheet in the pack

The Case Exclusion Cascade, the Variable Register, and the Outlier Decision Log.

Case Exclusion Cascade

Raw N at the top, one numbered rule per row, analytic N at the bottom, and a reconciliation row that subtracts in public.

IDRule as executedWhy it existsRemovedRemaining
meridian_w3_raw.dta as receivedStarting point. Nothing changed.4,812
E1drop duplicate respondent_id, keep earliestSession timeouts let respondents restart. The later attempt inherits prefilled answers.1184,694
E2drop if consent_confirmed != 1Approval covers affirmative consent only. 51 blank, 12 declined.634,631
E3drop if employer_id in (4 11 14)Three employers did not renew data sharing after wave 2.4024,229
E4drop if items_answered / items_offered < 0.20Threshold fixed 4 Feb, before the file arrived. The date is part of the row.2713,958
E5drop if missing(wellbeing_score)Primary outcome absent. This rule defines the analytic sample.3443,614
E6drop if hire_date > exposure_window_startExposure is undefined, not zero, for someone hired mid-window.1493,465
Reconciliation: 118 + 63 + 402 + 271 + 344 + 1491,3473,465

4,812 minus 1,347 is 3,465. The column closes, so 28.0 per cent of the raw file is excluded and the methods section states that figure. The largest exclusion is E3, and it is not attrition: the respondents did not withdraw, their employer did.

Variable Register

The applicable denominator is the column nobody ships, and it is the one that changes conclusions.

VariableMissing codes in useObservedMissingApplicable denominatorMissingness
wellbeing_scorenone in analytic file3,46503,4650.0%
ot_hours.a .b .c .d and system .1,9181,5472,0436.1%
contract_type.b3,441243,4650.7%
tenure_months.a3,2162493,4657.2%
sick_days_12m.b .c2,8745913,0967.2%

Unpacking the 1,547 missing cells on ot_hours:

CodeMeaningCellsBelongs in a missingness rate
.cNot applicable; contract carries no overtime provision1,204No
.aNot asked; routed past after reporting part-time hours218No
.bAsked and refused51Yes
.dSentinel 999, recoded at T241Yes
.Absent with no recorded reason33Yes
Total missing1,547125 of them

1,547 of 3,465 is 44.6 per cent and it is the wrong denominator: 1,422 rows were never asked the question. The applicable denominator is 3,465 minus 1,422, or 2,043, and 125 of those are missing. That is 6.1 per cent. A 44.6 per cent rate triggers an imputation model and a reviewer's question. A 6.1 per cent rate triggers neither. Export to CSV and only the wrong number survives.

Outlier Decision Log

Most outliers are not outliers. Keeping a value is a decision and it gets a row too.

VariableValueRowsSentinelWhat the check foundEffect on the statistic
ot_hours99941YesA wave 2 extract had been exported to CSV with 999 written for every missing cell, then merged back inMean of the 1,959 numeric cells falls from 27.2 to 6.4 hours
ot_hours61 to 803NoVerified against employer timesheets. All genuine; two are one respondent's second jobMean unchanged. Standard deviation rises 0.3
ot_hours0 on salaried contracts62NoSkip logic failed for one employer's link, so salaried staff saw the block and answered 0Applicable denominator falls 2,105 to 2,043; mean rises 6.2 to 6.4
tenure_months-90YesPresent in the wave 2 CSV copy only. Logged with zero rows so nobody merges it againNone
wellbeing_score019NoAll 19 answered every item. Zero is the scale floorNone. A floor is data, not an error

The 41 sentinel cells contributed 40,959 of a 53,234 total, which is 77 per cent of the sum from 2 per cent of the cells. No distribution plot flags that; it looks like a long right tail. It gets caught by asking whether an instrument with a maximum of 60 could physically record 999.

What's in the pack

01

Case Exclusion Cascade sheet

Raw N, one numbered rule per exclusion with its syntax and threshold, rows removed, rows remaining, and a reconciliation row that does the subtraction in public.

02

Variable Register sheet

Every variable with its label, storage type, value labels, every missing code in use and what each one means, and the applicable denominator a missingness rate should use.

03

Transformation Register sheet

One row per derived variable: its sources, the rule as executed, what happens when an input is missing, and why the derivation takes this form and not the obvious one.

04

Outlier Decision Log sheet

How each flagged value was found, whether it turned out to be a sentinel, what the external check found, the decision, and the effect on the statistic as a number.

05

Cleaning Log

One section per rule: what was run, why the data needed it, what alternative was considered and rejected, and what the decision costs. Revisions are dated rather than overwritten.

06

Codebook

Generated from the register rather than written beside it, because two descriptions of the same variable drift apart within a month and the codebook holds the stale one.

07

Known Limitation Note

What the analytic file no longer represents, rule by rule, with the direction each exclusion pushes an estimate. Written while the reasons are still known rather than at submission.

08

A rule and a row count, never a description

The standing space rule every prompt reads first. ICPSR's own guidance is that there are at least six missing data situations, each of which should have a distinct missing data code.

How to use it

  1. 1

    Open in River, or download it

    Open the pack in River and the agent reads your file's metadata with you, or download the blank Word documents and CSV sheets instantly.

  2. 2

    Send the native file, not an export

    A Stata or SPSS file plus your eligibility criteria and your primary outcome. The export is where the missing-value meanings die, and they do not come back.

  3. 3

    Register the variables before anything moves

    Observed and missing counts per variable, every missing code and its meaning, and the applicable denominator. This is the only irreversible step, so it runs first.

  4. 4

    Build the cascade as the rules run

    One numbered row per exclusion with its count, then reconcile. If the column does not close, rows left for a reason nobody recorded, and the sheet says so.

Frequently asked questions

Is this template free?

Yes. Download the whole pack as Word documents and CSV sheets with no signup and no credit card. Edit with AI is a separate, optional path where the agent reads your data file and builds the register and the cascade with you. The template library holds the rest.

What format are the downloaded files?

Word documents for the four documents and the rule, and CSV for the four sheets, in one zip. They open natively in Word, Pages, Google Docs, Excel, Numbers and Sheets with nothing to convert. Inside River the same content opens as live Docs and Sheets.

Why does it insist on the native file rather than a CSV?

Because a delimited file cannot hold why a value is absent. Stata alone carries 27 missing values, the system one plus 26 extended codes that analysts use to record not asked, refused or not applicable. A CSV has one empty cell, and the export is not reversible.

I only have a CSV. Is the pack still useful?

Yes, with one honest loss. The cascade, the transformation register and the outlier log all work unchanged. The Variable Register records that the missing-value semantics are unrecoverable, and that becomes a line in the limitation note rather than a silent gap in the missingness rates.

Does River clean the data for me?

It proposes rules and writes the record; you approve each rule before it is applied. Nothing is recoded silently and the raw file is never edited, because the raw file is the evidence. The researcher workspace is where the rest of the project lives.

Does the pack remove outliers?

It resolves them, which is different. The first three questions are whether the value is physically possible for the instrument, whether it repeats on a conventional number, and what upstream file wrote numbers for missing. Winsorising before those checks buries a sentinel inside a plausible range.

Is this only for survey data?

No. The worked example is a workforce survey because the missing-code problem is sharpest there, and the structure is identical for administrative records, trial data, panel extracts or a scraped dataset. Any file with an eligibility criterion has a cascade, and any file with an absent value has denominators.

Write the record while the reasons still exist

Send the native data file, your eligibility criteria and your primary outcome. The register and the cascade come back with the arithmetic closed.

Edit with AI