Public databases / Epidemiology

How to Use the NHANES Database: From Data Download to Weighted Cox Regression and RCS

Many NHANES tutorials stop after downloading and merging files. This page uses official raw data from ten cycles (1999–2018) to run a full analysis of the TyG index and mortality: download, mortality linkage, weight combination, weighted Cox regression, RCS curves, subgroups and sensitivity analyses. Every number comes from one real run.

The data on this page come from one complete Scientify run: it downloaded 100 official files and ran every analysis in about 1.5 hours, then passed an independent review. See the run record

Short answer

NHANES is the US National Health and Nutrition Examination Survey, released every two years by NCHS at CDC. The data are free, and the official entry point is wwwn.cdc.gov/nchs/nhanes. A mortality study takes five steps: download each cycle's XPT files and merge on SEQN; link the NCHS public-use mortality file; choose the weight for your subsample and combine cycles; fit weighted Cox and RCS models with the survey package; finish with subgroup and sensitivity analyses. This example includes 22,894 adults with 3,686 all-cause deaths.

About this page

Tutorial
What this page solves
You want to write an association study with NHANES but are unsure where to download files, which weight to use, how to link mortality, and how to run Cox and RCS models correctly.
Who it is for
Medical graduate students and clinicians working with public databases. You should know R and the basics of Cox regression.
What you will have
A complete NHANES mortality workflow, what each step should produce, and a real set of results to compare against.
Covers
  • Download paths and variable lookup for official NHANES files
  • Parsing the fixed-width NCHS mortality file and defining cardiovascular death
  • Choosing fasting subsample weights and multi-cycle factors
  • The TyG formula and unit conversion
  • Survey-weighted Cox regression, RCS curves and weighted Kaplan-Meier curves
  • Subgroup interactions, proportional hazards checks and sensitivity analyses, with real results
Does not cover
  • Two-day dietary weights for 24-hour recalls
  • Causal inference methods such as Mendelian randomization
  • Writing the introduction and discussion

Main path: step by step

Step 1

Why this stepEach module in each NHANES cycle is a separate XPT file, so first decide which files you need.

The official entry point is wwwn.cdc.gov/nchs/nhanes. Data are released in two-year cycles since 1999, and each cycle has five module groups: demographics, dietary, examination, laboratory and questionnaire, each with several XPT files. Choose a cycle and a module on the site to see the file list and variable documentation (Doc File).

NHANES is run by NCHS, part of the US CDC. Since 1999 it has been released in two-year cycles, free of charge. File names carry a letter suffix per cycle: none for 1999–2000, _B for 2001–2002, through _J for 2017–2018. All files merge on the participant ID SEQN.

This example downloaded 100 official files across ten cycles. CDC has changed its download paths: the old path /Nchs/Nhanes/2017-2018/DEMO_J.XPT now returns an HTML 404 page. Use the new path, and check the start of each file to confirm it is XPT data rather than an error page.

Current download URL patterntext
https://wwwn.cdc.gov/Nchs/Data/Nhanes/Public/2017/DataFiles/DEMO_J.xpt
# the year is the first year of the cycle; the file name carries the cycle suffix
Reading XPT files in Rr
library(haven)
demo <- read_xpt("DEMO_J.xpt")
glu  <- read_xpt("GLU_J.xpt")
trig <- read_xpt("TRIGLY_J.xpt")
d <- Reduce(function(x, y) merge(x, y, by = "SEQN", all.x = TRUE), list(demo, glu, trig))
CycleDemographicsFasting glucoseTriglycerides
1999–2000DEMOLAB10AMLAB13AM
2001–2002DEMO_BL10AM_BL13AM_B
2003–2004DEMO_CL10AM_CL13AM_C
2005–2006DEMO_DGLU_DTRIGLY_D
2007–2018DEMO_E … DEMO_JGLU_E … GLU_JTRIGLY_E … TRIGLY_J
Laboratory file names differ in the first three cycles. The variables are LBXGLU (glucose, mg/dL) and LBXTR (triglycerides, mg/dL) throughout. Check variable names per cycle instead of guessing from file names.

Step 2

Why this stepMortality outcomes come from public files that NCHS releases after linking NHANES to the National Death Index (NDI).

