Package {cdcanthro}


Title: Standardized Metrics Based on the CDC and WHO Growth Charts
Version: 0.4.0
Date: 2026-08-30
Description: Calculation of sex- and age-standardized growth metrics using the LMS method (lambda-mu-sigma). The package includes functions for the CDC Growth Charts (cdc_z) and the WHO Charts (who_z). Because CDC recommends using the WHO Charts for children under 24 months and the CDC Charts among older children, there can be large differences at age 2.0 years. For example, a girl weighing 9.9 kg would be at the WHO 10th percentile on the day before her second birthday, but at the CDC 2nd percentile the following day. The 'gradual_z' function reduces the differences among 2- to 5-year-olds by taking a weighted average of the CDC and WHO z-scores.
License: GPL-3
Encoding: UTF-8
LazyData: true
ByteCompile: true
NeedsCompilation: no
Depends: R (≥ 3.5.0)
Imports: data.table (≥ 1.15.0), stats, utils
Suggests: tibble
Packaged: 2026-08-30 14:51:44 UTC; davidfreedman
Author: David Freedman ORCID iD [aut, cre], Carrie Daymont [ctb]
Maintainer: David Freedman <DavidSFreedman@gmail.com>
Repository: CRAN
Date/Publication: 2026-08-31 15:20:03 UTC

cdcanthro: Sex- and Age-Standardized Metrics from the CDC and WHO Growth Charts

Description

Calculation of sex- and age-standardized growth metrics using the LMS method (lambda-mu-sigma). The function cdc_z(), previously named cdcanthro(), uses the 2000 CDC growth charts for children and adolescents with ages of >= 24.0 to < 240 months, to generate sex- and age-standardized z-scores and percentiles for weight, height, and body mass index (BMI). The output includes extended BMI z-scores for values above the 95th percentile to more accurately characterize children with very high BMIs.

Because CDC recommends the WHO Growth Standards for children under 2 years of age, there is also a function, who_z(), which computes sex- and age- (or length-) standardized metrics for children under five years of age.

There is also a function, gradual_z(), which smooths the discontinuities at age 2.0 resulting, in large part, from the use of different reference data. For example, a girl weighing 9.9 kg would be at the 10th percentile the day before her second birthday and at the 2nd percentile the following day.

Author(s)

David S Freedman

Maintainer: David S Freedman <DavidSFreedman@gmail.com>

Other contributors:


Sample Anthropometric Data from NHANES

Description

A sample dataset of 7393 NHANES participants. Variables include height, weight, sex, and age in months. Note that months is given as the completed number of months.

Usage

data(NHanes)

Format

A data frame or data table with observations on multiple anthropometric variables.


CDC Growth Chart Reference Data (2000)

Description

LMS parameters (L, M, S) for age- and sex-standardized growth metrics.

Usage

data(cdc_ref_data)

Format

A data.table with columns for sex, age, and LMS values. Parameter names represent the first letter of weight, height, or BMI; this is followed by 'l', 'm', or 's' for the LMS parameters. 'mref' and 'sref' are the M and S parameters at 240 months of age. For sexn, '1' are boys and '2' are girls.

Source

https://www.cdc.gov/growthcharts/percentile_data_files.htm


Generate Sex- and Age-Standardized Weight, Height, and BMI Metrics From the CDC Growth Charts

Description

Generate z-scores, percentiles, and other sex- and age-standardized metrics for weight, height, and BMI based on the 2000 CDC growth charts. For children with obesity, the extended BMI z-scores and percentiles are calculated. The calculations are restricted to children with ages between 24.0 (inclusive) and < 240 months. Note that cdc_z is the preferred name; the previous name, cdcanthro, will work but will be deprecated

The BMI metrics include z-scores and percentiles, along with newer metrics such as extended BMIz and percent of the 50th and 95th percentiles. The extended BMI metrics are used for BMIs above the 95th percentile.

Usage

cdc_z(data, age, wt, ht, bmi, sex_code, all_vars = FALSE)
cdcanthro(data, age, wt, ht, bmi, sex_code, all_vars = FALSE)

Arguments

data

a data.frame, data.table, or tibble (tbl_df) containing the input data. The class of the returned object matches the class of data.

age

Age in months, specified as accurately as possible. Required.

wt

