Skip to contents

Scope

Create pediatric-friendly binary risk flags (dyslipidemia, insulin resistance, hyperglycemia, hypertension) from routine labs and BP z-scores with configurable NA and extreme handling.

When to use

  • You have lipid panel, glucose/HbA1c, BP z-scores, age, and z-scored HOMA-IR and want quick binary risk features.
  • You need NA policies, high-missingness warnings, and optional extreme-value screening/capping built in.
  • You are working in pediatrics/adolescents where triglyceride thresholds differ by age and BP is already standardized.

Inputs

  • data: data.frame/tibble with required numeric inputs.
  • col_map: named list mapping required keys (defaults to same names): chol_total, chol_ldl, chol_hdl, triglycerides, age_year, z_HOMA, glucose, HbA1c, bp_sys_z, bp_dia_z.
  • Units assumed: lipids mmol/L; glucose mmol/L; HbA1c mmol/mol (IFCC); BP inputs already z-scores; age in years; z_HOMA is a z-scored HOMA-IR.
  • na_action: keep (default) propagates NA; omit drops rows missing required inputs; error aborts; ignore acts like keep; warn acts like keep plus high-missingness warnings via na_warn_prop (default 0.2).
  • check_extreme: set TRUE to scan using extreme_action (warn/cap/error/ignore/NA) with default bounds unless overridden by extreme_rules (defaults: chol_total 0.5–20; chol_ldl 0.1–15; chol_hdl 0.1–5; triglycerides 0.1–30; age_year 0–120; z_HOMA -5–5; glucose 2–40; HbA1c 15–200; bp_sys_z/bp_dia_z -5–5).

Quick start

library(HealthMarkers)
library(tibble)

peds <- tibble::tibble(
  chol_total = c(5.4, 4.8),
  chol_ldl   = c(3.6, 2.9),
  chol_hdl   = c(0.9, 1.2),
  triglycerides = c(1.6, 1.0),
  age_year   = c(15, 9),
  z_HOMA     = c(1.5, 0.8),
  glucose    = c(5.8, 5.1),
  HbA1c      = c(40, 35),
  bp_sys_z   = c(1.2, 1.8),
  bp_dia_z   = c(0.5, 1.7)
)

metabolic_risk_features(
  data = peds,
  col_map = list(
    chol_total = "chol_total", chol_ldl = "chol_ldl", chol_hdl = "chol_hdl", triglycerides = "triglycerides",
    age_year = "age_year", z_HOMA = "z_HOMA", glucose = "glucose", HbA1c = "HbA1c",
    bp_sys_z = "bp_sys_z", bp_dia_z = "bp_dia_z"
  ),
  na_action = "keep"
)
#> # A tibble: 2 × 4
#>   dyslipidemia insulin_resistance hyperglycemia hypertension
#>   <fct>        <fct>              <fct>         <fct>       
#> 1 1            1                  1             0           
#> 2 0            0                  0             1

Scan, cap, and warn

extreme <- peds
extreme$triglycerides[1] <- 40  # high
extreme$bp_sys_z[2] <- 9        # out of range

metabolic_risk_features(
  data = extreme,
  col_map = list(
    chol_total = "chol_total", chol_ldl = "chol_ldl", chol_hdl = "chol_hdl", triglycerides = "triglycerides",
    age_year = "age_year", z_HOMA = "z_HOMA", glucose = "glucose", HbA1c = "HbA1c",
    bp_sys_z = "bp_sys_z", bp_dia_z = "bp_dia_z"
  ),
  na_action = "warn",
  check_extreme = TRUE,
  extreme_action = "cap",
  verbose = TRUE
)
#> # A tibble: 2 × 4
#>   dyslipidemia insulin_resistance hyperglycemia hypertension
#>   <fct>        <fct>              <fct>         <fct>       
#> 1 1            1                  1             0           
#> 2 0            0                  0             1

Missing data policy

missing <- peds
missing$glucose[2] <- NA

metabolic_risk_features(
  data = missing,
  col_map = list(chol_total = "chol_total", chol_ldl = "chol_ldl", chol_hdl = "chol_hdl", triglycerides = "triglycerides",
                 age_year = "age_year", z_HOMA = "z_HOMA", glucose = "glucose", HbA1c = "HbA1c",
                 bp_sys_z = "bp_sys_z", bp_dia_z = "bp_dia_z"),
  na_action = "omit"
)
#> # A tibble: 1 × 4
#>   dyslipidemia insulin_resistance hyperglycemia hypertension
#>   <fct>        <fct>              <fct>         <fct>       
#> 1 1            1                  1             0

