Skip to contents

Scope

Compute spirometry interpretive markers: pre/post FEV1/FVC ratios, fixed-ratio obstruction flag (0.70), optional GLI percent-predicted/z/LLN/GOLD when demographics and rspiro are available (falls back to simple refs if not), and bronchodilator response deltas (%). Includes mapping validation, NA policies, optional extreme screening/capping on volumes, and safe handling of zero/negative values and ratios > 1 warnings.

When to use this

  • You have spirometry volumes (FEV1, FVC) in liters and optionally post-bronchodilator values.
  • You want obstruction flags by fixed ratio and, when possible, LLN/GOLD using GLI references.
  • You need controlled NA handling, optional outlier checks/capping, and post-bronchodilator response calculations.

What you need (inputs & options)

Argument Purpose / Options Notes
data Data frame/tibble with spirometry Volumes must be in liters
col_map Named list mapping columns Required: fev1, fvc; Optional: fev1_post, fvc_post, age, height, sex, ethnicity
na_action Missing-data policy for required fev1/fvc “keep” (default), “omit”, “error”, “ignore”, “warn”
check_extreme Scan inputs against bounds Default FALSE
extreme_action Handling for extremes “warn” (default), “cap”, “error”, “ignore”, “NA”
extreme_rules Bounds list c(min, max) per input Default fev1 0–8 L, fvc 0–10 L
verbose Emit progress messages Default FALSE

Units: Inputs must be liters. No unit conversion is performed.

GLI inputs (optional): age (years), height (cm), sex (male/female or 1/0/2), ethnicity (GLI-compatible strings). Requires rspiro; otherwise a debug fallback reference is used or GLI fields stay NA.

Handling and expectations

  • Validation & coercion: required columns must exist; non-numeric volumes are coerced with warnings; non-finite become NA.
  • Missingness: keep/ignore/warn propagate NA; omit drops rows with required NA; error aborts if required NA.
  • Extreme screening (optional): bounds on fev1/fvc; extreme_action controls warn/cap/error/ignore/NA. Defaults cap to 0–8/0–10 only if enabled.
  • Domain warnings: zero FVC -> ratio NA with warning; negative volumes warn; ratios > 1 warn to check units.
  • GLI references: used only when age/height/sex/ethnicity provided and rspiro available; else a simple fallback is used (debug) or GLI outputs remain NA. Ethnicity mapped to GLI categories; sex mapped from first letter/1/0/2.
  • GOLD grade: computed only when obstruction_lln is TRUE; uses fev1 percent-predicted thresholds.
  • Bronchodilator response: percent change (post - pre) / pre * 100; requires both pre and post columns.
  • Padding: if rows are omitted under na_action = "omit", outputs are padded back to input row count when NA policy keeps rows.

Defaults and validation details

  • Default extreme bounds: fev1 0–8 L, fvc 0–10 L (applied only when check_extreme = TRUE).
  • GLI mapping: sex strings starting with m/1 -> Male; f/0/2 -> Female; ethnicity regex maps to GLI categories (Caucasian, African American, North East Asian, South East Asian, Other).
  • Fallback reference (if rspiro unavailable): rough height/age equations for testability; not clinical—aimed to avoid all-NA outputs in tests.
  • High-missing diagnostics are not emitted unless verbose/debug logging is enabled via hm_inform.
  • Empty result: if na_action = "omit" drops all rows, returns a zero-row tibble with expected columns.

Outputs

  • Columns: ratio_pre, ratio_post, copd_flag_fixed, obstruction_lln, fev1_pp, fvc_pp, fev1_z, fvc_z, ratio_z, gold_grade, bdr_fev1, bdr_fvc.
  • NA arises when required inputs are missing, ratios are undefined (e.g., zero FVC), GLI inputs are absent/invalid, or post values are missing for deltas.

Worked example 1: Basic fixed-ratio outputs

library(HealthMarkers)
library(tibble)

df <- tibble::tibble(
  FEV1 = c(2.8, 1.6, NA),
  FVC  = c(3.6, 2.1, 3.0)
)

spirometry_markers(
  data = df,
  col_map = list(fev1 = "FEV1", fvc = "FVC"),
  na_action = "keep"
)
#> # A tibble: 3 × 12
#>   ratio_pre ratio_post copd_flag_fixed obstruction_lln fev1_pp fvc_pp fev1_z
#>       <dbl>      <dbl> <lgl>           <lgl>             <dbl>  <dbl>  <dbl>
#> 1     0.778         NA FALSE           NA                   NA     NA     NA
#> 2     0.762         NA FALSE           NA                   NA     NA     NA
#> 3    NA             NA NA              NA                   NA     NA     NA
#> # ℹ 5 more variables: fvc_z <dbl>, ratio_z <dbl>, gold_grade <chr>,
#> #   bdr_fev1 <dbl>, bdr_fvc <dbl>

Interpretation: Returns pre FEV1/FVC ratios and fixed-ratio flags; NA propagates where inputs are missing.

Worked example 2: With post-BD, GLI inputs, cap extremes