Weight in kg. Optional. If omitted, WAZ-related metrics will be missing.

ht

Height in cm. Optional. If omitted, HAZ-related metrics will be missing.

bmi

BMI in kg/m^2. Optional. If omitted but both wt and ht are supplied, BMI is computed as wt / (ht / 100)^2. If all three of wt, ht, and bmi are omitted, the function stops with an error.

sex_code

Numeric coding for sex if other than 1 for boys and 2 for girls. Optional.

all_vars

logical. If TRUE, returns additional intermediate variables (L, M, S values; sigma; and the distance-from-median metrics from Freedman et al.). Default is FALSE.

Details

Argument values can be quoted (e.g., age='agemos') or unquoted (age = agemos).

The function expects the child's sex to be named sex; either upper- or lower-case is fine. You cannot have both SEX and sex in your data. Values can be coded as boys/girls, b/g, male/female, m/f, or 1/2. Character values can be in upper- or lower-case; only the first character is considered. If sex is numeric and not coded as 1/2, specify this in the optional sex_code argument; the code for boys is the first number. For example, 0/1 coding would be specified as sex_code = 0:1 or sex_code = c(0,1).

Weight is in kg, height is in cm, and BMI is in kg/m^2.

At least one of wt, ht, or bmi must be present. Metrics that cannot be calculated from the supplied variables will be missing from the output, and warnings will indicate the missing variables. For example, supplying only wt returns WAZ but omits HAZ and BMI metrics from the output.

Age in months should be given as accurately as possible because the function linearly interpolates between completed months of age. If ages are given as the completed number of months (as in NHANES), add 0.5 because values such as 36 represent the interval [36, 37) months. If the function detects integer numbers for all ages, it will add 0.5 to all age values.

If age is in days, divide by 30.4375 so that a child who is 3672 days old would have an age in months of 120.641. For additional information on age, see the ‘See Also’ section below.

If all_vars = TRUE, all variables in the Freedman et al. paper will be output, along with the L, M, and S values for each child and the value of sigma for the half-normal distribution.

For children without obesity, BMI z-scores are calculated as

Z = ((BMI / M)^L - 1) / (L \times S)

where BMI is the child's BMI, L is the Box-Cox transformation for normality for the child's sex and age, M is the median, and S is the coefficient of variation. Reference data are the merged LMS files from the CDC (see ‘See Also’).

For children with obesity, BMI percentiles are calculated as

90 + 10 \times \Phi((\mathrm{BMI} - \mathrm{p95}) / \sigma)

where p95 is the sex- and age-specific 95th percentile, \Phi is the CDF of a N(0, 1) distribution (pnorm()), and sigma is the scale parameter of the half-normal distribution. Values of sigma for children with obesity are based on formulas in Wei et al.

The class of the returned object matches the class of the input data: a data.frame input returns a data.frame, a data.table returns a data.table, and a tibble (tbl_df) returns a tibble (provided the tibble package is installed; otherwise a data.frame is returned with a warning).

Value

A data.table, data.frame, or tibble containing the original data and various weight, height, and BMI metrics.

If your dataset has ages that are < 24 or >= 240 months, these rows will be present in the output dataset. All calculated metrics will be NA. If this is not what you want, delete these rows before running cdc_z().

Variables in output:

waz, haz, bmiz

Sex- and age-standardized z-scores for weight, height, and BMI. bmiz is based on the 2000 CDC growth charts for non-obese children and extended BMIz for obese children.

wap, hap, bmip

Sex- and age-standardized percentiles for weight, height, and BMI. bmip is based on the extended BMI metrics for obese children.

mod_waz, mod_haz, mod_bmiz

Modified z-scores.

orig_bmip, orig_bmiz

Original BMI percentiles and z-scores based solely on the LMS method. orig_bmiz and bmiz are identical for children with BMI at or below the 95th percentile.

p50, p95

Sex- and age-specific 50th and 95th percentiles of BMI.

bmip95

BMI expressed as a percentage of the 95th percentile; 120 percent is the lower threshold for severe obesity.

perc_median

Percent difference between the child's BMI and the median (50th percentile) BMI for the child's sex and age.

If all_vars = TRUE, additional BMI metrics described in Freedman et al. are also returned. These express BMI as distance or percent distance from the median. To convert to percent of the median, add 100 to the values.