This example uses the 2019 public-use linked mortality files, one .dat file per cycle. They are fixed-width and must be read with the column positions from the official NCHS read program, not as CSV.

Cardiovascular death is UCOD_LEADING equal to 001 (heart disease) or 005 (cerebrovascular disease). Follow-up time is PERMTH_EXM, months from the examination to death or the end of follow-up. Check cause-of-death code frequencies and the follow-up range after reading.

Download URLtext
https://ftp.cdc.gov/pub/Health_Statistics/NCHS/datalinkage/linked_mortality/NHANES_2017_2018_MORT_2019_PUBLIC.dat
VariableColumnsMeaning
SEQN1–6Participant ID
ELIGSTAT15Linkage eligibility, 1 = eligible
MORTSTAT16Vital status, 1 = deceased
UCOD_LEADING17–19Leading underlying cause of death
PERMTH_INT43–45Months of follow-up from interview
PERMTH_EXM46–48Months of follow-up from examination
Python slices are half-open, so SEQN is line[0:6].

Step 3

Why this stepNHANES is a complex survey. Unweighted results describe the sample, not the US population.

The rule is that the variable from the smallest subsample determines the weight. Fasting glucose and triglycerides are measured only in the morning fasting subsample, so a TyG study must use the fasting weight (WTSAF2YR, or WTSAF4YR for 1999–2002), not the examination weight WTMEC2YR.

When combining cycles, multiply each cycle's weight by its years over the total years. Here 20 years are combined: the four-year 1999–2002 weight is multiplied by 4/20 and each two-year weight from 2003 onward by 2/20. The design variables SDMVPSU (PSU) and SDMVSTRA (stratum) are in the DEMO files.

Building the survey design (example code)r
library(survey)
d$wt20 <- ifelse(d$cycle %in% c("1999-2000", "2001-2002"),
                 d$WTSAF4YR * 4 / 20,
                 d$WTSAF2YR * 2 / 20)
options(survey.lonely.psu = "adjust")
des <- svydesign(ids = ~SDMVPSU, strata = ~SDMVSTRA,
                 weights = ~wt20, nest = TRUE, data = d)
# build the design on the full sample, then subset(); do not drop rows first
des_a <- subset(des, analysis_flag == 1)

Step 4

Why this stepDefine the exposure and the final analysis sample.

NHANES LBXTR and LBXGLU are already in mg/dL; use them directly without converting again. Inclusion criteria: age ≥20, not pregnant, positive fasting glucose and triglycerides, fasting weight above 0, eligible for mortality linkage, and follow-up after the examination above 0.

TyG indextext
TyG = ln[ TG (mg/dL) × FPG (mg/dL) / 2 ]

# if values are in mmol/L, convert first: TG × 88.57, glucose × 18.018
NHANES 1999–2018 participant flow chart from 101,316 to 22,894
Participant flow (labels in Chinese). Missing fasting laboratory values is the largest exclusion (30,601); 22,894 participants are included.

Step 5

Why this stepEstimate how mortality risk changes per one-unit increase in TyG.

After full adjustment the linear HR confidence interval crosses 1. A non-significant linear term does not mean no association, so the next step checks for a nonlinear relationship with RCS. When the 95% CI crosses 1, do not claim a statistical association.

Weighted Cox regression (model 3, example code)r
fit <- svycoxph(Surv(PERMTH_EXM, MORTSTAT) ~ tyg + age + sex + race +
                  edu + pir + smoke + bmi + diabetes + hypertension +
                  cvd + cancer, design = des_a)
summary(fit)
OutcomeModel 3: HR per 1 unit TyG (95% CI)
All-cause mortality1.03 (0.95–1.12)
Cardiovascular mortality1.10 (0.93–1.29)
Model 1 is unadjusted; model 2 adjusts for age, sex and race; model 3 adds education, PIR, smoking, BMI, diabetes, hypertension, cardiovascular history and cancer. TyG quartiles were also analyzed with Q1 as reference.

Step 6

Why this stepRCS does not assume linearity and tests whether the exposure–outcome relationship is curved.

