Three datasets, all 12% missing, three completely different problems
Three datasets come back with an income column that is 12% missing. Same number, so presumably the same treatment.
In the first, a server occasionally dropped a write. Delete or impute — the answer barely moves. In the second, one segment skipped the back half of the form; drop those rows and that segment vanishes from the analysis entirely. In the third, high earners declined the income question, and the mean of what survives sits 1,489 below the truth.
| Why the income cell is blank | Missing rate | If you simply delete those rows |
|---|---|---|
| A server occasionally dropped a write | 12% | the answer barely moves |
| One segment skipped the back half of the form | 12% | that segment disappears from the analysis |
| High earners declined the income question | 12% | mean income lands 1,489 below the truth |
All three are 12%. And the rate cannot tell you which one you have. The hard part of handling missing data is never the filling — it is working out what you are dealing with.
The key question
Why is this cell blank — and does the reason have anything to do with the value itself?
Three reasons a cell can be blank
Donald Rubin's taxonomy is still where every discussion of missing data starts. The names are forbidding; the question behind them is not — what is the blankness related to?
MCAR
no patternBlank for reasons unrelated to anything in the table.
MAR
explained by a column you haveOne group skipped a section. Predictable, and fixable.
MNAR
explained by the missing valueThe largest values are the ones absent. Not recoverable.
MAR is the worst-named term in statistics
It says "at random" and means nothing of the kind. What it actually claims is "random once you condition on what you already know". Within an age band the blanks are random; across the dataset they are anything but.
| MCAR | MAR | MNAR | |
|---|---|---|---|
| Blank because of | Nothing in particular | Another column you observed | The hidden value itself |
| Example | A sensor dropped a reading | One segment skipped a section | High earners refused to answer |
| Deleting rows | Unbiased | Biased | Biased |
| Model-based imputation | Works, adds little | Works well | Cannot fix it |
| Testable from the data? | Partly | Partly | No — needs outside knowledge |
The final row is the fundamental difficulty of the whole topic. You cannot establish MNAR from the data. Doing so would require knowing the values that are missing — and if you knew them, they would not be missing.
So in practice you reason about it from domain knowledge. A non-response rate on the income question that is triple every other question is already grounds for suspecting MNAR.
The same 12% can cost you nothing or everything
Dropping rows with blanks is the simplest treatment and by far the most common. Under MCAR it costs sample size and introduces no bias. The trouble starts everywhere else.
| Situation | Deleting rows gives you | What you actually lost |
|---|---|---|
| A sensor drops readings (MCAR) | A smaller sample | Precision |
| Older users skip an online field (MAR) | No older users | An entire segment |
| High earners hide income (MNAR) | A lower mean income | The conclusion itself |
| Only churners have a reason recorded | No churners | The thing you are predicting |
| 5% missing in each of 20 columns | 64% of rows gone | Two thirds of the data |
That last row catches people out constantly. Five per cent per column sounds harmless, but spread independently across twenty columns only 0.95²⁰ ≈ 36% of rows are complete. Looking at per-column rates gives you no warning that this is happening.
Mean-filling keeps every row, so it looks costless. What it actually does is manufacture confidence. Every filled cell lands exactly on the mean, which makes the data look tighter than it is.
| Method | Mean | Variance | Correlation | Standard error |
|---|---|---|---|---|
| Mean fill | = | ↓ | ↓ | too small |
| Median fill | shifts | ↓ | ↓ | too small |
| Regression fill | = | ↓ | inflated | too small |
| Multiple imputation | = | ✓ | ✓ | ✓ |
| Listwise deletion (MCAR) | = | ✓ | ✓ | honest, just larger |
The standard error column is the one that matters. Any single-imputation method makes standard errors come out too small, because the filled-in values get treated as though they had been observed. Confidence intervals narrow, p-values shrink, and things that were not significant start looking as though they are.
What multiple imputation does differently
Instead of one value per blank it generates several plausible values, producing several complete datasets, analyses each, and pools the results. The fact that you do not know what belonged in that cell then shows up honestly in the standard error. More work, and the only version that does not lie.
An empty "spouse's income" probably means unmarried. An empty "cancellation reason" means they have not cancelled. In cases like these the blank is not noise — it is the strongest predictor in the table.
Which is why adding an indicator column before you fill anything is nearly always worth it. One extra column buys the model access to the fact that a value was absent.
Settle the mechanism, then pick the method
Look at where the blanks are before deciding what to do about them. A table of per-column rates is not enough; you need a row-by-column picture before a pattern appears.
| Missing rate | Default posture | Note |
|---|---|---|
| Under 5% | Delete or fill simply | Both give nearly the same answer |
| 5–20% | Consider model-based imputation | Add an indicator column too |
| 20–50% | Impute carefully, justify it | Imputed values start outnumbering real ones |
| Over 50% | Consider dropping the column | Keeping it requires an argument |
| Over 80% | Keep only the indicator | Presence tells you more than the value |
These are starting points, not rules. A column that is 60% missing can be worth keeping if it is decisive when present, and a column that is 3% missing deserves care if those 3% are MNAR.
| Method | Use when | What it costs |
|---|---|---|
| Listwise deletion | MCAR and under about 5% missing | Sample size; bias if not MCAR |
| Mean / median fill | A quick baseline, nothing more | Shrinks variance, weakens correlations |
| Forward fill | Time series where the value persists | Invents flat stretches that never happened |
| kNN imputation | Correlated columns, moderate size | Slow; sensitive to scaling |
| Regression / MICE | MAR with informative predictors | Complexity; needs the model to be right |
| Missing as a category | Categorical columns, tree models | Only sensible if blankness means something |
| An indicator column | Whenever blankness might carry signal | One more column; usually worth it |
What mean-filling did to the p-value
A salary table for 800 employees is missing 120 salaries (15%). Fill them with the mean, then run the department comparison.
| Complete cases (680) | After mean fill (800) | Read | |
|---|---|---|---|
| Mean salary | $84,200 | $84,200 | Identical by construction |
| Standard deviation | $30,100 | $27,700 | Down 8% |
| Correlation with tenure | 0.62 | 0.53 | The relationship looks weaker |
| p-value across departments | 0.031 | 0.008 | Looks more significant |
| Width of the 95% CI | ±$2,270 | ±$1,920 | Narrower |
The mean held and everything else moved. Putting 120 people exactly on the mean makes the data look tighter than it is, which shrinks the p-value and narrows the interval. Confidence appeared out of nowhere.
Checking who the 120 were made it worse: mostly executives and new hires. Executive pay was withheld; new hires had not been finalised. Two groups nowhere near the mean, all assigned the mean.
The lesson here
The real problem with mean imputation is not that the mean is wrong — it is that the standard error starts lying. Moving p from 0.031 to 0.008 upgrades "significant" to "highly significant" on the strength of numbers that were invented.
On a loan underwriting model, previous_employment_length came in 34% missing. Before deciding whether to drop or fill it, somebody flagged the blanks and looked at them on their own.
What the indicator showed
Default rate where the value was present: 3.1%
Default rate where the value was blank: 11.4%
Blank meant first job, or a gap in employment history. That single indicator predicted better than the original column ever had.
Had the column been dropped on the grounds that 34% is too much, the model would have lost its strongest feature. Find out what the blank means before deciding what to do with it.
Misconception 1
❌ A low missing rate means any method will do.
Three per cent missing still removes a whole group if those 3% are one group. What matters is not the percentage but who is absent.
Misconception 2
❌ Mean filling is safe because it preserves the mean.
The mean is the only thing it preserves. Variance, correlation, standard errors and p-values all move — and they always move in the direction of more confidence, which is what makes it dangerous.
Misconception 3
❌ Filling with zero is the neutral choice.
Zero is not neutral, it is a specific claim. Fill income with zero and the person is unemployed; fill temperature with zero and it is freezing. Especially dangerous in any column where zero already means something.
Misconception 4
❌ A good enough method makes the missingness go away.
No method creates information that was never collected. What a good method does is not fill the hole but report honestly that there is one.
Misconception 5
❌ You can detect MNAR by inspecting the data.
You cannot. Detecting it would require knowing the missing values, and knowing them would mean they were not missing. Domain knowledge and an understanding of how the data was collected are the only routes to that judgement.
Hold the rate fixed and change only the reason
A 40 × 6 map. Red cells are blank, and all three mechanisms are set to the same 12% rate. The first column is income; the cards below compare the true mean against the mean of whatever survived.
40 rows × 6 columns. The blank rate stays at 12% — only the reason changes. MCAR — blank for no reason at all
True mean income
4684
Mean of what is left
4432
Bias
-252
Blanks are scattered with no structure, so what survives is still a fair sample. The gap of -252 is sampling noise from 31 remaining values, not bias — it shrinks as n grows.
The rate tells you how much is gone. Only the mechanism tells you what it cost.
Learning points
The same 12% produces a bias of zero under one mechanism and 1,489 under another.
MAR is explained by a column you already hold, which is exactly what model-based imputation needs.
Under MNAR the largest values are the absent ones, so nothing that remains carries that information.
Without the map there is no way to tell the three apart.
Ask why first
The mechanism decides everything
Filling is not free
Every method distorts something
Blankness is data
Which cells are empty can be the finding
The question is not "how should I fill this?"
It is "why is it blank?" A method chosen before that answer is a guess that may or may not hold — and when it does not, it fails without telling you.
Missing-data handling has more influence on the final numbers than almost any other preprocessing step, and gets less thought than any of them. In SKARI you can check the following alongside.
Diagnosis
Missing Map, Missing Rate, Little's MCAR Test
Single imputation
Mean, Median, Forward Fill, kNN
Multiple imputation
MICE, Regression Imputation, Pooling
Sensitivity
Complete Case vs Imputed, Indicator Variables
Once this clicks, you can answer questions like these.