Missing Data Generator
Dropping incomplete rows is safe when values are missing completely at random, and quietly biases everything when they are not. The usual diagnostic — compare the missingness rate between two halves of another column — separates the safe case from the rest and then stops. It cannot tell you whether the gaps depend on something you recorded or on the very value that is absent, and no test on the data can. This generates all three mechanisms, and because it keeps the values it removed, it can show you the bias itself rather than describing it.
What this generator does
Builds an age, income and hours table, removes income values under one of three mechanisms and hours values completely at random, so a row can be incomplete in more than one place. It reports the rate overall and for the younger and older halves, how many rows a complete-case analysis would drop, and the mean income before and after removal.
How to use this tool
- Choose the pattern and roughly what share of values should be missing.
- Compare the missingness rate between the younger and older halves — and notice that the last two patterns look alike on it.
- Then compare the mean income before and after removal, which is where those two differ.
- Copy the CSV to test an imputation method.
Understanding the controls
- How many rows
- Between 20 and 500 rows of age, income and hours, split at the median age for the diagnostic.
- Pattern
- Completely at random removes values independently of everything. Missing at random removes far more from older rows — visible, and correctable, because age is recorded for everyone. Missing not at random removes far more of the high incomes, which is neither.
- Missing rate (%)
- Roughly what share of income values are absent overall.
- Seed
- Reproduces the same rows and the same gaps.
Worked examples
- 20 rows, missing at random by age, 30% target rate, seeded "demo"
- 15% of income values and 10% of hours values ended up missing, leaving 5 of 20 rows incomplete somewhere. The diagnostic shows 9.1% missing among younger rows against 22.2% among older ones — a real gap, and one the missing-not-at-random pattern would show too, which is exactly why the diagnostic alone can't tell the two apart.
Common use cases
- Test data for imputation and missing-value handling
- Showing when complete-case analysis is safe and when it is not
- Teaching the difference between missing at random and not
- Checking that a pipeline handles empty cells at all
- Reproducing the same pattern of gaps from a seed
How this generator works
The age-dependent pattern applies a much higher removal chance above the median age; the not-at-random pattern applies it above the median income instead. Both produce a large split by age, which is exactly the difficulty: the diagnostic reports “not completely at random” for both and cannot say which is at work. What separates them is measurable only here — under the not-at-random pattern the values that were removed are markedly larger than the ones that survived. Every claim is re-checked against the rows before display, and the split by age is judged as a two-proportion z rather than a fixed number of percentage points, because two halves that are genuinely alike differ by several points quite often.
Randomness and fairness
Ages, incomes and which values go missing are random; the pattern is enforced and verified. Seeded datasets reproduce exactly and are therefore explicitly not cryptographically secure; a dataset comes back while the generator is unchanged. Without a seed the browser's cryptographically secure generator is used.
For how randomness is produced across the whole site, see how Generate Random works.
Limitations and good to know
- The not-at-random pattern cannot be identified from the data. This page can show its bias only because it kept the values it removed, which is exactly what a real dataset cannot do.
- Three columns only — age, income and hours — chosen because the dependency between them is intuitive. Age is never missing, since the diagnostic needs a complete column to split on.
- No imputation is performed; this generates the problem rather than solving it.
- Rates are approximate, since each row is decided independently.
- Rows are discarded when you leave; seed them to test two imputation methods on identical gaps.
Privacy and your data
Rows and gaps are generated in your browser. Neither the data nor your seed leaves the page; what is measured is that a dataset was made and how many rows it has.
Frequently asked questions
- If the diagnostic can't distinguish the last two patterns, what can?
- Nothing computed from the data alone — that's the honest limit this page demonstrates rather than hides. Because this tool kept the values it removed, it can additionally show that under the not-at-random pattern the removed income values are markedly larger than the ones that survived — a check only possible here, since a real dataset never retains what was actually removed.
- Is it ever safe to just drop the incomplete rows?
- Only under the completely-at-random pattern, where missingness has nothing to do with any value, recorded or not. Under the other two patterns, dropping incomplete rows systematically removes a non-random slice of the data — older people, or higher earners — and any statistic computed on what remains is biased by exactly that omission, not just smaller in sample size.
Related generators
- Outlier Dataset GeneratorContaminated samples where the planted outliers are labelled, so a detection rule can be scored on both kinds of error.
- Logistic Regression Dataset GeneratorTwo-feature classification data with a known decision boundary, and the majority-class baseline any model must beat.
- Synthetic Test Data GeneratorBuild a whole table of fictional records from the fields you choose, then export them as a table, JSON, CSV or SQL inserts.
- Correlation Matrix GeneratorCorrelation matrices built from a factor model, so they are positive semi-definite — which hand-picked numbers usually are not.
- Sampling Distribution SimulatorTake a sample, take its mean, repeat — and watch means from even a badly skewed population pile up symmetrically.