This example uses 4 knots in the weighted Cox model at the 5th, 35th, 65th and 95th weighted percentiles of TyG (7.63, 8.33, 8.82, 9.76), with the weighted median 8.57 as reference. RCS gives two P values: the overall P tests any association, and the nonlinear P tests departure from a straight line.

For all-cause mortality the overall P is 0.0096 and the nonlinear P is 0.0090. The curve is U-shaped with its lowest point near TyG 9.0. For cardiovascular mortality the nonlinear P is 0.025.

Weighted RCS curve of TyG and all-cause mortality, U-shaped with a minimum near 9.0
All-cause RCS curve (fully adjusted). Solid line is the HR, grey band the 95% CI, dashed line HR = 1.
Weighted RCS curve of TyG and cardiovascular mortality
Cardiovascular RCS curve, nonlinear P = 0.025.

Step 7

Why this stepCox models assume the HR does not change over time, which needs checking. KM curves show survival by group.

Calling cox.zph directly on an svycoxph fit gives P values near 1. This is an artefact of the weight scale and the test should not be used. Here follow-up was split into 0–60, 60–120 and >120 months, and a TyG × period interaction was tested with a design-based Wald test: P = 0.034 for all-cause mortality, which suggests non-proportional hazards, so period-specific HRs are also reported; P = 0.49 for cardiovascular mortality.

Weighted KM curves by TyG quartile use survey::svykm, with group comparison by survey::svylogrank. Curves labeled as weighted must be weighted estimates.

Weighted Kaplan-Meier survival curves for all-cause mortality by TyG quartile
Weighted KM curves by TyG quartile (all-cause mortality).

Step 8

Why this stepTest whether the TyG–mortality association differs across populations.

Seven subgroups were prespecified: age (<60 / ≥60), sex, race, BMI, diabetes, hypertension and cardiovascular history. Each stratum reports HR, 95% CI, participants and events, with an interaction P value. Only the age interaction was significant (P < 0.001): HR 1.14 (0.95–1.37) under 60 and 0.95 (0.87–1.05) at 60 or older.

Judge subgroup differences by the interaction P value, not by one stratum being significant and another not. Here the non-Hispanic Black stratum has HR 1.24 (1.04–1.48), but the race interaction P is 0.378, so it is wrong to say TyG matters only in that group. Subgroup tests were not corrected for multiple comparisons and are exploratory.

Subgroup forest plot of TyG and all-cause mortality with HR, sample size, events and interaction P values for seven subgroups
All-cause mortality subgroup forest plot, adjusted HR per 1 unit TyG.

Step 9

Why this stepCheck whether the main conclusion holds under other reasonable choices.

AnalysisPurpose
Exclude deaths in the first 2 yearsReduce reverse causation from baseline illness
Exclude baseline cardiovascular disease and cancerReduce the influence of existing disease
Multiple imputation (m = 5, 10 iterations)Handle missing covariates; outcome, follow-up, exposure, weights and strata enter the imputation model, pooled with Rubin's rules
Unweighted CoxShow the effect of weighting
Each sensitivity analysis lists sample size, events, model specification and HR.

Concepts and judgment

Comparison

Why this stepWhy studies using the same database and index reach different numbers.

The shared finding is a non-significant quartile trend test together with a nonlinear RCS. These do not conflict: the trend test checks monotonic change, while RCS allows curvature. Inflection points depend on age structure and covariates, so 8.88, 9.18 and 9.364 should not be used as clinical cut-offs.

StudySampleMain result
Chen et al., 20241999–2018, n = 17,118All-cause Q4 vs Q1 HR 0.93 (0.76–1.14); RCS threshold 8.88, nonlinear P = 0.0071
Wang et al., 20242001–2018, n = 15,388All-cause Q4 HR 1.02 (0.62–1.48); curve falls then rises
Sun et al., 20221999–2014, age ≥45, n = 9,254All-cause continuous HR 1.01 (0.93–1.10); inflection point 9.18
This page1999–2018, age ≥20, n = 22,894All-cause continuous HR 1.03 (0.95–1.12); U-shaped, minimum near 9.0, exploratory breakpoint 9.364
Age range, cycles, follow-up end, covariates and sample selection differ, so thresholds do not transfer between studies.