Note

library(cdcanthro) will also load the data.table package.

Note that argument names can be quoted or unquoted: cdc_z(data, age, wt, ht, bmi), and cdc_z(data, 'age', 'wt', 'ht', 'bmi') produce the same result.

Author(s)

David Freedman DavidSFreedman@gmail.com

References

Kuczmarski RJ, Ogden CL, Guo SS, Grummer-Strawn LM, Flegal KM, Mei Z, et al. 2000 CDC Growth Charts for the United States: methods and development. Vital and Health Statistics Series 11, Data from the National Health Survey 2002;11:1–190.

Wei R, Ogden CL, Parsons VL, Freedman DS, Hales CM. A method for calculating BMI z-scores and percentiles above the 95th percentile of the CDC growth charts. Annals of Human Biology 2020;47:514–21.

Freedman DS, Woo JG, Ogden CL, Xu JH, Cole TJ. Distance and Percent Distance from Median BMI as Alternatives to BMI z-score. British Journal of Nutrition 2019;124:1–8.

See Also

CDC LMS percentile data files: https://www.cdc.gov/growthcharts/percentile_data_files.htm

CDC extended BMI data files: https://www.cdc.gov/growthcharts/extended-bmi-data-files.htm

CDC SAS programs and more information on agemos in Table 1 of https://www.cdc.gov/growth-chart-training/hcp/computer-programs/sas.html

Examples

data <- data.table::CJ(sex = 1:2, agem = 120.5, wtk = c(30, 65), htc = c(135, 144))
data[, let(bmi = wtk / (htc / 100)^2)]
out <- cdc_z(data, age = agem, wt = wtk, ht = htc, bmi = bmi)
round(out, 2)[1:5]

out <- cdc_z(data, age = agem, wt = wtk, ht = htc, bmi = bmi, all_vars = TRUE)
round(out, 2)[1:5]

d <- data.frame(sex = c(1, 2, 1, 2, 2),
                age = c(141, 54, 217, 155, 52),
                wt  = c(57, 25, 72, NA, 17.7),
                ht  = c(143, 102, 166, 169, 105))
d <- cdc_z(d, age, wt, ht)
round(d, 2)

d <- data.frame(sex = c(0, 1, 0),
                age = c(120.5, 60.5, 180.5),
                wt  = c(40, 25, 65))
d <- tibble::as_tibble(d)
cdc_z(d, age, wt, sex_code = 0:1) # note use of sex_code

head(NHanes) # age is given as completed months
d <- data.table::copy(NHanes)
head(cdc_z(d, agemos, wt, ht, bmi))[,.(seqn, agemos, waz, haz, bmiz)]
d[, let(agemos = agemos + 0.5)]
head(cdc_z(d, agemos, wt, ht, bmi))[,.(seqn, agemos, waz, haz, bmiz)]
# same Z-scores

Gradual WHO-to-CDC Transition Z-Scores

Description

Computes a smooth, gradually transitioning z-score for weight, height/length, and body mass index (BMI) that blends World Health Organization (WHO) and Centers for Disease Control and Prevention (CDC) growth reference z-scores across early childhood. These gradual z-scores use WHO z-scores up to 730 days (2.0 y) of age, CDC z-scores are used from 1826 days (5.0 y) of age onward, and a weighted average of the CDC and WHO z-scores between ages 2 and 5 years.

Gradual z-scores avoid the abrupt jump produced by switching directly from WHO to CDC references at age 2 years as recommended by CDC. For example, under an abrupt switch, a girl weighing 9.9 kg would be at the 10th percentile (WHO) the day before her second birthday and at the 2nd percentile (CDC) the following day; gradual_z avoids this discontinuity.

Usage

gradual_z(data,
         agedays = agedays,
         whowtz  = who_waz,
         cdcwtz  = waz,
         whohtz  = who_lhaz,
         cdchtz  = haz,
         whobmiz = who_bmiz,
         cdcbmiz = bmiz)

Arguments

data

A data.frame, data.table, or tibble containing, at minimum, the age column and at least one complete WHO/CDC z-score column pair. The same class is returned. Not every z-score pair is required – see Value.

agedays

Column for age in days. Note that all arguments can be either unquoted or quoted.

