Scope
Compute OGTT-based insulin sensitivity indices (Matsuda, Cederholm, Gutt, Stumvoll variants, BIGTT, HIRI_inv, Belfiore, etc.) from glucose/insulin at 0/30/120 minutes plus weight, BMI, age, and sex. Includes validation, missingness policies, optional extreme-value screening on outputs, and optional normalization of the returned indices.
When to use this
- You have OGTT glucose (mmol/L) and insulin (pmol/L) at 0, 30, 120 minutes, plus weight, BMI, age, and sex, and need multiple published insulin sensitivity indices.
- You want consistent NA handling, optional extreme screening on outputs, and optional normalization for modeling pipelines.
What you need (inputs & options)
| Argument | Purpose / Options | Notes |
|---|---|---|
| data | Data frame/tibble with OGTT labs and demographics | Columns mapped via col_map
|
| col_map | Named list mapping required keys | G0/G30/G120 (glucose mmol/L); I0/I30/I120 (insulin pmol/L); weight (kg); bmi (kg/m^2); age (years); sex (1=male, 2=female; 0/1 coerced) |
| normalize | Output normalization method | “none”, “z”, “inverse”, “range”, “robust” (default “none”) |
| na_action | Missing-data policy for required inputs | “keep” (default), “omit”, “error” |
| na_warn_prop | Proportion to trigger high-missingness diagnostics | Default 0.2 (emitted in debug/verbose) |
| check_extreme | Scan outputs for magnitude > extreme_limit
|
Default FALSE |
| extreme_limit | Absolute threshold for output extremes | Default 1e3 |
| extreme_action | Handling for flagged outputs | “warn” (default), “cap”, “error”, “ignore”, “NA” |
| verbose | Emit progress and completion summaries | Default FALSE |
Units: Inputs must already be in mmol/L (glucose) and pmol/L (insulin); weight kg; BMI kg/m^2; age years; sex coded 1/2 (0/1 coerced). The function internally converts glucose to mg/dL (x18) and insulin to muU/mL (/6) where specific formulas require it.
Handling and expectations
- Validation: required columns must exist; non-numeric inputs are coerced with warnings; non-finite values become NA.
- Missingness:
keeppropagates NA;omitdrops rows with any required NA;erroraborts if required inputs contain NA (before computation). - High-missing diagnostics:
na_warn_propcontrols debug/verbose messages on missingness; enableverbose = TRUEto see them. - Unit handling: inputs are expected in mmol/L (glucose) and pmol/L (insulin); internally converted to mg/dL (*18) and muU/mL (/6) where formulas need them.
- Extreme screening (optional): applied after
computing indices; flags |value| >
extreme_limit; handling viaextreme_action(warn/cap/error/ignore/NA). - Normalization (optional): applied after extreme handling via
normalize_vec(); use “none” for raw interpretable values. - Sex coding: expects 1 = male, 2 = female; 0 is treated as female after coercion; other strings become NA.
Outputs
- Returns a tibble with: Isi_120, Cederholm_index, Gutt_index, Avignon_Si0, Avignon_Si120, Avignon_Sim, Modified_stumvoll, Stumvoll_Demographics, Matsuda_AUC, Matsuda_ISI, BigttSi, Ifc_inv, HIRI_inv, Belfiore_isi_gly.
- NA indicates missing/invalid inputs, zero/negative arguments to logs, or values blanked by extreme handling.
Defaults and validation details
- Default
extreme_limit: 1e3; used only whencheck_extreme = TRUE. - Output screening happens before normalization; capped/NA outputs are
then normalized if
normalize != "none". - High-missingness diagnostics are only printed when verbose/debug logging is on.
- Zero/negative inputs to log-based terms become NA by design (safe log guard).
Worked example 1: Basic usage (raw outputs)
library(HealthMarkers)
library(tibble)
df <- tibble::tibble(
G0 = 5.5, I0 = 60,
G30 = 7.8, I30 = 90,
G120 = 6.2, I120 = 50,
weight = 70, bmi = 24, age = 30, sex = 1
)
ogtt_is(
data = df,
col_map = list(
G0 = "G0", I0 = "I0",
G30 = "G30", I30 = "I30",
G120 = "G120", I120 = "I120",
weight = "weight", bmi = "bmi",
age = "age", sex = "sex"
),
normalize = "none",
na_action = "keep",
check_extreme = FALSE
)
#> # A tibble: 1 × 14
#> Isi_120 Cederholm_index Gutt_index Avignon_Si0 Avignon_Si120 Avignon_Sim
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 10.8 1.10 2.67 9.62 10.2 9.93
#> # ℹ 8 more variables: Modified_stumvoll <dbl>, Stumvoll_Demographics <dbl>,
#> # Matsuda_AUC <dbl>, Matsuda_ISI <dbl>, BigttSi <dbl>, Ifc_inv <dbl>,
#> # HIRI_inv <dbl>, Belfiore_isi_gly <dbl>Interpretation: Returns all indices with NA only where inputs are missing or non-finite.
Worked example 2: Extreme scan, capping, and z-normalization
ogtt_is(
data = df,
col_map = list(
G0 = "G0", I0 = "I0",
G30 = "G30", I30 = "I30",
G120 = "G120", I120 = "I120",
weight = "weight", bmi = "bmi",
age = "age", sex = "sex"
),
normalize = "z",
na_action = "keep",
check_extreme = TRUE,
extreme_limit = 1e3,
extreme_action = "cap",
verbose = TRUE
)
#> # A tibble: 1 × 14
#> Isi_120 Cederholm_index Gutt_index Avignon_Si0 Avignon_Si120 Avignon_Sim
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 0 0 0 0 0 0
#> # ℹ 8 more variables: Modified_stumvoll <dbl>, Stumvoll_Demographics <dbl>,
#> # Matsuda_AUC <dbl>, Matsuda_ISI <dbl>, BigttSi <dbl>, Ifc_inv <dbl>,
#> # HIRI_inv <dbl>, Belfiore_isi_gly <dbl>Interpretation: Outputs are capped at +/- 1000 before z-scaling; verbose logs summarize extreme counts.
Troubleshooting & common pitfalls
- Missing YAML: ensure this header stays at the top; Markdown before it will break knitting.
- Missing columns: every required
col_mapkey must exist indataand be mapped. - Units: inputs must be mmol/L (glucose) and pmol/L (insulin); only internal conversions are applied for formulas.
- Sex coding: expects 1/2; 0/1 are coerced; other strings become NA and propagate.
- Extreme handling: only applied when
check_extreme = TRUE, and only after computing indices. - All NA outputs: usually missing required inputs, zero/negative values passed to logs, or NA produced by normalization after NA inputs.
Verbose diagnostics
old_opt <- options(healthmarkers.verbose = "inform")
ogtt_is(
data = df,
col_map = list(
G0 = "G0", I0 = "I0",
G30 = "G30", I30 = "I30",
G120 = "G120", I120 = "I120",
weight = "weight", bmi = "bmi",
age = "age", sex = "sex"
),
normalize = "none",
verbose = TRUE
)
#> ogtt_is(): preparing inputs
#> ogtt_is(): column map: G0 -> 'G0', I0 -> 'I0', G30 -> 'G30', I30 -> 'I30', G120 -> 'G120', I120 -> 'I120', weight -> 'weight', bmi -> 'bmi', age -> 'age', sex -> 'sex'
#> ogtt_is(): results: Isi_120 1/1, Cederholm_index 1/1, Gutt_index 1/1, Avignon_Si0 1/1, Avignon_Si120 1/1, Avignon_Sim 1/1, Modified_stumvoll 1/1, Stumvoll_Demographics 1/1, Matsuda_AUC 1/1, Matsuda_ISI 1/1, BigttSi 1/1, Ifc_inv 1/1, HIRI_inv 1/1, Belfiore_isi_gly 1/1
#> # A tibble: 1 × 14
#> Isi_120 Cederholm_index Gutt_index Avignon_Si0 Avignon_Si120 Avignon_Sim
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 10.8 1.10 2.67 9.62 10.2 9.93
#> # ℹ 8 more variables: Modified_stumvoll <dbl>, Stumvoll_Demographics <dbl>,
#> # Matsuda_AUC <dbl>, Matsuda_ISI <dbl>, BigttSi <dbl>, Ifc_inv <dbl>,
#> # HIRI_inv <dbl>, Belfiore_isi_gly <dbl>
options(old_opt)Tips for best results
- Keep
normalize = "none"for clinical interpretation; use “z” or “robust” only when scaling is needed for modeling. - Use
na_action = "omit"for modeling-ready datasets;keepfor exploratory review. - Start with
check_extreme = TRUE,extreme_action = "warn"to gauge outliers; tighten tocaporerrorif needed. - Inspect distributions of glucose and insulin values to catch unit errors before running.
Validation notes
- Glucose values are multiplied by 18 and insulin divided by 6 inside formulas that require mg/dL or muU/mL.
- Logs are safe: nonpositive arguments become NA.
- Extreme handling and normalization occur after computing raw indices; disable both to mirror published formulas.
See also
- Function documentation:
?ogtt_is,?normalize_vec - Related vignettes: fasting_is, health_markers, glycemic_markers