df2 <- tibble::tibble(
  fev1_pre = c(2.1, 0.9, 7.5),
  fvc_pre  = c(3.0, 1.8, 11.0),
  fev1_post = c(2.4, 1.1, 7.2),
  fvc_post  = c(3.2, 1.9, 10.5),
  age = c(55, 72, 45),
  height = c(170, 160, 182),
  sex = c("male", "female", "male"),
  ethnicity = c("Caucasian", "African American", "Other")
)

cm2 <- list(
  fev1 = "fev1_pre",
  fvc = "fvc_pre",
  fev1_post = "fev1_post",
  fvc_post = "fvc_post",
  age = "age",
  height = "height",
  sex = "sex",
  ethnicity = "ethnicity"
)

spirometry_markers(
  data = df2,
  col_map = cm2,
  check_extreme = TRUE,
  extreme_action = "cap",
  na_action = "keep",
  verbose = TRUE
)
#> # A tibble: 3 × 12
#>   ratio_pre ratio_post copd_flag_fixed obstruction_lln fev1_pp fvc_pp fev1_z
#>       <dbl>      <dbl> <lgl>           <lgl>             <dbl>  <dbl>  <dbl>
#> 1      0.7       0.75  FALSE           FALSE              40.8   42.1  -5.92
#> 2      0.5       0.579 TRUE            TRUE               23.7   31.2  -7.63
#> 3      0.75      0.686 TRUE            TRUE              126.   125.    2.65
#> # ℹ 5 more variables: fvc_z <dbl>, ratio_z <dbl>, gold_grade <chr>,
#> #   bdr_fev1 <dbl>, bdr_fvc <dbl>

Interpretation: Extremes are capped before ratios; GLI fields are computed when rspiro is available, otherwise fall back or remain NA. Bronchodilator deltas are percent changes pre→post.

Worked example 3: Strict missing policy

try(
  spirometry_markers(
    data = df,
    col_map = list(fev1 = "FEV1", fvc = "FVC"),
    na_action = "error"
  )
)
#> Error in spirometry_markers(data = df, col_map = list(fev1 = "FEV1", fvc = "FVC"),  : 
#>   spirometry_markers(): required inputs contain missing values (na_action='error').

Interpretation: Aborts when required inputs contain NA.

Troubleshooting & common pitfalls

  • YAML/header: keep YAML at the top; stray text before it breaks knitting.
  • Units: volumes must be liters; convert upstream. Ratios > 1 often indicate unit issues.
  • Missing columns: ensure fev1 and fvc are mapped; post and GLI inputs are optional.
  • GLI availability: requires rspiro plus age/height/sex/ethnicity; otherwise GLI outputs may be NA or use fallback approximations.
  • Zero/negative volumes: produce warnings; zero FVC yields NA ratios.
  • Outliers: enable check_extreme with extreme_action = "cap" or "NA" to constrain implausible volumes.

Verbose diagnostics

Enable verbose output to inspect column mapping, row counts, and result summaries during QC:

old_opt <- options(healthmarkers.verbose = "inform")
spirometry_markers(
  data.frame(FEV1 = 2.8, FVC = 3.5),
  col_map = list(fev1 = "FEV1", fvc = "FVC"),
  verbose = TRUE
)
#> spirometry_markers(): preparing inputs
#> spirometry_markers(): column map: fev1 -> 'FEV1', fvc -> 'FVC'
#> spirometry_markers(): results: ratio_pre 1/1, ratio_post 0/1, copd_flag_fixed 1/1, obstruction_lln 0/1, fev1_pp 0/1, fvc_pp 0/1, fev1_z 0/1, fvc_z 0/1, ratio_z 0/1, gold_grade 0/1, bdr_fev1 0/1, bdr_fvc 0/1
#> # A tibble: 1 × 12
#>   ratio_pre ratio_post copd_flag_fixed obstruction_lln fev1_pp fvc_pp fev1_z
#>       <dbl>      <dbl> <lgl>           <lgl>             <dbl>  <dbl>  <dbl>
#> 1       0.8         NA FALSE           NA                   NA     NA     NA
#> # ℹ 5 more variables: fvc_z <dbl>, ratio_z <dbl>, gold_grade <chr>,
#> #   bdr_fev1 <dbl>, bdr_fvc <dbl>
options(old_opt)

Tips for best results

  • Provide demographics and install rspiro when GLI-based percent-predicted and GOLD grades are needed; otherwise rely on fixed 0.70 flag.
  • Use na_action = "omit" for modeling datasets that require complete spirometry; keep/warn for exploratory review.
  • Review ratios > 1 or negative volumes—these usually indicate unit or entry errors.
  • For bronchodilator response, supply both pre and post volumes; otherwise response outputs are NA.

Validation notes

  • Ratio: FEV1 / FVC; fixed obstruction flag uses 0.70 (prefers post values when present).
  • Bronchodilator response: 100 * (post - pre) / pre for FEV1 and FVC.
  • GOLD stage uses fev1 percent-predicted when obstruction_lln is TRUE; relies on GLI or fallback references.
  • Fallback references are non-clinical and intended only to avoid all-NA outputs when rspiro is absent.

See also

  • Function docs: ?spirometry_markers
  • Related vignettes: pulmo_markers, health_markers, health_summary