metabolic_risk_features(
  data = missing,
  col_map = list(chol_total = "chol_total", chol_ldl = "chol_ldl", chol_hdl = "chol_hdl", triglycerides = "triglycerides",
                 age_year = "age_year", z_HOMA = "z_HOMA", glucose = "glucose", HbA1c = "HbA1c",
                 bp_sys_z = "bp_sys_z", bp_dia_z = "bp_dia_z"),
  na_action = "warn"
)
#> # A tibble: 2 × 4
#>   dyslipidemia insulin_resistance hyperglycemia hypertension
#>   <fct>        <fct>              <fct>         <fct>       
#> 1 1            1                  1             0           
#> 2 0            0                  NA            1

Expanded example: cap extremes, drop incomplete rows

ext_cap <- peds
ext_cap$triglycerides[1] <- 40   # extreme high
ext_cap$bp_sys_z[2] <- 9         # extreme high
ext_cap$HbA1c[2] <- NA           # missing HbA1c to trigger drop

out_cap <- metabolic_risk_features(
  data = ext_cap,
  col_map = list(
    chol_total = "chol_total", chol_ldl = "chol_ldl", chol_hdl = "chol_hdl", triglycerides = "triglycerides",
    age_year = "age_year", z_HOMA = "z_HOMA", glucose = "glucose", HbA1c = "HbA1c",
    bp_sys_z = "bp_sys_z", bp_dia_z = "bp_dia_z"
  ),
  na_action = "omit",
  check_extreme = TRUE,
  extreme_action = "cap",
  verbose = TRUE
)

list(rows_returned = nrow(out_cap), flags = out_cap)
#> $rows_returned
#> [1] 1
#> 
#> $flags
#> # A tibble: 1 × 4
#>   dyslipidemia insulin_resistance hyperglycemia hypertension
#>   <fct>        <fct>              <fct>         <fct>       
#> 1 1            1                  1             0

Threshold quick-reference

Flag Logic (values in mmol/L unless noted)
Dyslipidemia CT > 5.2 OR LDL > 3.4 OR HDL < 1.0 OR TG > 1.1 (age 0–9) OR TG > 1.5 (age 10–19)
Insulin resistance z_HOMA > 1.28 (≈90th percentile)
Hyperglycemia Glucose 5.6–6.9 OR HbA1c 39–47 mmol/mol
Hypertension BP z-score > 1.64 (systolic or diastolic)

Handling and outputs

  • Missingness: keep/ignore propagate NA; omit drops rows with missing required inputs; warn logs high-missingness; error aborts on missing required inputs.
  • Extreme values: with check_extreme = TRUE, scan against defaults or extreme_rules; choose extreme_action to warn, cap, NA, ignore, or error.
  • Outputs: tibble with factor columns dyslipidemia, insulin_resistance, hyperglycemia, hypertension (levels 0/1). Age-based TG cutoffs: >1.1 mmol/L (0–9 y) or >1.5 mmol/L (10–19 y) for dyslipidemia; BP z > 1.64 for hypertension; z_HOMA > 1.28 for insulin resistance; glucose 5.6–6.9 or HbA1c 39–47 for hyperglycemia.

Verbose diagnostics

old_opt <- options(healthmarkers.verbose = "inform")
metabolic_risk_features(
  data = peds,
  col_map = list(
    chol_total = "chol_total", chol_ldl = "chol_ldl", chol_hdl = "chol_hdl",
    triglycerides = "triglycerides", age_year = "age_year", z_HOMA = "z_HOMA",
    glucose = "glucose", HbA1c = "HbA1c", bp_sys_z = "bp_sys_z", bp_dia_z = "bp_dia_z"
  ),
  verbose = TRUE
)
#> metabolic_risk_features(): preparing inputs
#> metabolic_risk_features(): column map: chol_total -> 'chol_total', chol_ldl -> 'chol_ldl', chol_hdl -> 'chol_hdl', triglycerides -> 'triglycerides', age_year -> 'age_year', z_HOMA -> 'z_HOMA', glucose -> 'glucose', HbA1c -> 'HbA1c', bp_sys_z -> 'bp_sys_z', bp_dia_z -> 'bp_dia_z'
#> metabolic_risk_features(): results: dyslipidemia 2/2, insulin_resistance 2/2, hyperglycemia 2/2, hypertension 2/2
#> # A tibble: 2 × 4
#>   dyslipidemia insulin_resistance hyperglycemia hypertension
#>   <fct>        <fct>              <fct>         <fct>       
#> 1 1            1                  1             0           
#> 2 0            0                  0             1
options(old_opt)

Tips

  • Keep lipids/glucose in mmol/L and HbA1c in mmol/mol; BP inputs must already be z-scores.
  • Tighten extreme_rules to your cohort before using extreme_action = "cap" or "error".
  • Use na_action = "omit" for analysis-ready flags; keep/warn during QA to inspect missingness.
  • Watch for HbA1c reported in % (values <=14 suggest percent) and lipids/glucose in mg/dL (would appear ~×38.7 or ×18 higher); standardize units before calling.
  • BP inputs must already be z-scores; large magnitude (|z| > 5) usually indicates scaling issues.