One NHANES dataset, four variance machines, and exactly what the naive standard error quietly gets wrong.
This is the empirical companion to a conceptual note, “Weights get the point estimate right; the design gets the uncertainty right.” That note made three claims. Here we put all three on real data — the National Health and Nutrition Examination Survey (NHANES) — and hold every claim to an explicit numerical gate. The setting is deliberately mundane: the association between family income and depression. The point is not the finding; it is that one number can carry three or four different standard errors depending on which variance machinery you turn on — while the estimate itself never moves.
Concretely, we test that (1) point estimates are invariant to the variance machinery — a weighted mean and a weighted regression coefficient are numerically identical whether computed naively, with fixest and clustering, or with the full survey/srvyr design; (2) fixest with weights + clustering at the PSU recovers most of the design-based standard error; and (3) naive standard errors are materially anti-conservative, by an amount we quantify.
NHANES is a stratified, multistage cluster sample. Respondents are nested in primary sampling units (PSUs, roughly counties), PSUs are nested in strata, and each respondent carries a MEC examination weight that scales the sample up to the U.S. population.1 Pooling the eight PHQ-9 cycles from 2005–2023 and restricting to adults aged 20–80 with a valid income-to-poverty ratio gives an analytic domain of 42,463 respondents, spread over 129 strata and 263 PSUs (2–3 PSUs per stratum, median 2). The weights are far from equal — their coefficient of variation is 0.90, a Kish weighting design effect of $1+\mathrm{CV}(w)^2 = 1.80$ before a single cluster is considered.
1. Pooled MEC weight: each cycle’s 2-year weight (the 3.2-yearWTMECPRP for the combined 2017–March 2020 file) is multiplied by its share of the 17.2 pooled analytic years, per CDC’s NHANES weighting guidance. Point estimates and design-based SEs are both invariant to a common rescaling of the weights.
The key move is to declare the design once and read four different standard errors off the same estimate. We line up four variance regimes, from the one that knows nothing about the design to the one that knows everything:
| Regime | weights | heterosk. | clustering (PSU) | stratification |
|---|---|---|---|---|
| V0 naive iid | ✓ | ✗ | ✗ | ✗ |
| V1 hetero-robust (HC1) | ✓ | ✓ | ✗ | ✗ |
| V2 cluster @ PSU | ✓ | ✓ | ✓ | ✗ |
| V3 full survey design | ✓ | ✓ | ✓ | ✓ |
V0 is what you get by bolting a textbook standard error onto a weighted group-by. V1 adds White heteroskedasticity-robust corrections. V2 clusters at the PSU — the econometrician’s rendering of the design. V3 is the full Taylor-linearized survey estimator, which additionally nets out the between-stratum variation and uses the design-correct degrees of freedom.2 Two families of estimand run through all four: Family A, weighted prevalences of probable major depression (PHQ-9 ≥ 10), overall and by income and age; and Family B, regressions whose headline coefficient is the Low–High income gap.
2. The design degrees of freedom are $\text{n}_{\text{PSU}} - \text{n}_{\text{strata}} = 263 - 129 = 134$. Note the gulf: 42,463 respondents but only 134 design df. The number of PSUs, not the number of people, governs the precision of the tails.Start with the claim that should be boring and is worth making undeniable. A sampling weight fixes who is in the sample; it is the inverse probability of selection, and it enters every estimator as a simple ratio $\hat{\bar Y} = \sum_i w_i y_i / \sum_i w_i$. Nothing about strata or PSUs appears in that formula. So the same number falls out of a naive weighted mean, a fixest weighted regression, and srvyr’s survey_mean() — to the last decimal.3
| Quantity | Naive weighted (V0) | fixest + cluster (V2) | Survey design (V3) |
|---|---|---|---|
| A1 · P(PHQ-9 ≥ 10), overall | 0.0834223623 | 0.0834223623 | 0.0834223623 |
| B1 · Low–High gap (LPM β) | 0.1190594408 | 0.1190594408 | 0.1190594408 |
Across all 42,463-respondent prevalence cells, the closed-form weighted mean and srvyr’s design-based mean agree to max |V0 − V3| = 0.0e+00. For the regressions, feols/feglm and svyglm return the same coefficient vector to 3.3e-14 (linear probability model), 1.8e-12 (linear score), and 1.3e-12 (logit — different IRLS paths, same maximum). Every estimand in the study, plotted below, sits on the 45° line to within 1.8e-12.
The verbatim gate log:
[PASS] POINT-A: srvyr means == closed-form weighted means -- max|V0-V3| = 0.000e+00 over 22 cells [PASS] POINT-B1: feols == svyglm (LPM) -- max|dcoef| = 3.331e-14 [PASS] POINT-B3: feols == svyglm (linear) -- max|dcoef| = 1.805e-12 [PASS] POINT-B2: feglm == svyglm (logit) -- max|dcoef| = 1.258e-12 [PASS] SANITY-DEFF: A1 implied DEFF (se_V3/se_V0)^2 in [1.2,6] -- implied = 1.470 ; srvyr deff = 2.409
Now turn on the variance machines one at a time and watch the confidence interval breathe while the point stays pinned. Figure 2 is the thesis in one frame: a single vertical line for the shared coefficient, four stacked intervals of visibly different width.
For that headline gap, the naive standard error is 0.00380 against a design-based 0.00550. The naive interval is 32% too narrow — the honest interval is 1.46× wider — and the t-statistic on the income gap falls from a swaggering 31.4 to a still-decisive 21.6. Here the association is strong enough to survive; for a marginal subgroup contrast, that same factor is the difference between a star and a shrug.
| Variance regime | SE | df | 95% CI width | t | SE / design |
|---|---|---|---|---|---|
| V0 · naive iid | 0.00380 | 38,232 | 0.0149 | 31.4 | 0.69 |
| V1 · hetero-robust (HC1) | 0.00513 | 38,232 | 0.0201 | 23.2 | 0.93 |
| V2 · cluster @ PSU | 0.00579 | 262 | 0.0228 | 20.6 | 1.05 |
| V3 · full survey design | 0.00550 | 134 | 0.0218 | 21.6 | 1.00 |
| Variance regime | SE | df | 95% CI width | t | SE / design |
|---|---|---|---|---|---|
| V0 · naive iid | 0.04992 | 38,232 | 0.1957 | 29.5 | 0.74 |
| V1 · hetero-robust (HC1) | 0.06865 | 38,232 | 0.2691 | 21.4 | 1.02 |
| V2 · cluster @ PSU | 0.07444 | 262 | 0.2931 | 19.8 | 1.11 |
| V3 · full survey design | 0.06707 | 134 | 0.2653 | 21.9 | 1.00 |
| Variance regime | SE | df | 95% CI width | t | SE / design |
|---|---|---|---|---|---|
| V0 · naive iid | 0.05612 | 38,232 | 0.2200 | 38.6 | 0.74 |
| V1 · hetero-robust (HC1) | 0.07283 | 38,232 | 0.2855 | 29.7 | 0.96 |
| V2 · cluster @ PSU | 0.08598 | 262 | 0.3386 | 25.2 | 1.13 |
| V3 · full survey design | 0.07616 | 134 | 0.3013 | 28.4 | 1.00 |
Two structural details earn the tables their credibility. First, the tolerance the logit demanded: feglm and svyglm travel different IRLS routes, so we tightened both to deviance tolerances near $10^{-11}$ to make the coefficients agree past the eighth decimal. Second, and more consequential, the naive iid SE for the logit is only meaningful once the weights are normalized to mean 1.4
The good news for practitioners who live in fixest: you do not need the full survey apparatus to get an honest standard error. Weighting and clustering at the PSU — vcov = ~psu_uid — lands within a few percent of the design. Figure 3 shows every shortcut’s SE as a ratio to the design-based truth.
For the three regression coefficients the cluster-robust SE is 1.05×, 1.11×, and 1.13× the design SE — slightly conservative, which is the safe direction to err. What still separates V2 from V3 decomposes into three pieces. (i) Stratification is a precision gain the cluster-robust estimator leaves on the table: guaranteeing balanced coverage of every region×urbanicity cell removes a whole dimension of sampling noise, so V3 sits just below V2. (ii) Degrees of freedom differ — fixest uses $n_{\text{cluster}}-1 = 262$, the survey estimator uses design df = 134, and the naive regimes pretend they have 38,232. (iii) Random domain size: for subgroup means the survey machinery keeps a component that an intercept-only regression within the subgroup drops.5
SDMVPSU, which takes values 1–3 and recycles across strata. That would collapse 42,463 respondents into three fake mega-clusters. Always cluster on a globally-unique psu_uid = interaction(stratum, psu) — here 263 genuine PSUs.
The same story reads off the plain overall prevalence. Its design effect is a substantial 2.41 against a simple random sample of the same size:
| Variance regime | Estimate | SE | df | DEFF (srvyr) |
|---|---|---|---|---|
| V0 · naive iid | 0.0834 | 0.00181 | 38,245 | — |
| V2 · cluster @ PSU | 0.0834 | 0.00246 | 262 | — |
| V3 · full survey design | 0.0834 | 0.00219 | 134 | 2.41 |
Notice that not every naive SE errs downward. For the highest-income group the design SE is actually smaller than the naive iid SE — there, stratification’s precision gain outweighs clustering’s penalty.6 The design does not merely inflate; it corrects in whichever direction the sampling scheme demands.
6. This is visible in Figure 3: the High-income prevalence cell’s naive point sits to the right of 1.0. Ignoring strata is conservative on this margin; you would be understating your own precision.Clustering’s deepest practical consequence is that a big survey buys a much smaller effective sample. Positively correlated observations within a PSU carry less information than their headcount suggests, so the design-effective $n$ is $n/\text{DEFF}$. Across the 18 income×age prevalence cells, design effects run from 1.22 to 2.51 (median 1.67).
This is why some income×age contrasts are noisier than their raw counts promise, and why power calculations for subgroup comparisons should use $n/\text{DEFF}$, not $n$. It also produces an honest wrinkle worth reporting rather than hiding: in 8 of the fine age×income cells the cluster-robust SE actually comes in below the naive one — a near-zero or slightly negative within-PSU correlation at that granularity. The design effect is an average tendency, not a law that binds every cell.
fixest, weight and cluster at the PSU. That recovers the SE to within a few percent (here 1.05–1.13× the design) — erring slightly conservative. Cluster on a globally-unique psu_uid, never raw SDMVPSU.svyglm/survey_mean get right and the shortcuts do not.The one-paragraph version: weights answer “who does each observation represent?” and so fully determine the estimate; standard errors answer “how would this estimate move across repeated draws of the same design?” and depend on features weights do not encode. Declaring the design once fixes the second question without touching the first.
Estimands. Family A: weighted prevalence of PHQ-9 ≥ 10, overall (A1), by income (A2), and by income×age group (A3). Family B, all with the right-hand side Income + Sex + factor(CycleShort) + poly(Age, 3) and income releveled so High is the reference: B1 linear probability model for PHQ-9 ≥ 10, B2 logistic regression, B3 linear model for the PHQ-9 total score. The headline coefficient is IncomeLow, the Low–High gap.
The V0 standard error of a weighted mean is the iid linearization with normalized weights $\tilde w_i = w_i/\sum_j w_j$: $\;\widehat{\mathrm{SE}} = \sqrt{\sum_i \tilde w_i^{\,2}\,(y_i-\hat{\bar y})^2}\,$. It knows nothing about strata or PSUs. The V2 cluster-robust mean is fit as a weighted intercept-only regression with vcov = ~psu_uid, so Families A and B share the same machinery.
$\text{MEC\_wt} = \text{MEC\_wt}_{\text{raw}} \times (\text{years}/17.2)$, with WTMECPRP for the combined 2017–March 2020 file and WTMEC2YR otherwise; 17.2 = total pooled analytic years across the eight cycles. Design declared on the full file (all rows with positive weight, 81,820) and subset afterwards, per CDC practice for domain variance.
R 4.5.1 · fixest 0.13.2 · survey 4.5 · srvyr 1.3.1 · arrow 21.0.0.1. options(survey.lonely.psu = "adjust"); nest = TRUE in as_survey_design. Every fixest call sets vcov explicitly. Run July 7, 2026.
=== SE-compare assertion log ===
design df (n_PSU - n_strata) = 134
[PASS] POINT-A: srvyr means == closed-form weighted means -- max|V0-V3| = 0.000e+00 over 22 cells
[PASS] POINT-B1: feols == svyglm (LPM) -- max|dcoef| = 3.331e-14
[PASS] POINT-B3: feols == svyglm (linear) -- max|dcoef| = 1.805e-12
[PASS] POINT-B2: feglm == svyglm (logit) -- max|dcoef| = 1.258e-12
[INFO] ORDER se_V0<=se_V2: 8 of 25 cells violate (negative-ICC domains; reported not failed)
violating cells: A3/Low:50-59, A3/Low:60-69, A3/Low:70-80, A3/Middle:40-49, A3/Middle:50-59, A3/High:20-29, A3/High:40-49, A3/High:50-59
[PASS] CLUSTER-B1: se_V2/se_V3 in [0.85,1.15] -- ratio = 1.052
[PASS] CLUSTER-B2: se_V2/se_V3 in [0.85,1.15] -- ratio = 1.110
[PASS] CLUSTER-B3: se_V2/se_V3 in [0.85,1.15] -- ratio = 1.129
[PASS] SANITY-DEFF: A1 implied DEFF (se_V3/se_V0)^2 in [1.2,6] -- implied = 1.470 ; srvyr deff = 2.409
TOTAL FAILS: 0
@book{lumley2010complex,
title = {Complex Surveys: A Guide to Analysis Using R},
author = {Lumley, Thomas}, publisher = {Wiley}, year = {2010}}
@article{cameron2015practitioner,
title = {A Practitioner's Guide to Cluster-Robust Inference},
author = {Cameron, A. Colin and Miller, Douglas L.},
journal = {Journal of Human Resources}, volume = {50}, number = {2},
pages = {317--372}, year = {2015}}
@article{moulton1990illustration,
title = {An Illustration of a Pitfall in Estimating the Effects of Aggregate Variables on Micro Units},
author = {Moulton, Brent R.},
journal = {Review of Economics and Statistics}, volume = {72}, number = {2},
pages = {334--338}, year = {1990}}
@article{bdm2004,
title = {How Much Should We Trust Differences-in-Differences Estimates?},
author = {Bertrand, Marianne and Duflo, Esther and Mullainathan, Sendhil},
journal = {Quarterly Journal of Economics}, volume = {119}, number = {1},
pages = {249--275}, year = {2004}}
Generated programmatically from results_master.csv; every statistic in this article is injected from the pipeline output, none hand-typed.