whowtz

WHO weight-for-age z-score.

cdcwtz

CDC weight-for-age z-score.

whohtz

WHO length/height-for-age z-score.

cdchtz

CDC height-for-age z-score.

whobmiz

WHO BMI-for-age z-score.

cdcbmiz

CDC BMI-for-age z-score.

Details

Naming the arguments rather than relying on position is recommended. However, if the input was created using cdc_z and who_z, the function can be called as gradual_z(data). Argument values can be quoted or unquoted.

For each row, age in days determines which of three regions applies:

This produces a transition that is continuous at both boundaries, avoiding the discontinuity that would result from switching abruptly from WHO to CDC references at a single cutoff age.

For ages between 2 and 5 years, the gradual z-score is a weighted average of the WHO and CDC z-scores:

Z_{gradual} = \frac{Z_{WHO} \times (5 - \mathrm{ageyears}) + Z_{CDC} \times (\mathrm{ageyears} - 2)}{3}

It should be noted that gradual z-scores from 2 through 5 years of age are not directly comparable to those based on other reference data, and researchers may need sensitivity analyses to facilitate comparison with other studies.

Further, because of the change in recumbent length to standing height at age 2.0 years, a discontinuity at this age will be present for grad_haz and grad_bmiz.

Value

An object of the same class as data (data.frame, data.table, or tibble), containing all columns of data, plus:

grad_waz

Gradual (blended) weight-for-age z-score. Added only if both whowtz and cdcwtz are found in data.

grad_haz

Gradual (blended) height/length-for-age z-score. Added only if both whohtz and cdchtz are found in data.

grad_bmiz

Gradual (blended) BMI-for-age z-score. Added only if both whobmiz and cdcbmiz are found in data.

Each of the three gradual measures is checked independently. If neither column of a pair is found, that measure is skipped with an informational message(). If only one column of a pair is found, that measure is skipped with a warning() instead. If no complete pair is found, a warning() is issued.

In the output, each measure's columns are grouped together in the order CDC, WHO, gradual (e.g. who_waz, waz, grad_waz), for weight, then height, then BMI; any other original columns (including agedays) come first.

Author(s)

David Freedman DavidSFreedman@gmail.com

References

Daymont C, Hwang W, Paul IM, Shur N, Freedman DS (2025). "Creation and Evaluation of New Growth Charts With a Gradual Transition From WHO to CDC Values." Pediatrics, 156(3), e2025070697. doi:10.1542/peds.2025-070697

See Also

The original growth charts, tables, and R/Stata code are available at https://github.com/carriedaymont/gradual-who-cdc.

Examples

library(data.table)
dt <- data.table(
  agedays  = c(730, 1096, 1461, 1826), # 2, 3, 4, and 5 years of age
  who_waz  = c(0.9, 0.7, 0.6, 0.4),
  waz      = c(0.7, 0.5, 0.3, 0.3),
  who_lhaz = c(-0.2, 0.1, 0.2, 0.1),
  haz      = c(-0.3, 0.0, 0.1, 0.2),
  who_bmiz = c(1.0, 0.9, 0.8, 0.7),
  bmiz     = c(0.1, 0.5, 0.2, 0.2)
)
result <- gradual_z(dt, agedays, who_waz, waz, who_lhaz, haz, who_bmiz, bmiz)
result[, ageyears:= round(agedays/365.25,2)]
result

gradual_z(dt) # because column names match defaults

WHO Reference Data

Description

LMS parameters (L, M, S) in the WHO charts for age- and sex-standardized growth metrics.

Usage

data(who_ref_data)

Format

A data.table with columns for sex (sexn coded as 1 (boys) / 2 (girls)), age in days, and LMS values. Variable names represent the weight (wei), length or height (len), BMI (bmi), weight-for-length (wfl), or head circumference (headc). This prefix is followed by '_' and then by 'l', 'm', or 's' representing the LMS parameters.

Sexn is coded as '1' (boys) and '2' (girls).

In contrast to the sex- and age-standardized metrics, weight-for-length is weight standardized for sex and length; it represents the distribution of weights for a specific length.

The 'denom' variable indicates if the row represents age-standardization or len-standardization.

Source

https://www.who.int/toolkits/child-growth-standards/standards


