Scope
Compute ALM/BMI and flag low muscle mass using FNIH cut-points (men < 0.789; women < 0.512) with optional NA and extreme handling.
When to use this
- You need a quick sarcopenia risk flag based on ALM relative to body size.
- You have ALM (kg), BMI (kg/m^2), and sex, and want FNIH cut-points applied automatically.
- You want the option to cap implausible ALM/BMI values and control missing-data policy.
What you need (rich guide)
- Required columns:
alm(kg),bmi(kg/m^2),sex(m/f/1/0; other values yieldNAfor the flag). - Defaults: ALM in kg, BMI in kg/m^2. No unit conversion is performed.
- Policies:
na_action(keep/warn/ignorebehave like keep;omitdrops;erroraborts).check_extreme+extreme_actioncan cap/NA/error on implausible ALM/BMI. - FNIH cut-points are built in; nothing to configure beyond column mapping.
Load packages and data
Use a small subset of the simulated data. Here we derive a simple ALM proxy for illustration.
library(HealthMarkers)
library(dplyr)
sim_path <- system.file("extdata", "simulated_hm_data.rds", package = "HealthMarkers")
sim <- readRDS(sim_path)
sim_small <- dplyr::slice_head(sim, n = 30)
# Example proxy for ALM (replace with measured ALM when available)
sim_small <- sim_small %>%
mutate(ALM_kg = pmax(10, pmin(35, weight * 0.35)))Column map
Map your columns; sex is normalized by first letter (m/f/1/0).
col_map <- list(
alm = "ALM_kg",
bmi = "BMI",
sex = "sex"
)Walkthrough (compute ALM/BMI and flag)
alm_out <- alm_bmi_index(
data = sim_small,
col_map = col_map,
na_action = "keep",
check_extreme = FALSE,
verbose = FALSE
)
alm_out %>%
slice_head(n = 5) %>%
select(alm_bmi_ratio, low_muscle_mass)
#> # A tibble: 5 × 2
#> alm_bmi_ratio low_muscle_mass
#> <dbl> <lgl>
#> 1 0.929 FALSE
#> 2 0.964 FALSE
#> 3 1.16 FALSE
#> 4 0.941 FALSE
#> 5 1.00 FALSEInterpretation: alm_bmi_ratio is ALM/BMI.
low_muscle_mass is TRUE if below the
sex-specific FNIH cut-point; NA if sex or ratio is
NA.
Missing data and extremes
Compare NA handling and optional capping.
demo <- sim_small[1:8, c("ALM_kg", "BMI", "sex")]
demo$ALM_kg[3] <- NA
demo$BMI[4] <- 2 # implausible, will be capped
alm_keep <- alm_bmi_index(
data = demo,
col_map = col_map,
na_action = "keep",
check_extreme = TRUE,
extreme_action = "cap",
extreme_rules = list(alm = c(5, 40), bmi = c(10, 60)),
verbose = FALSE
)
alm_omit <- alm_bmi_index(
data = demo,
col_map = col_map,
na_action = "omit",
check_extreme = TRUE,
extreme_action = "cap",
extreme_rules = list(alm = c(5, 40), bmi = c(10, 60)),
verbose = FALSE
)
list(
keep_rows = nrow(alm_keep),
omit_rows = nrow(alm_omit),
preview = alm_keep %>% select(alm_bmi_ratio, low_muscle_mass) %>% slice_head(n = 3)
)
#> $keep_rows
#> [1] 8
#>
#> $omit_rows
#> [1] 7
#>
#> $preview
#> # A tibble: 3 × 2
#> alm_bmi_ratio low_muscle_mass
#> <dbl> <lgl>
#> 1 0.929 FALSE
#> 2 0.964 FALSE
#> 3 NA NAVerbose diagnostics
Set verbose = TRUE to emit three structured messages per
call:
- Preparing inputs — start-of-function signal.
-
Column map — confirms which data column each
required key (
alm,bmi,sex) resolved to. Example:alm_bmi_index(): column map: alm -> 'ALM_kg', bmi -> 'BMI', sex -> 'Sex' -
Results summary — shows how many rows computed
successfully (non-NA) per output column. Example:
alm_bmi_index(): results: alm_bmi_index 30/30, low_alm_bmi_flag 30/30, ...
verbose = TRUE emits at the "inform" level;
you also need options(healthmarkers.verbose = "inform")
active:
old_opt <- options(healthmarkers.verbose = "inform")
df_v <- data.frame(
ALM_kg = c(14.0, 9.5),
BMI = c(24.0, 22.0),
Sex = c("male", "female")
)
alm_bmi_index(df_v,
col_map = list(alm = "ALM_kg", bmi = "BMI", sex = "Sex"),
verbose = TRUE)
#> alm_bmi_index(): preparing inputs
#> alm_bmi_index(): column map: alm -> 'ALM_kg', bmi -> 'BMI', sex -> 'Sex'
#> alm_bmi_index(): results: alm_bmi_ratio 2/2, low_muscle_mass 2/2
#> # A tibble: 2 × 2
#> alm_bmi_ratio low_muscle_mass
#> <dbl> <lgl>
#> 1 0.583 TRUE
#> 2 0.432 TRUE
options(old_opt)Reset with options(healthmarkers.verbose = NULL) or
"none".
Expectations
- Required columns must be mapped; missing columns abort.
-
na_actioncontrols row handling (keep/warn/ignorebehave like keep;omitdrops;erroraborts). -
check_extremescreens raw ALM/BMI;extreme_actioncan warn/cap/NA/error; tuneextreme_rulesto your lab limits. - Sex must normalize to m/f/1/0 for the flag to evaluate; otherwise
the flag is
NA.
Common pitfalls
- Feeding ALM in pounds or BMI in non-metric units will misclassify; keep ALM in kg and BMI in kg/m^2.
- A single implausible BMI (e.g., <=0) zeroes the ratio; enable
check_extremeto cap or NA such inputs. - Using an ALM proxy (like weight * 0.35) is illustrative only; use measured ALM when possible.
-
na_action = keepleaves missing inputs asNA; chooseomitfor stricter pipelines.
Validation notes
- Spot-check one row: ratio = ALM/BMI; compare to FNIH thresholds
(0.789 men, 0.512 women) to verify
low_muscle_mass. - With
check_extreme = TRUEandextreme_action = cap, ALM/BMI will be truncated into your specified ranges before the ratio. - Expect
low_muscle_massto beNAwhen sex cannot be normalized.
See also
-
adiposity_sds()/adiposity_sds_strat()for standardizing BMI or related measures. -
frailty_index()for a broader frailty construct.