| Type: | Package |
| Title: | Puberty Stage Line Diagrams and SDS for Tanner Pubertal Stages |
| Version: | 1.8.0 |
| Date: | 2026-07-18 |
| Description: | Plots Tanner pubertal stage measurements (genital, pubic hair, testicular volume, breast, menarche) against Dutch 1997 growth-study references as stage line diagrams, and converts observed stages to age-conditional standard deviation scores (SDS). Testicular volume can be entered as a raw orchidometer reading in ml. Implements the method of van Buuren and Ooms (2009) <doi:10.1002/sim.3567>. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/growthcharts/tanner, https://growthcharts.org/tanner/ |
| BugReports: | https://github.com/growthcharts/tanner/issues |
| Encoding: | UTF-8 |
| Depends: | R (≥ 3.5.0) |
| Imports: | haven |
| LazyData: | true |
| RoxygenNote: | 7.3.3 |
| Suggests: | testthat (≥ 3.0.0), knitr, rmarkdown |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| NeedsCompilation: | no |
| Packaged: | 2026-07-28 20:39:47 UTC; buurensv |
| Author: | Stef van Buuren [aut, cre], Jeroen Ooms [aut] |
| Maintainer: | Stef van Buuren <stef.vanbuuren@tno.nl> |
| Repository: | CRAN |
| Date/Publication: | 2026-08-06 13:10:02 UTC |
Calculate the standard deviation score (SDS) of a pubertal stage
Description
Calculates the SDS for a pubertal stage measurement, given the patient's age and observed stage, by interpolating between the surrounding reference percentiles.
Usage
calculate_sds(age, stage, type, ref = tanner::nl1997)
Arguments
age |
Vector of patient ages. The length of |
stage |
Vector of patient stages, the same length as
|
type |
Reference type: one of |
ref |
Reference data, as produced by |
Details
Implements the mid-P value method of van Buuren & Ooms (2009), equation
(6): treating the observed stage c as a coarsened version of a
continuous latent variable, uniformly distributed within the stage's
probability interval [P(Y<c|X), P(Y<c+1|X)). The mid-P value
pi_c = P(Y<c|X) + P(Y=c|X)/2 is the mean of that latent variable,
and Z = qnorm(1 - pi_c) = qnorm(1 - (P(Y>=c|X) + P(Y>=c+1|X))/2)
converts it to a Z-score/SDS. This is why the SDS averages the
surrounding-stage percentiles rather than looking up a single stage's
percentile directly: the averaging is the mid-P value itself, not an ad
hoc smoothing step. The same formula applies to tv's 12 Prader
bead categories, treating each raw ml reading as belonging to the
bead-category interval it falls into (see below).
Value
A numeric vector of SDS values, the same length as age
(one value per element of age).
References
van Buuren S, Ooms JCL (2009). Stage line diagram: An age-conditional reference diagram for tracking development. Statistics in Medicine, 28(11), 1569-1579. doi:10.1002/sim.3567
Examples
# a single boy, genital stage 3 at age 12
calculate_sds(age = 12, stage = 3, type = "gen")
# a boy's genital-stage trajectory over three visits
calculate_sds(age = c(10, 12, 14), stage = c(1, 3, 4), type = "gen")
# testicular volume in ml, interpolated between Prader beads
calculate_sds(age = 13, stage = 11, type = "tv")
Find segments of constant stage in a vector
Description
Determines the runs (segments) in z over which the value does not
change, ignoring missing values. Used by
interpolate_trajectory to split a patient's stage
trajectory into per-stage segments.
Usage
find_stage_segments(z)
Arguments
z |
A vector, typically of pubertal stages. |
Value
A logical matrix with one row per segment and one column per
element of z, where TRUE marks membership of that element
in the segment.
Interpolate a pubertal stage trajectory along reference curves
Description
Computes the x/y coordinates needed to plot a patient's pubertal stage trajectory along the reference curves, including the interpolated segments between measurement ages within the same stage.
Usage
interpolate_trajectory(refx, refy, patx, pats)
Arguments
refx |
Vector of reference ages. |
refy |
Matrix of reference values, one column per stage. |
patx |
Vector of patient ages. |
pats |
Vector of patient stages (column indices into |
Value
A list with components x, y, stage and
patient (a logical flag indicating whether a point is an
observed patient measurement or an interpolated reference point).
Examples
# reference ages and genital stage percentile curves for boys
refx <- seq(8, 21, 0.25)
refy <- tanner::nl1997_lines$gen[, -1]
# a boy observed at G1 at age 10, still G1 at age 11, then G3 at age 13
patx <- c(10, 11, 13)
pats <- c(1, 1, 3)
curve <- interpolate_trajectory(
refx = refx, refy = refy, patx = patx, pats = pats
)
curve
# curve$patient flags the observed measurements; the other points
# interpolate along the reference curve between them
plot(curve$x, curve$y, type = "l")
points(curve$x[curve$patient], curve$y[curve$patient], pch = 16)
Dutch 1997 pubertal stage references
Description
Reference percentiles for pubertal stage variables by age, based on the
Dutch 1997 growth study (Fredriks et al., 2000). Used by
calculate_sds to convert an observed age/stage combination
into a standard deviation score.
Usage
nl1997
Format
A list with six components, one per pubertal stage variable:
gen, phb, tv, bre, phg and
men. Each component is a data frame whose first column is
age and whose remaining columns hold the age at which 50
the reference population reaches each stage.
Source
Fredriks AM, van Buuren S, Burgmeijer RJ, et al. (2000).
Continuing positive secular growth change in The Netherlands 1955-1997.
Pediatric Research, 47(3), 316-323. Percentiles were refit in R
from data-raw/data/pub.ref.1997r.txt, correcting testis-volume
(tv) fitting errors present in the original S-Plus-fitted
pub.ref.1997.txt; the genital-stage columns match Table 5 of
van Buuren S (2014). Growth charts of human development.
Statistical Methods in Medical Research, 23(4), 346-368.
doi:10.1177/0962280212473300
Dutch 1997 pubertal stage reference lines
Description
Reference curves, expressed as standard deviation scores (SDS) by age,
derived from nl1997. Used by plot_stadia to
draw the percentile lines on a puberty stadia plot.
Usage
nl1997_lines
Format
A list with six components, one per pubertal stage variable:
gen, phb, tv, bre, phg and
men. Each component is a matrix whose first column is
age and whose remaining columns hold the SDS curve for each
stage.
Source
Derived from nl1997; see
data-raw/R/create_references.R.
Plot a puberty stadia diagram
Description
Plots Tanner pubertal stage measurements for one or more persons against the Dutch 1997 reference curves, expressed as standard deviation scores (SDS) by age.
Usage
plot_stadia(
data = pub.data,
persons = unique(data$id),
plotline = c(TRUE, FALSE, FALSE),
type = c(TRUE, FALSE, FALSE),
colors = c("#0060A0", "#00A000", "#A00000"),
overlay = FALSE,
ovsex = "M",
ref = tanner::nl1997_lines,
title = "Tanner pubertal stages - Patient ",
padid = TRUE
)
Arguments
data |
A data frame with columns |
persons |
Vector of person identifiers (values of |
plotline |
Logical vector of length 3 indicating which reference lines to draw. |
type |
Logical vector of length 3 indicating which pubertal stage variables to plot. |
colors |
Character vector of length 3 with the colors used for the three pubertal stage variables. |
overlay |
If |
ovsex |
Sex ( |
ref |
Reference data used to draw the reference lines, as produced
by |
title |
Plot title. |
padid |
If |
Value
Invisibly returns NULL; the function draws on the current
graphics device.
Draw a person's pubertal stage trajectory on a puberty stadia plot
Description
Internal helper used by plot_stadia to draw a single
person's pubertal stage trajectory, interpolated along the reference
curves, on the current plot.
Usage
plot_stadia_data(ages, pubs, sex, type, colors, ref)
Arguments
ages |
Vector of ages at measurement. |
pubs |
Data frame with the pubertal stage variables for this person;
|
sex |
|
type |
Logical vector of length 3 indicating which pubertal stage variables to plot. |
colors |
Character vector of length 3 with the colors for the three pubertal stage variables. |
ref |
Reference data, as produced by |
Value
Invisibly returns NULL; the function draws on the current
graphics device.
Draw the frame, percentile bands and axes of a puberty stadia plot
Description
Internal helper used by plot_stadia to draw the plot frame,
the early/late percentile bands, the TNO logo and the axes.
Usage
plot_stadia_general(
i = " ",
opt = c(TRUE, TRUE, TRUE, TRUE, TRUE),
title = " ",
padid = TRUE
)
Arguments
i |
Person identifier appended to the title when |
opt |
Logical vector of length 5 selecting which elements to draw: frame and title, extreme percentile regions, TNO logo, axes, margin reference text. |
title |
Plot title. |
padid |
If |
Value
Invisibly returns NULL; the function draws on the current
graphics device.
Draw reference percentile lines on a puberty stadia plot
Description
Internal helper used by plot_stadia to add the Dutch
reference lines for males (Genital, Pubic hair, Testis) or females
(Breast, Pubic hair, Menarche) to the current plot.
Usage
plot_stadia_lines(plotlines, colors, sex, ref)
Arguments
plotlines |
Logical vector of length 3 indicating which reference lines to draw. |
colors |
Character vector of length 3 with the colors for the three pubertal stage variables. |
sex |
|
ref |
Reference data, as produced by |
Value
Invisibly returns NULL; the function draws on the current
graphics device.
Directory where generated plot and data files are written
Description
Set on package load to a "plotfiles" subdirectory of
tempdir(). Used by the rApache handlers plotter
and plotterpro as the destination directory for generated
PDF, PNG, CSV and TXT files, and by upload_tryCatch_pro as
the destination for uploaded data files and the .RData file it
hands off to plotterpro. The directory itself is only created
lazily, on the first actual write inside these handlers – not merely by
loading the package – so calling library(tanner) to use unrelated
functions like calculate_sds has no disk side effects.
Reassign this before calling the handlers to change where they read/write.
Usage
plotdumpdir
Format
An object of class character of length 1.
rApache handler for the puberty plot webapp
Description
Reads pubertal staging data from the rApache GET request, builds
a puberty plot and writes it to PDF and PNG files in plotdumpdir.
This function is intended to be called from the rApache web frontend
shipped in inst/webapps, not interactively from R.
Usage
plotter()
Value
Invisibly returns the generated file name stem (also written,
via cat(), to the response – under rApache, standard output
is the HTTP response body).
See Also
Other webapp-internals:
plotterpro(),
upload_tryCatch_pro()
rApache handler for the professional puberty plot webapp
Description
Reads a saved data file (written by upload_tryCatch_pro)
from plotdumpdir, as referenced in the rApache POST
request, calculates SDS values for the pubertal stages, and writes the
results and a puberty plot to CSV, TXT and PDF files, also in
plotdumpdir. This function is intended to be called from the
rApache web frontend shipped in inst/webapps, not interactively
from R.
Usage
plotterpro()
Value
Invisibly returns the JSON response string (also written, via
cat(), to the response – under rApache, standard output
is the HTTP response body).
See Also
Other webapp-internals:
plotter(),
upload_tryCatch_pro()
Snap raw testicular volume readings to the nearest Prader bead curve
Description
Internal helper used by plot_stadia_data to trace a tv
trajectory along the single nearest reference curve, since tv is
recorded as a raw ml reading rather than one of the 12 Prader bead
volumes. Unlike calculate_sds's tv handling (which
interpolates continuously between the two surrounding beads), this
snaps to whichever bead is closest, since a trajectory line can only
follow one reference curve at a time.
Usage
snap_tv_to_nearest_bead(ml, refy_colnames)
Arguments
ml |
Vector of raw testicular volume readings, in ml. |
refy_colnames |
Column names of the tv reference curves (e.g.
|
Value
Integer vector the same length as ml: the column index
(into refy_colnames) of the nearest bead curve, or NA
where ml is NA.
Draw the TNO logo
Description
Plots the current TNO logo (upright "TN" wordmark plus a ring-shaped "O")
using the current coordinate system. Used by
plot_stadia_general to brand the puberty stadia plots.
Usage
tnologo(col = "darkblue", bcol = "white", at = c(0, 0), size = 300, aspect = 1)
Arguments
col |
Foreground color. |
bcol |
Background color. |
at |
(x, y) coordinate of the lower left corner of the logo. |
size |
Horizontal size, measured in the units of the x-axis. |
aspect |
Unit size of the y-axis divided by the unit size of the x-axis. |
Value
Invisibly returns NULL; the function draws on the current
graphics device.
Parse Prader bead ml thresholds from tv reference column names
Description
Internal helper shared by calculate_sds and
snap_tv_to_nearest_bead: both need the raw ml threshold
each "T"-prefixed tv reference column represents (e.g.
"T12" -> 12), though what they do with those thresholds
afterward differs (bracket-and-interpolate vs. snap-to-nearest).
Usage
tv_ml_thresholds(colnames)
Arguments
colnames |
Character vector of |
Value
Numeric vector the same length as colnames: the ml
threshold each column represents.
rApache handler for uploading puberty data files
Description
Validates an uploaded data file (referenced in the rApache FILES
request), saves it as an .RData file in plotdumpdir,
and writes a JSON summary of the data per person to the response. This
function is intended to be called from the rApache web frontend shipped
in inst/webapps, not interactively from R.
Usage
upload_tryCatch_pro()
Value
Invisibly returns the HTML/JSON response string (also written,
via cat(), to the response – under rApache, standard output
is the HTTP response body).
See Also
Other webapp-internals:
plotter(),
plotterpro()