Sex- and Age- (or Length-) Standardized Weight, Length/Height, BMI, and Head Circumference Metrics from the WHO Growth Charts

Description

Calculates z-scores and biologically-implausible-value (BIV) flags for weight-for-age, length/height-for-age, BMI-for-age, head-circumference-for-age, and weight-for-length, based on the WHO Child Growth Standards. The original data are returned together with the calculated metrics.

This function is included in the cdcanthro package because CDC recommends using (1) the CDC Growth Charts for children with ages (months) >=24 and < 240, and (2) the WHO Standards for children < 24 months of age. The use of these different charts, along with the change from recumbent length to standing height at age 2.0 y, creates discontinuities at age 2.0 years (730 days). https://www.cdc.gov/growth-chart-training/hcp/overview/recommended.html

Usage

who_z(data,
          agedays = agedays,
          wt = wt,
          lenhei = lenhei,
          bmi = bmi,
          headc = headc,
          sex_code = 1:2)

Arguments

data

a data.frame or data.table of measurements. Must contain a variable named sex or SEX (but not both).

agedays

age in completed days. Note that all arguments can be unquoted (e.g., agedays = days) or quoted(agedays = 'days') If age is given as completed number of months (e.g., NHANES), add 0.5 months, multiply by 30.4375 to convert to agedays, and round to the nearest day.

wt

weight in kg.

lenhei

recumbent length (ages <= 730 days) or standing height (ages > 730 days), in cm. Note that there is an ~0.7 difference in M (median) between 730 and 731 days in the reference data, when the measurement changes from recumbent length to standing height

bmi

body mass index, kg/m^2. If not supplied but both wt and lenhei are, BMI is calculated as wt / (lenhei/100)^2.

headc

head circumference in cm.

sex_code

Numeric coding for sex if other than 1 for boys and 2 for girls. Optional.

Details

Column names can be given with or without quotation marks. Naming the arguments rather than relying on position is recommended, e.g. who_z(d, agedays = age, wt = weight); otherwise a value can silently land in the wrong slot. Any absent measurement is skipped with a warning, and its z-score is not returned.

sex may be coded as boys/girls, male/female, or 1/2. Character values may be upper or lower case; only the first character is used, so 'b' / 'g' is fine. If sex is numeric and not coded as 1/2, specify this in the optional sex_code argument; the code for boys is the first number. For example, 0/1 coding would be specified as sex_code = 0:1 or sex_code = c(0,1).

Age in the WHO reference data goes from 0 to 1856 days. However, weight-for-length Z is calculated only for children <= 730 days of age with a length between 45 and 110 cm.

Value

A data.table containing the original data plus the calculated metrics. The age-based z-scores are calculated for children with an agedays between 0 and 1826 (inclusive). Weight-for-length z is calculated for children between 0 and 730 days.

WHO Z-scores:

BIV flags, following the anthro package. Each 'f' (flag) is 1 if the z-score is outside the WHO plausibility range, 0 if inside, and NA if the z-score is NA:

Note that there doesn't appear to be any publications that justify these cutpoints. While values outside these ranges are outliers, the measurement may be correct.

Author(s)

David Freedman DavidSFreedman@gmail.com

References

World Health Organization, Department of Nutrition for Health and Development. WHO Child Growth Standards: Length/height-for-age, weight-for-age, weight-for-length, weight-for-height, and body mass index-for-age. Methods and Development. Geneva; 2006. https://apps.who.int/iris/handle/10665/43413

The reference LMS values are in the 'Expanded Percentile' files at doi:10.1111/j.1651-2227.2006.tb02378.x

See Also

cdc_z for standardized values based on the CDC growth charts

Examples

NHanes
d <- NHanes
d <- data.table::copy(NHanes)
d[, let(lenhei=ifelse(agedays<=730,length,ht))]
# lenhei is a composite of length and ht:
# it is length for 0 to <=730 days, but height for >730 days
d <- d[agedays <= 1826]
out <- who_z(d, agedays, wt, lenhei, bmi, headc)
head(out)

# verify that the function works for head circumference (small N)
temp <- NHanes[!is.na(headc)]
temp[, let(lenhei=ifelse(agedays<=730,length,ht))]
out <- who_z(temp, agedays, wt, lenhei, bmi, headc)
head(out)