The reference functions in
pft (pft_spirometry(),
pft_volumes(), pft_diffusion(), and the
one-call workflow pft_interpret()) all take a data frame
and append reference columns to it. This article documents exactly which
columns each function expects, which are optional, and how to point pft
at columns whose names don’t match the canonical ones.
Three categories of column drive the reference functions:
Required – demographics that must be present, or the function errors:
pft_spirometry(year = 2012) and
pft_interpret(year = 2012): sex,
age, height, race.pft_spirometry(year = 2022) and
pft_interpret(year = 2022): sex,
age, height (the GLI Global 2022 equations are
race-neutral and ignore race).pft_volumes() and pft_diffusion():
sex, age, height.Optional measured –
<measure>_measured columns whose presence unlocks
z-score and percent-predicted outputs for that measure. Missing these is
silent; the function simply emits fewer output columns. Recognised
measures by function:
fev1, fvc,
fev1fvc, fef2575, fef75.frc, tlc, rv,
rv_tlc, erv, ic,
vc.dlco,
kco_tr, va.tlco, kco_si,
va.Optional BDR – (pft_interpret() only)
<measure>_pre and <measure>_post
columns for fev1, fvc, or
fev1fvc. When both columns of a pair are present,
bronchodilator-response columns are appended for that measure.
<measure>_pre is the baseline
value obtained before bronchodilator administration.<measure>_post is the corresponding value
obtained after bronchodilator administration, according to the
laboratory’s testing protocol.The two columns must hold the same physiologic measure in the same
units, from the same paired pre/post assessment. The caller
assigns these columns. pft does not infer pre/post
status from timestamps, values, medication records, or curve shape; it
interprets the column names literally. The same definitions apply to the
pre and post arguments of
pft_bdr() and pft_bdr_2005().
The canonical types and units are:
| Column | Type | Allowed values / units |
|---|---|---|
sex |
character | "M" or "F". Common variants
("male", "Female", "m", …) are
auto-normalised with a warning. |
age |
numeric | Years (decimal allowed). |
height |
numeric | Centimetres. |
race |
character | One of "Caucasian", "AfrAm",
"NEAsia", "SEAsia",
"Other/mixed". Common synonyms are auto-normalised. (GLI
2012 only.) |
fev1_measured, fvc_measured, etc.
(spirometry) |
numeric | Litres for volumes; L/s for flows; dimensionless for FEV1/FVC. |
frc_measured, tlc_measured, …
(volumes) |
numeric | Litres. rv_tlc_measured is dimensionless. |
dlco_measured, kco_tr_measured,
va_measured (diffusion, SI.units = FALSE, the
default) |
numeric | DLCO in mL/min/mmHg; KCO in mL/min/mmHg/L; VA in L. |
tlco_measured, kco_si_measured,
va_measured (diffusion, SI.units = TRUE) |
numeric | TLCO in mmol/min/kPa; KCO in mmol/min/kPa/L; VA in L. |
<measure>_pre, <measure>_post
(BDR) |
numeric | Same units as <measure>_measured. |
Diffusion units are selected by the caller with
SI.units; the measured diffusion columns must already be in
the selected system. pft does not infer the unit system
from numeric magnitude and does not convert measured values between
systems. Columns from the other system are ignored
(e.g. dlco_measured under SI.units = TRUE).
See vignette("diffusion-capacity").
See the Glossary for definitions of every measure abbreviation.
Decimal precision. No fixed number of decimal places is required for any numeric input. Decimal values are accepted and are used at the precision you supply; inputs do not need to be rounded to the number of decimals shown on a clinical report.
What is checked. pft checks that the
required demographic columns are present (and errors if they are not),
normalises common sex and race spellings with a warning, and computes
reference values only within each source equation’s age range. Rows
outside that range return NA reference values rather than
extrapolated ones:
| Function | Source equations | Age range (years) |
|---|---|---|
pft_spirometry() |
GLI 2012 / GLI Global 2022 | 3-95 (GLI 2012 FEF25-75 and FEF75: 3-90) |
pft_volumes() |
GLI 2021 | 5-80 |
pft_diffusion() |
GLI 2017 | 5-90 |
What is not checked. pft does not
perform general physiologic plausibility screening or technical quality
control of measured values. It does not flag implausible heights,
negative or out-of-range measured values, values entered in the wrong
units, or maneuvers that would fail acceptability review. These checks
depend on the source laboratory, measurement context, units,
demographics, and raw curves, which pft does not see.
A result without an error does not confirm that an input is
clinically plausible or technically acceptable. You are
responsible for validating source data, units, and physiologic
plausibility before interpretation; pft is not a substitute
for laboratory quality control or raw-curve review.
Source populations. Each reference function
documents the population its equations were derived from. The GLI Global
2022 spirometry equations are race-neutral. The GLI 2021 lung-volume
equations were derived from participants of European ancestry, and the
GLI 2017 diffusion equations are described by their source as being for
Caucasians; see the “Applicability” sections of
?pft_volumes and ?pft_diffusion.
If your data frame uses different column names for the demographics,
all reference functions accept sex, age,
height, and (where applicable) race overrides.
Three forms are accepted: a bare column name (the usual tidyverse
style), a string, or an injection from a variable:
patient <- data.frame(
Sex = "M",
Age_y = 45,
Ht_cm = 178,
Ancestry = "Caucasian"
)
# Bare names (tidyverse-style)
pft_spirometry(patient,
sex = Sex,
age = Age_y,
height = Ht_cm,
race = Ancestry)#> # A tibble: 1 × 13
#> Sex Age_y Ht_cm Ancestry fev1_pred_2022 fev1_lln_2022 fev1_uln_2022
#> <chr> <dbl> <dbl> <chr> <dbl> <dbl> <dbl>
#> 1 M 45 178 Caucasian 3.87 2.94 4.75
#> # ℹ 6 more variables: fvc_pred_2022 <dbl>, fvc_lln_2022 <dbl>,
#> # fvc_uln_2022 <dbl>, fev1fvc_pred_2022 <dbl>, fev1fvc_lln_2022 <dbl>,
#> # fev1fvc_uln_2022 <dbl>
# Strings -- equivalent
pft_spirometry(patient,
sex = "Sex",
age = "Age_y",
height = "Ht_cm",
race = "Ancestry")#> # A tibble: 1 × 13
#> Sex Age_y Ht_cm Ancestry fev1_pred_2022 fev1_lln_2022 fev1_uln_2022
#> <chr> <dbl> <dbl> <chr> <dbl> <dbl> <dbl>
#> 1 M 45 178 Caucasian 3.87 2.94 4.75
#> # ℹ 6 more variables: fvc_pred_2022 <dbl>, fvc_lln_2022 <dbl>,
#> # fvc_uln_2022 <dbl>, fev1fvc_pred_2022 <dbl>, fev1fvc_lln_2022 <dbl>,
#> # fev1fvc_uln_2022 <dbl>
# Injection from a variable, e.g. driven by a config
sex_col <- "Sex"
pft_spirometry(patient, sex = !!sex_col,
age = Age_y,
height = Ht_cm,
race = Ancestry)#> # A tibble: 1 × 13
#> Sex Age_y Ht_cm Ancestry fev1_pred_2022 fev1_lln_2022 fev1_uln_2022
#> <chr> <dbl> <dbl> <chr> <dbl> <dbl> <dbl>
#> 1 M 45 178 Caucasian 3.87 2.94 4.75
#> # ℹ 6 more variables: fvc_pred_2022 <dbl>, fvc_lln_2022 <dbl>,
#> # fvc_uln_2022 <dbl>, fev1fvc_pred_2022 <dbl>, fev1fvc_lln_2022 <dbl>,
#> # fev1fvc_uln_2022 <dbl>
The user’s original column names are preserved in
the output (no renaming to canonical). Sex and race values are
normalised in place, so e.g. "male" becomes
"M" in the original Sex column.
The _measured, _pre, and _post
columns are not overridable – they are looked up by name. If your data
uses different names, rename them before calling pft:
required column(s) missing from input: 'race'
– you called pft_spirometry(d, year = 2012) without a
race column. Either supply one (canonical levels:
"Caucasian", "AfrAm", "NEAsia",
"SEAsia", "Other/mixed") or call
pft_spirometry(d, year = 2022) for the race-neutral
equations.
Warning: pft input normalization: ... –
one or more sex or race values were normalised (e.g. "male"
→ "M") or set to NA because they didn’t match any known
canonical value. The warning is consolidated to one message per call and
lists the offending values so you can locate the affected rows.
year = 2012 running but all outputs NA
– check whether the race column contains values outside the
five GLI 2012 categories. Unknown values are set to NA, which propagates
through the reference equations.