---
title: "Get started with essential8"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Get started with essential8}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

## Overview

`essential8` computes component and composite Life's Essential 8 (LE8)
cardiovascular health scores. The current implementation scores adults aged
20 years or older using the American Heart Association's 2022 definition.
Pediatric scoring is not yet available.

This vignette shows complete and incomplete-data workflows. See `?score_le8`
for the full input contract and scoring details.

## Create an adult data frame

Supply one row per person. The example below includes two
adults with raw responses to the 16-item Mediterranean Eating Pattern for
Americans (MEPA) screener. It also demonstrates both possible BMI profiles and both possible glucose measures.

```{r create-data}
library(essential8)

adult_data <- data.frame(
  id = c("patient_1", "patient_2"),
  age = c(42, 61),
  sex = c("female", "male"),
  # Daily servings
  olive_oil = c(2, 1),
  green_leafy_vegetables = c(1, 0.5),
  other_vegetables = c(2, 1),
  whole_grains = c(2, 1),
  # Weekly servings
  berries = c(3, 1),
  other_fruit = c(5, 2),
  meat = c(2, 5),
  fish = c(3, 1),
  chicken = c(2, 4),
  cheese = c(1, 4),
  butter_cream = c(1, 5),
  beans = c(3, 1),
  sweets_and_pastries = c(1, 5),
  nuts = c(4, 1),
  fast_food = c(0, 2),
  alcohol = c(4, 0),
  moderate_activity_minutes = c(100, 60),
  vigorous_activity_minutes = c(25, 0),
  smoking_status = c("never", "former"),
  years_since_quit = c(0, 6),
  current_inhaled_nds = c(FALSE, FALSE),
  secondhand_smoke_home = c(FALSE, FALSE),
  sleep_hours = c(7.5, 6.5),
  bmi = c(24.2, 24.0),
  bmi_profile = c("general", "asian_pacific"),
  non_hdl_cholesterol = c(125, 145),
  lipid_lowering_treatment = c(FALSE, TRUE),
  diabetes = c(FALSE, FALSE),
  glucose_measure = c("fasting_glucose", "hba1c"),
  glucose_value = c(95, 6.0),
  systolic_bp = c(118, 132),
  diastolic_bp = c(76, 84),
  antihypertensive_treatment = c(FALSE, TRUE)
)
```

## Compute LE8 scores

Pass the data frame to `score_le8()`. The returned data frame retains the
input columns and appends the derived activity measure, eight component
scores, the number of contributing components, composite score, completeness
indicator, and category.

```{r score-data}
scored <- score_le8(adult_data, diet_method = "mepa")

scored[c(
  "id",
  "mepa_total",
  "le8_diet_score",
  "physical_activity_moderate_equivalent_minutes",
  "le8_composite_score",
  "le8_category"
)]
```

Each vigorous activity minute counts as two moderate activity minutes and is
recorded as `physical_activity_moderate_equivalent_minutes`. The
`le8_composite_score` is the mean of the eight component scores for complete
records. Categories are `"low"` below 50, `"moderate"` from 50 to less than
80, and `"high"` at 80 or higher.

The component scores are available for analysis and quality checks:

```{r component-scores}
component_columns <- setdiff(
  grep("^le8_.*_score$", names(scored), value = TRUE),
  "le8_composite_score"
)

scored[c("id", component_columns)]
```

## Understand the MEPA inputs

The MEPA response columns use the 16 screener-item labels in snake case. The
column names should reflect as seen below, but you can map custom columns using
`mepa_columns = c()`.

- `olive_oil`, `green_leafy_vegetables`, `other_vegetables`, and
  `whole_grains` are servings per day.
- `berries`, `other_fruit`, `meat`, `fish`, `chicken`, `cheese`,
  `butter_cream`, `beans`, `sweets_and_pastries`, `nuts`, and `alcohol` are
  servings per week.
- `fast_food` is the number of times per week that meals are consumed from
  fast-food restaurants.

The screener defines `meat` as red meat, hamburger, bacon, or sausage;
`fish` includes fish, shellfish, or seafood; and `cheese` means full-fat or
regular cheese or cream cheese.

`score_le8()` evaluates each criterion and returns their sum as `mepa_total`
so that the derived diet input can be audited. The default MEPA sex field is
`sex`. If `sex` is absent, a field named `female` is
recognized automatically; map any other name with, for example,
`mepa_columns = c(sex = "reported_sex")`. Values are trimmed and matched
case-insensitively as `"m"`/`"f"` or `"male"`/`"female"`. Numeric or character
`0`/`1` values are also accepted, where `0` is male and `1` is female.

## Choose other input methods explicitly

The `diet_method` argument defaults to `"mepa"`. If a source data set
contains both MEPA and percentile inputs, split the rows into separate data
frames and call `score_le8()` separately for each method.

- For `diet_method = "mepa"`, `diet_value` must be absent or contain only
  missing values.
- For `diet_method = "percentile"`, MEPA columns are ignored. Supply
  `diet_value` as a DASH or HEI-2015 percentile from 1 to 100, calculated
  against the relevant reference population before calling `score_le8()`.
  If it is absent or missing, the diet component cannot be scored.
- Set `bmi_profile` to either `"general"` or `"asian_pacific"`. The function
  does not infer a BMI profile from race or ethnicity.
- Set `glucose_measure` to `"fasting_glucose"` for a value in mg/dL or
  `"hba1c"` for a percentage. Diagnosed diabetes requires HbA1c for scoring.

The percentile workflow is executable without removing the unused MEPA columns:

```{r percentile}
percentile_data <- adult_data[1, , drop = FALSE]
percentile_data$diet_value <- 95
percentile_scores <- score_le8(
  percentile_data,
  diet_method = "percentile"
)
percentile_scores[
  c("diet_value", "le8_diet_score", "le8_composite_score")
]
```

Three optional, caller-adjudicated flags control clinical-judgment adjustments:
`apply_lean_muscular_bmi_override`, `apply_sleep_apnea_penalty`, and
`apply_prediabetes_metformin_penalty`. When these columns are absent, their
adjustments are not applied.

## Work with incomplete component data

Component inputs may be missing for individual adults. Component-specific
columns may also be omitted when an entire domain is unavailable. The package
does not impute missing data, convert units, or round raw measurements before
scoring. `age` remains required and complete because the package must establish
that every record is eligible for adult scoring.

By default, `score_le8()` calculates the composite when at least seven of the
eight component scores are available. Choose any threshold from 1 through 8
with `min_components`. The composite is the mean of the available components
when the threshold is met.

```{r incomplete-data}
incomplete_data <- adult_data
incomplete_data$sleep_hours[1] <- NA_real_
incomplete_data$bmi[2] <- NA_real_

incomplete_scores <- score_le8(
  incomplete_data,
  min_components = 7
)

incomplete_scores[c(
  "id",
  "le8_composite_score",
  "le8_n_components",
  "le8_complete"
)]
```

`le8_n_components` makes the denominator explicit, and `le8_complete` is
`TRUE` only when all eight components are available. Row-level missingness is silent; when a component cannot be calculated for any observation, one consolidated warning identifies every unavailable component. If structural missingness makes `min_components` impossible, the warning also states that no composite scores can be calculated.

## Source-defined inputs

`score_le8()` also rejects combinations for which the AHA source does not
define a score. Examples include an underweight BMI that
requires clinical judgment, a diagnostic-range glucose value paired with no
diabetes diagnosis, and simultaneous current combustible smoking and inhaled
nicotine-delivery-system use. Reconcile these records before scoring.
