| EDA asks | Modelling asks |
|---|---|
| What is in this file? | Does X predict Y? |
| What is wrong with it? | How large is the effect? |
| What shape is this variable? | Is it significant? |
| Who is missing, and why? | Controlling for what? |
| Tukey's objection | What it changed |
|---|---|
| Statistics had become confirm-only | Made exploration a legitimate stage |
| Display was treated as decoration | Made plotting central, not cosmetic |
| Assumptions went unchecked | Look at the data before assuming its shape |
| Robustness was neglected | Median and IQR over mean and SD for messy data |
| Exploratory | Confirmatory | |
|---|---|---|
| Hypothesis | Generated by the analysis | Fixed before the analysis |
| p-values | Not meaningful | The point |
| Data | This dataset | Ideally fresh data |
| Surprises | Welcome | A warning sign |
| Output | Questions | Answers |
| The story you arrived with | What EDA might find |
|---|---|
| "The scheme improved nutrition" | The outcome is missing for a third of the treated |
| "District X is an outlier" | District X has 40 households in the sample |
| "Incomes rose" | The mean rose; the median did not |
| "Coverage is 90%" | 90% of those the question applied to |
| Skipped step | What ships as a result |
|---|---|
| No inspection | A weight variable read as a measurement |
| No cleaning | Age 999 in the mean |
| No description | A mean reported for a bimodal variable |
| No plotting | A curved relationship summarised as r = 0.1 |
| No questioning | A pattern reported as a finding |
| Catch | Cost of missing it |
|---|---|
| Impossible values | A mean that no reader can reproduce |
| Non-random gaps | A finding that holds only for those who answered |
| Skew | A "typical" household nobody resembles |
| Clustering and weights | Confidence intervals far too narrow |
| Duplicate IDs | Households counted twice, silently |
| Design choice | What it means for your analysis |
|---|---|
| Dwellings are sampled, not people | People in institutions and the homeless are out of frame |
| One respondent often answers for all | Members' details are proxy-reported |
| Household defined by shared cooking | Definitions differ between surveys |
| Members listed by relation to head | "Head" is a reported role, not a legal one |
| Question about | Lives in | Keyed by |
|---|---|---|
| Assets, water, sanitation | Household roster | Household ID |
| Age, sex, education, work | Member roster | HH ID + person line |
| Fertility, anthropometry | Woman / child file | HH ID + line |
| Consumption items | Item-level file | HH ID + item code |
| HH ID | Person line | Age | Sex | Education |
|---|---|---|---|---|
| 10231 | 1 | 44 | Male | Secondary |
| 10231 | 2 | 40 | Female | Primary |
| 10231 | 3 | 16 | Female | Secondary |
| 10231 | 4 | 11 | Male | Primary |
| 10232 | 1 | 67 | Female | None |
| You want | You must |
|---|---|
| Number of households | Count distinct household IDs, not rows |
| Mean household size | Collapse to household level first |
| % of women literate | Restrict to women, then weight by person weight |
| Household consumption per head | Divide by members, not by rows |
| Survey | What it covers | Who runs it | Frequency |
|---|---|---|---|
| NSS (consumption, etc.) | Consumption expenditure, employment, social consumption | NSSO / MoSPI | Rounds (subject rotates) |
| PLFS | Labour force: work, unemployment, wages | NSSO / MoSPI | Annual since 2017–18 |
| NFHS | Health, nutrition, fertility, anaemia, women's status | IIPS / MoHFW | ~5 yrs (NFHS-5: 2019–21) |
| CMIE-CPHS | Household income, consumption, sentiment | CMIE (private) | Continuous, 3 waves/yr |
| Survey | Best used for | Watch out for |
|---|---|---|
| NSS | Consumption, employment, social consumption | Subject rotates by round; comparability across rounds |
| PLFS | Annual and quarterly labour estimates | Urban panel design differs from rural |
| NFHS | Health, nutrition, gender, district estimates | Cross-sectional; not a panel |
| Census | Complete counts, small areas | Decennial; 2021 round delayed |
| NSS employment rounds | PLFS | |
|---|---|---|
| Started | Quinquennial rounds | 2017-18 |
| Frequency | Every ~5 years | Annual rural, quarterly urban |
| Panel element | None | Urban households revisited |
| Comparability | — | Breaks with earlier NSS series |
| NFHS-5 gives you | It does not give you |
|---|---|
| District-level estimates | Block or village estimates |
| Anthropometry and biomarkers | Consumption or income |
| Women 15-49 and men 15-54 | A panel over time |
| Two phases (2019-20, 2020-21) | A clean pre- and post-pandemic split |
| CPHS strength | CPHS caution |
|---|---|
| High frequency — waves every four months | Not an official statistical product |
| A genuine panel of households | Attrition accumulates across waves |
| Fast reading on income and unemployment | Sampling frame criticised for under-covering the poorest |
| Fills gaps between official rounds | Access is commercial, so replication is limited |
| Statistic | Unit it belongs to | Denominator |
|---|---|---|
| Anaemia prevalence | Women 15-49 | Women tested, not all women |
| Stunting rate | Children under 5 | Children measured |
| MPCE | Household, per head | Household members |
| Unemployment rate | Person in labour force | Labour force, not population |
anaemia_pct_women_tested is ugly and has never once been misread.| Design feature | Consequence for EDA |
|---|---|
| Stratification | Estimates must respect strata |
| Clustering (PSUs) | Observations within a village are correlated |
| Unequal selection probability | Raw sample proportions are not population ones |
| Non-response adjustment | Weights carry more than selection |
| Open the file and answer | Before you compute anything |
|---|---|
| What is one row? | Household, person, item, or birth |
| What is the key? | Which columns uniquely identify a row |
| Where is the weight? | And is it a household or person weight |
| What is the universe? | Who was asked this block at all |
| Which codes mean missing? | From the codebook, not by guessing |
| Step | Done when |
|---|---|
| Load | Row and column counts match the documentation |
| Inspect | Every column has a known type and range |
| Clean | Every recode is in a script, with a reason |
| Describe | No variable is unexamined |
| Visualise | Every continuous variable has been plotted once |
| Question | The open questions are written down |
| Load trap | Symptom |
|---|---|
| IDs read as numbers | Leading zeros gone; merges fail |
| Missing codes read as values | Mean age of 143 |
| Wrong encoding | Mojibake in state names |
| Fixed-width read with wrong layout | Every column shifted by one |
| Only the first file loaded | Half the sample missing, no error |
07 to 7, and the merge that then fails will fail quietly, dropping rows rather than erroring.| Question | What you are checking |
|---|---|
| How many rows & columns? | Size and whether the file is complete |
| What type is each column? | Numeric, text, date, categorical codes |
| What is the range of each? | Min, max, plausibility |
| How many distinct values? | Categorical levels, accidental duplicates |
| How many missing per column? | Where the gaps are |
| Inspect | Red flag |
|---|---|
| Row count | Suspiciously round, or half the documented total |
| Column types | A continuous variable stored as text |
| Min and max | Values outside anything possible |
| Distinct values | A "continuous" variable with six levels |
| Missing count | Zero missing on a question with a skip pattern |
| Never | Instead |
|---|---|
| Edit the raw file | Read it read-only; write a cleaned copy |
| Delete a suspicious row | Flag it and decide explicitly |
| Overwrite a variable | Create a new one and keep both |
| Recode silently | Comment the reason next to the line |
| Variable type | Describe with | Also report |
|---|---|---|
| Continuous, symmetric | Mean, SD | % missing |
| Continuous, skewed | Median, IQR | Min, max, % missing |
| Categorical | Frequency table | Levels with zero counts |
| Binary | Percentage | Denominator |
| Coded ID | Count of distinct values | Duplicates |
| Summary that hides it | Plot that shows it |
|---|---|
| Mean and SD | Bimodality — two peaks |
| Correlation | A curved or U-shaped relation |
| Median | A spike at a top-code |
| Range | Heaping on round numbers |
| Percent missing | Missingness concentrated in one region |
| Pattern noticed | Question it becomes |
|---|---|
| Consumption is bimodal in one state | Are two populations pooled here? |
| A variable is missing more for women | Is it a skip pattern or non-response? |
| One district is an outlier | Sample size, coding error, or real? |
| Two variables correlate strongly | Is one derived from the other? |
| Without the codebook you cannot know | So you cannot |
|---|---|
| What 9 means in this column | Compute any mean safely |
| Who was asked the question | State a denominator |
| The reference period | Compare with another survey |
| Which weight applies | Describe the population |
| Codebook field | Why EDA needs it |
|---|---|
| Variable label | What it actually measures |
| Value codes | 1 = yes, 2 = no, 9 = missing |
| Units | Rupees? months? per week? |
| Universe / who answers | Only women 15–49? only workers? |
| Reference period | Last 7 days? last 30? last year? |
| Skip patterns | Why a block is blank for some rows |
| Codebook field | Question it prevents |
|---|---|
| Universe | "Why is this 40% missing?" |
| Reference period | "Last week or last year?" |
| Units | "Rupees or hundreds of rupees?" |
| Value codes | "Is 2 higher or lower than 1?" |
| Level | Meaning | Survey example | Valid maths |
|---|---|---|---|
| Nominal | Labels, no order | Religion, state, ration-card type | Counts, mode |
| Ordinal | Ordered, unequal gaps | Education level, wealth quintile | Median, rank |
| Interval | Equal gaps, no true zero | Year of birth | Mean, difference |
| Ratio | Equal gaps, true zero | Age, income, consumption | All, ratios |
| Level | Common mistake |
|---|---|
| Nominal | Taking a mean of state codes |
| Ordinal | Treating quintile gaps as equal |
| Interval | Saying 20 degrees is twice 10 |
| Ratio | None inherent — but watch zeros |
| Looks continuous but is not | Why |
|---|---|
| State code | Nominal label stored as a number |
| Wealth quintile | Ordinal ranking, unequal gaps |
| Religion code | Nominal |
| Number of children | Genuinely a count — this one is fine |
| Education years vs level | One is continuous, one is ordinal |
| Column | What a mean of it would be |
|---|---|
| State code | A number between two states |
| Caste category code | Meaningless |
| Sex (1/2) | A rescaled sex ratio, by accident |
| District code | Nonsense with three decimal places |
| Code | Often means | Risk if treated as a value |
|---|---|---|
| 99 / 999 | Not known / not stated | Inflates the mean enormously |
| 97 / 98 | Refused / not applicable | Phantom category in tables |
| 0 | Sometimes a real zero, sometimes 'none' | Ambiguous — check codebook |
| Blank | Skip pattern or true missing | Silent loss of cases |
| Code | Typical meaning | What to do |
|---|---|---|
| 99 / 999 | Not known / not stated | Recode to missing |
| 97 / 98 | Refused / not applicable | Distinguish the two |
| 0 | Sometimes real, sometimes none | Check the codebook |
| Blank | Skipped or genuinely absent | Check the skip logic |
| Derived variable | Decision hiding inside it |
|---|---|
| MPCE | Which expenditure items count |
| Age group | Where the cut points fall |
| "Has toilet" | Whether shared facilities count |
| Poverty status | Which line, which year, which deflator |
| Household size | Whether visitors and absentees are members |
| Profile line | Example entry |
|---|---|
| Name and meaning | mpce_mrp — monthly per-capita consumption |
| Type and level | Continuous, ratio |
| Range / levels | 210 to 42,000 rupees |
| Missing codes | None; blanks are genuine |
| Universe | All sampled households |
| % missing | 0.4% |
| Variable type | First look | What you are hunting |
|---|---|---|
| Categorical | Frequency table | Unexpected levels, tiny cells |
| Binary | Percentage + denominator | A third category hiding as missing |
| Continuous | Histogram + five-number summary | Skew, spikes, impossible values |
| Date | Min and max | Dates outside fieldwork |
| ID | Count of distinct values | Duplicates |
| Sanitation facility | Households | % |
|---|---|---|
| Improved, not shared | 6,420 | 64.2 |
| Improved, shared | 1,180 | 11.8 |
| Unimproved | 910 | 9.1 |
| Open defecation | 1,390 | 13.9 |
| Not stated | 100 | 1.0 |
| Read the table for | What it reveals |
|---|---|
| A level with a tiny count | Too small to report separately |
| A level that should not exist | A coding or entry error |
| "Not stated" size | How much of the denominator is unusable |
| A missing level | A category with zero cases — say so |
| Feature | Likely cause |
|---|---|
| Two peaks | Two populations pooled (rural / urban) |
| Spike at a round number | Heaping — respondents rounding ages or amounts |
| Wall at the maximum | Top-coding |
| Spike at zero | "None" coded as 0 alongside real zeros |
| Gap in the middle | A filter or a recode error |
| Density plot | Histogram |
|---|---|
| Smooth, easy to overlay groups | Honest about the actual counts |
| Bandwidth is a choice | Bin width is a choice |
| Can show mass below zero | Cannot invent impossible values |
| Good for comparison | Good for spotting spikes and gaps |
| Statistic | Robust to outliers? | Use when |
|---|---|---|
| Mean | No | Roughly symmetric, no extreme tail |
| Median | Yes | Skewed money variables |
| SD | No | Alongside a mean, symmetric data |
| IQR | Yes | Alongside a median |
| Min / max | They are the outliers | Always, as a sanity check |
| Shape | Mean vs median | Report |
|---|---|---|
| Right-skewed | Mean > median | Median, and say it is skewed |
| Left-skewed | Mean < median | Median |
| Symmetric | Roughly equal | Either; mean is fine |
| Bimodal | Both mislead | Split the groups and describe each |
| Log scale helps | Log scale hurts |
|---|---|
| Money spread over orders of magnitude | Variables with true zeros |
| Seeing the low end of a squashed range | Audiences who read the axis as linear |
| Making a multiplicative pattern look linear | When absolute differences are the point |
| Problem | Survey example | How EDA spots it |
|---|---|---|
| Missing values | Income blank for some | Count of NA per variable |
| Impossible values | Age = 230, −3 children | Min/max range check |
| Special codes as data | 99 = 'not stated' | Spike at 99 in histogram |
| Top-coding | Income capped at a max | Wall of cases at the ceiling |
| Heaping | Ages bunched at 0, 5, 10 | Comb pattern in histogram |
| Duplicates | Same HH twice | Duplicate household IDs |
| Problem | Cheapest detector |
|---|---|
| Missing values | Count of NA by column |
| Impossible values | Min / max table |
| Codes read as data | Histogram — look for a lone far spike |
| Duplicates | Count of rows vs count of distinct keys |
| Heaping | Frequency of the last digit |
| Top-coding | Frequency of the maximum value |
| Mechanism | Effect on your estimate | What helps |
|---|---|---|
| Skip / not applicable | None — adjust the denominator | Read the skip logic |
| Missing completely at random | Loss of precision only | Nothing much needed |
| Missing at random | Bias unless you condition | Condition on the observed cause |
| Missing not at random | Bias you cannot remove from the data | Bound it; say so |
| Cross-tabulate missingness against | Question it answers |
|---|---|
| Sector (rural / urban) | Is one setting harder to survey? |
| Sex of respondent | Is a module reaching women less well? |
| State | Is it a fieldwork problem in one place? |
| Wealth quintile | Is refusal concentrated at the top? |
| Interviewer or PSU | Is it one team rather than the population? |
| Before deciding | Check |
|---|---|
| Is it possible at all? | Range and logic rules |
| Is it a code? | The codebook, again |
| Is it one record or many? | A cluster of extremes is a pattern |
| Does it change the conclusion? | Run it with and without |
| Rule | Good at | Fails when |
|---|---|---|
| Range check | Impossible values | The value is possible but wrong |
| IQR rule | Symmetric-ish data | Skewed money — flags the whole tail |
| SD rule (±3) | Normal data | Skew or heavy tails |
| Logic check | Internal contradictions | Needs you to write the rules |
| Visual | Anything unexpected | Large n, where the eye gives out |
| Rule | Violation to flag |
|---|---|
| Age between 0 and ~110 | Age = 230, age = −1 |
| Percentages in 0–100 | Vaccination = 140% |
| Members ≥ earners | 8 earners in a 4-person household |
| Mother older than child | Mother 14, child 10 |
| Consumption > 0 | MPCE = 0 with members present |
| Rule family | Example |
|---|---|
| Range | 0 <= age <= 110 |
| Sum | Members >= earners |
| Relational | Mother at least 12 years older than child |
| Conditional | Pregnancy variables only for women |
| Cross-file | Every member row has a household row |
| Top-coding does | So you cannot |
|---|---|
| Caps the highest values | Compute a true mean |
| Creates a spike at the ceiling | Trust the SD or the range |
| Protects respondent privacy | Recover the real tail |
| Varies between surveys and rounds | Compare tails across sources naively |
| Pair | Tool | Summary |
|---|---|---|
| Categorical x categorical | Cross-tab | Row or column % |
| Categorical x continuous | Grouped medians, box plots | Median by group |
| Continuous x continuous | Scatter | Correlation, with caution |
| Any pair x a third | Faceting, colour | Same plot, split |
| Sector | Has toilet | No toilet | % with toilet |
|---|---|---|---|
| Rural | 5,180 | 2,020 | 71.9 |
| Urban | 2,610 | 190 | 93.2 |
| All | 7,790 | 2,210 | 77.9 |
| Cross-tab decision | Consequence |
|---|---|
| Which variable in rows | Determines the natural comparison |
| Row or column % | Two different questions |
| Include "not stated"? | Changes every percentage |
| Weighted or not | Sample vs population |
| Cell counts shown? | Whether the reader can judge precision |
| You want to say | Percentage direction |
|---|---|
| "Of rural households, 72% have a toilet" | Row % (rows = sector) |
| "Of households with toilets, 33% are urban" | Column % |
| "Rural households are 72% of the sample" | Neither — marginal % |
| r does not tell you | Why |
|---|---|
| The slope | r is scale-free; the slope is not |
| Whether it is causal | It never did |
| Whether the relation is curved | It measures straight lines only |
| Whether one point drives it | A single outlier can create or destroy r |
| Whether it holds in subgroups | It is a pooled number |
| Heatmap use | Heatmap misuse |
|---|---|
| Spotting variable clusters fast | Reading it as a causal structure |
| Finding near-duplicate variables | Picking predictors by highest r |
| Sanity-checking derived variables | Reporting the strongest cell as a finding |
| Split by | Because |
|---|---|
| Rural / urban | The largest single divide in most Indian data |
| State | Policy, prices and baselines differ enormously |
| Wealth quintile | Most outcomes gradient sharply |
| Sex | Many outcomes and many gaps are gendered |
| Social group | Persistent structural differences |
| Unweighted gives you | Weighted gives you |
|---|---|
| A description of the sample | An estimate for the population |
| Useful for finding data errors | Useful for any published number |
| No design assumptions | Correct selection and non-response adjustment |
| Weight type | Applies to | Use for |
|---|---|---|
| Household weight | Household records | Household-level estimates |
| Person / member weight | Member records | Population-level rates |
| Woman weight | Women's questionnaire | Fertility, anthropometry |
| Child weight | Child records | Stunting, immunisation |
| Over-sampled because | Consequence |
|---|---|
| Small states need usable estimates | They are over-represented in the raw file |
| Urban slums are policy-relevant | Raw urban share exceeds the true one |
| A minority group is of interest | Their raw share is inflated |
| Response rates differ | Weights carry that adjustment too |
| DEFF value | Reading |
|---|---|
| 1.0 | As good as a simple random sample |
| 1.5-2.5 | Typical for a clustered household survey |
| > 4 | Strong clustering — check the estimate carefully |
| Varies by variable | Normal: DEFF is per estimate, not per survey |
| Task | Tool that handles design |
|---|---|
| R | survey, srvyr |
| Python | samplics, statsmodels (partial) |
| Stata | svyset then svy: prefix |
| SPSS | Complex Samples module |
| Survey designed for | Do not claim |
|---|---|
| State-level estimates | A district figure |
| District-level (NFHS) | A block or village figure |
| National totals | A small-group rate |
| Rural and urban separately | A single combined rate without weighting |
| The eye catches | A table hides |
|---|---|
| Skew and long tails | Behind a mean |
| Two populations | Behind a single average |
| A curved relation | Behind a correlation of 0.1 |
| A spike at a code | Behind a plausible range |
| Clustering of gaps | Behind a total missing count |
| Small multiples work when | They fail when |
|---|---|
| The scales are shared | Each panel is auto-scaled |
| Panels are ordered meaningfully | Panels are alphabetical by accident |
| There are 4-30 panels | There are 200 |
| The shape is the message | A precise value is the message |
| Facet by | Reveals |
|---|---|
| Sector | Whether a pattern is urban only |
| State | Where the aggregate comes from |
| Sex | Gendered differences in shape, not just level |
| Wealth quintile | Gradients and their direction |
| Survey round | Change over time, and comparability breaks |
| Box plot shows | Box plot hides |
|---|---|
| Median, quartiles, spread | Bimodality |
| Outliers as individual points | The number of observations |
| Group comparisons at a glance | The shape between the quartiles |
| Fix | Trade-off |
|---|---|
| Transparency (alpha) | Still saturates at very high n |
| Smaller points | Harder to see isolated cases |
| Random sample of rows | Rare combinations may vanish |
| 2-D binning / hexbin | Individual outliers disappear |
| Contours | Reads as a model, not the data |
| Check | Failing looks like |
|---|---|
| Chart matches variable type | A bar chart of a continuous variable |
| Baseline honest | A 4-point rise that looks like a doubling |
| Axes labelled with units | "Amount" on the y-axis |
| Log scale considered for money | Ninety per cent of points in one corner |
| Weighted if it describes people | A sample picture read as a national one |
| n stated | A percentage with no denominator |
| EDA produces | Testing requires |
|---|---|
| A pattern noticed in this data | A hypothesis fixed in advance |
| Many comparisons, informally | A stated comparison, and correction |
| A plausible mechanism | A design that can distinguish mechanisms |
| A shortlist worth funding | Ideally fresh or held-out data |
| Legitimate EDA claim | Phrase it as |
|---|---|
| A distribution | "Median MPCE in the sample was..." |
| A data-quality problem | "Income is missing for 18%, concentrated in..." |
| A group comparison | "Weighted median differs by X between..." |
| A suggested relationship | "This pattern would be worth testing" |
| Cannot conclude | Because |
|---|---|
| X causes Y | Nothing here rules out confounding or reverse causation |
| This effect is significant | The hypothesis came from the data |
| This holds in village Z | Below the design resolution |
| The relation is linear | Only if you plotted it and it was |
| Slices tried | Chance of one striking result |
|---|---|
| 1 | About 5% at the usual threshold |
| 5 | About 23% |
| 20 | About 64% |
| 50 | About 92% |
| Record with every finding | Example |
|---|---|
| Unit and denominator | Women 15-49 who were tested |
| Weighted? | Yes, person weights |
| Level it holds at | State, not district |
| Data-quality caveats | 12% missing, concentrated in two states |
| Explored or tested | Exploratory — not yet tested |
| Instead of | Say |
|---|---|
| "Mean MPCE is 3,240" | "Half of households spend less than 2,700 per head" |
| "18% missing" | "Nearly one in five gave no income figure, mostly the better off" |
| "r = 0.62" | "States with higher female literacy tend to have lower fertility" |
| "DEFF = 2" | "This sample is about as informative as 5,000 independent households" |
| Tool | Good for | Note |
|---|---|---|
| R + tidyverse | Cleaning, plotting, reproducible analysis | Free; survey & srvyr packages handle weights |
| Python + pandas | Cleaning, large data, automation | Free; samplics / statsmodels for survey design |
| Stata | Standard for official microdata | svyset built-in for weights & design; widely used |
| Spreadsheets | Quick first look, small tables | Fine to start; not for weighted survey estimates |
| Tool | Weights | Learning cost |
|---|---|---|
| R + tidyverse + srvyr | Full survey support | Moderate |
| Python + pandas | Partial; samplics for design | Moderate |
| Stata | Excellent (svyset) | Licence cost |
| SPSS | Complex Samples module | Licence cost |
| Spreadsheet | None | Low — and unreproducible |
| Question a reviewer asks | Script answers it |
|---|---|
| "Where did this number come from?" | A line in a file |
| "What did you exclude?" | The filter, with its reason |
| "Can you redo it for 2019?" | Change one path |
| "Why did this change?" | The diff |
| Source | You get | Note |
|---|---|---|
| microdata.gov.in | NSS, PLFS unit-level data | Registration; codebooks alongside |
| dhsprogram.com | NFHS / DHS files | Free on request, per-survey approval |
| data.gov.in | Aggregated open data | Rarely unit level |
| censusindia.gov.in | Census tables | Tables, not microdata |