Reference and appendix

Run record

Why this stepData source and run conditions.

The numbers come from one long research task on Scientify on 27 October 2026. After the user uploaded a task brief and confirmed six research requirements, Scientify downloaded 100 official files, parsed the mortality files, combined weights and ran every analysis. It also caught the weight-scale artefact of cox.zph on a weighted model and switched to a time-interaction test.

The deliverables were a 16-page report in Chinese, 22 figures, tables, a one-command reproduction script and a data manifest with SHA256 hashes, and an independent review passed. The task took about 1.5 hours on a cloud CPU without renting a GPU.

Scientify workspace showing NHANES research requirements R1 to R6
The six research requirements confirmed before the run.
Scientify research brief listing findings with confidence levels
Research brief: each finding is labeled with confidence and evidence.

Common errors and fixes

Ordered by how often they occur.

WTMEC2YR used for a fasting-laboratory analysis

Cause: Fasting glucose and triglycerides are measured only in the fasting subsample.

Fix: Use WTSAF2YR (WTSAF4YR for 1999–2002) and rescale by cycle years when combining.

Downloaded XPT files cannot be read, or are only a few KB

Cause: CDC changed its paths and the old URLs return an HTML 404 page.

Fix: Use /Nchs/Data/Nhanes/Public/<year>/DataFiles/ and check the file header after download.

Weighted standard errors are unusually small

Cause: Rows were dropped before svydesign, which breaks the sampling structure.

Fix: Build the design on the full sample, then use subset().

Mortality columns are misaligned

Cause: The fixed-width .dat file was read as delimited text.

Fix: Use the column positions from the official NCHS read program; SEQN is columns 1–6.

TyG values are clearly too large

Cause: mg/dL values were multiplied by a conversion factor again.

Fix: LBXTR and LBXGLU are already mg/dL; use them directly.

cox.zph on svycoxph gives P values near 1

Cause: An artefact of the weight scale; the test is invalid.

Fix: Use a time-period interaction with a design-based Wald test.

survey reports a lonely PSU error

Cause: A stratum in the subset has only one PSU.

Fix: Set options(survey.lonely.psu = "adjust") and state it in the methods.

References

FAQ

What is the official NHANES website?

The entry point is wwwn.cdc.gov/nchs/nhanes, maintained by NCHS at the US CDC. Downloads are free and need no registration. Linked mortality files are in the NCHS linked_mortality directory on ftp.cdc.gov.

How do I download NHANES data?

Download XPT files by cycle and module from the CDC NHANES portal. The current URL pattern is wwwn.cdc.gov/Nchs/Data/Nhanes/Public/<year>/DataFiles/<file>.xpt. Mortality data are downloaded separately from the NCHS linked_mortality directory.

Which NHANES weight should I use?

The variable from the smallest subsample decides. Interview-only variables use WTINT2YR, examination variables WTMEC2YR, and fasting laboratory variables WTSAF2YR. When combining cycles, rescale by each cycle's share of the total years.

What is the TyG index formula?

TyG = ln[triglycerides (mg/dL) × fasting glucose (mg/dL) / 2]. For mmol/L, multiply triglycerides by 88.57 and glucose by 18.018 first.

What is the difference between the overall and nonlinear P in an RCS?

The overall P tests whether the exposure is associated with the outcome; the nonlinear P tests whether the relationship departs from a straight line. Here all-cause mortality has overall P = 0.0096 and nonlinear P = 0.0090, indicating a nonlinear association.

The Cox HR is not significant but the RCS is. Is that a contradiction?

No. A linear HR assumes monotonic change; in a U-shaped relationship both ends carry higher risk and the linear term can sit near 1. Here the linear HR is 1.03 (0.95–1.12) and the RCS nonlinear P is 0.009.

Is TyG still a good NHANES topic for a paper?

Several NHANES TyG–mortality studies are already published with similar conclusions. A new study needs a clear difference in population, outcome, exposure combination or method, and should compare itself with the existing work.

Let Scientify run your NHANES analysis

Upload your research idea. Scientify downloads the official data, combines weights, runs the weighted models and figures, and delivers reproducible code and a report.