---
title: "Understanding Effects"
author: "Ricardo G. Tomáz"
description: "Lag-specific, period-specific, and cumulative exposure effects"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Understanding Effects}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.align = "center",
  message = FALSE,
  warning = FALSE
)
```

# Introduction

The primary goal of `EpiExposure` is not only to fit distributed lag non-linear
models, but also to translate estimated exposure-lag-response surfaces into
epidemiologically meaningful quantities.

This section introduces five complementary approaches:

- lag-specific effects;
- period-specific effects;
- one-dimensional reduction of the fitted DLNM association;
- Exposure Cumulative Impact, or ECI;
- lag-specific decomposition of ECI.

These approaches help researchers investigate when associations are strongest,
compare biologically meaningful lag periods, and summarize complete exposure
profiles.

::: {.tutorial-note}
**What you will learn.** This tutorial shows how to reconstruct and interpret
lag-specific and period-specific effects, reduce a fitted DLNM association to
one dimension, calculate ECI for complete exposure profiles, and identify the
lags contributing most strongly to ECI.
:::

Effect estimates should be interpreted as modeled associations under the fitted
DLNM. They do not, by themselves, establish causal effects.

# Preparing the example model

This section uses the same example dataset and basic model specification
introduced in the *Get Started* section

```{r load-packages}
library(EpiExposure)
library(ggplot2)
```

```{r load-data}
data("epi_data")
```

Define the exposure-lag structures:

```{r define-exposures}
cb <- define_exposures(
  data = epi_data,
  vars = c(
    "tmean",
    "rain",
    "wetness"
  ),
  max_lag = 85,
  df_var = 3,
  df_lag = 2
)
```

Build the epidemic-level design:

```{r build-design}
dat <- build_design(
  data = epi_data,
  cb_templates = cb
)
```

Prepare the response:

```{r prepare-response}
dat <- prepare_response(
  data = dat,
  response = "y",
  family = "beta"
)
```

Fit the model:

```{r fit-model}
fit <- fit_epidlnm(
  data = dat,
  model_engine = "glmmTMB",
  family = "beta",
  random_effect = NULL,
  epiexposure_spec = attr(
    cb,
    "spec"
  )
)
```

The individual `cb_*` coefficients are components of the cross-basis expansion
and should not be interpreted separately. The functions below reconstruct those
coefficients into quantities defined over exposure values and retrospective
lags.

# Reference conditions and effect measures

Exposure-lag effects are interpreted relative to reference conditions. When an
exposure value is evaluated at a particular lag, the other lags are held at
their corresponding reference values.

Three effect measures are supported:

- `"linear"` returns the DLNM contrast on the linear predictor scale (`eta`).
- `"exponentiated"` returns `exp(eta)`, corresponding to response ratios for log-link models and odds ratios for logit-link models.
- `"percent"` returns `100 × (exp(eta) - 1)`, representing percent changes relative to the selected reference profile.

For links such as `"identity"`, `"probit"`, `"cloglog"`, or `"inverse"`, only `"linear"` is available.

In the examples below, we use:

```r
effect_measure = "percent"
```

expresses modeled contrasts as percentage effects relative to the selected
reference profile.

The interpretation of effect direction depends on the response and contrast:

- positive values indicate a higher modeled response than the reference;
- negative values indicate a lower modeled response than the reference;
- values near zero indicate little modeled contrast from the reference.

These values describe contrasts in the expected response under the fitted model.
They should not automatically be interpreted as causal risk changes.

# Lag-specific effects

## What are lag-specific effects?

Lag-specific effects describe how the modeled disease response changes across
exposure values at an individual retrospective lag, while the remaining lags
are held at their reference conditions.

A lag refers to the time elapsed between an exposure observation and the final
disease assessment:

```text
lag 0  → exposure measured at the disease assessment time
lag 1  → exposure measured one time unit before assessment
...
lag 85 → earliest exposure observation in the fitted profile
```

Lag-specific summaries help identify portions of the exposure profile in which
the fitted model shows stronger or weaker associations.

They do not imply that an individual `cb_*` coefficient corresponds to a
specific biological process. The lag-specific effect is reconstructed from the
joint cross-basis representation.

## Estimating lag-specific effects

```{r estimate-lag-effects}
epi_l <- summarise_effects(
  fit = fit,
  data = epi_data,
  scale = "lag",
  effect_measure = "percent",
  uncertainty = TRUE,
  n_samples = 10,
  output = "summary",
  at = list(
    tmean = seq(
      15,
      35,
      length.out = 100
    ),
    rain = seq(
      0,
      15,
      length.out = 100
    ),
    wetness = seq(
      0,
      24,
      length.out = 100
    )
  )
)
```

The `at` argument defines the exposure values at which the fitted
exposure-lag-response relationships are evaluated.

The number of values in each sequence controls the resolution of the resulting
effect grid. A denser grid produces smoother visualizations but increases
computation and output size.

Inspect the reconstructed summaries:

```{r inspect-lag-effects, echo=FALSE}
knitr::kable(
  utils::head(
    epi_l,
    10L
  ),
  digits = 3,
  align = "c"
)
```

## Visualizing lag-specific effects

```{r plot-lag-effects, fig.width=9, fig.height=7}
plot_effects(
  data = epi_l,
  scale = "lag",
  metric = "effect",
  vars = c(
    "tmean",
    "rain",
    "wetness"
  )
)
```

Interpret these plots jointly across exposure values and lags. Avoid drawing
conclusions from one isolated point, especially where uncertainty is large or
data support is limited.

## Local sensitivity and delta effects

In addition to effect estimates, `EpiExposure` can display local sensitivity
measures, denoted by (Delta).

Delta describes how rapidly the modeled effect changes as the exposure value
increases locally:

- positive values indicate an increasing modeled response;
- negative values indicate a decreasing modeled response;
- values near zero indicate local stability or a relatively flat portion of
  the estimated relationship.

```{r plot-delta-effects, fig.width=9, fig.height=7}
plot_effects(
  data = epi_l,
  scale = "lag",
  metric = "delta",
  delta_multiplier = 100,
  vars = c(
    "tmean",
    "rain",
    "wetness"
  )
)
```

Delta should be interpreted as a local feature of the fitted
exposure-lag-response surface. It is not a separate regression coefficient or
an independent causal effect.

# Period-specific effects

## Why summarize lag periods?

Individual lags may be difficult to interpret biologically, particularly when
disease development involves broader phases such as infection, colonization,
symptom development, or secondary spread.

Period-specific effects combine information across predefined lag intervals.
This allows the exposure-lag association to be summarized over biologically
meaningful phases rather than interpreted one lag at a time.

The periods should be selected using biological knowledge whenever possible.
They should not be chosen only because they produce larger or more visually
distinct effects.

## Defining epidemiological periods

```{r define-periods}
periods <- define_periods(
  max_lag = 85,
  cuts = c(
    20,
    40,
    60
  ),
  prefix = "Period"
)
```

```{r}
periods
```

The selected cut points divide the fitted lag interval into four periods:

- Period1: lags 0–20 (most recent exposures)
- Period2: lags 21–40
- Period3: lags 41–60
- Period4: lags 61–85 (oldest exposures)

These periods are defined on the retrospective lag scale used by DLNMs and `EpiExposure` rather than on the original chronological time scale. Consequently, Period1 contains exposures occurring closest to the disease assessment date, whereas Period4 contains exposures occurring furthest in the past. When assigning biological labels, remember that lower lags represent more recent exposure conditions and higher lags represent earlier exposure conditions.

## Estimating period-specific effects

```{r estimate-period-effects}
epi_p_summary <- summarise_effects(
  fit = fit,
  data = epi_data,
  scale = "period",
  lag_periods = periods,
  effect_measure = "percent",
  uncertainty = TRUE,
  n_samples = 20,
  output = "summary"
)
```

When `output = "summary"` and `uncertainty = TRUE`, `EpiExposure` summarizes the simulated parameter draws for each exposure-period combination. The reported effect corresponds to the median estimate across draws, while the lower and upper bounds represent the empirical uncertainty interval defined by `interval_probs` (95% by default).

This output is useful when the goal is to summarize the central tendency and uncertainty of the estimated effects rather than inspect each individual draw.

Inspect the summary:

```{r inspect-period-effects, echo=FALSE}
knitr::kable(
  utils::head(
    epi_p_summary,
    10L
  ),
  digits = 3,
  align = "c"
)
```

The summary output contains one row for each exposure-period combination and includes uncertainty summaries for the estimated effects, baseline prediction, predicted response, and response-scale difference (`delta`).

Visualizing period-specific effects:

```{r plot-period-effects, fig.width=9, fig.height=7}
plot_effects(
  data = epi_p_summary,
  scale = "period",
  vars = c(
    "tmean",
    "rain",
    "wetness"
  ),
  period_order = c(
    "Period4",
    "Period3",
    "Period2",
    "Period1"
  ),
  vars_order = c(
    "tmean",
    "rain",
    "wetness"
  ),
  period_response = "eta",
  period_ylab = "Effect"
)
```

Period-specific summaries describe the modeled contribution accumulated over
each defined lag interval. They should not be interpreted as four independently
estimated models because all periods arise from the same fitted cross-basis
surface.

## Returning uncertainty samples

When `output = "samples"`, the function returns the individual draw-specific results instead of summary statistics. Each row corresponds to one parameter draw and one exposure-period combination, allowing custom uncertainty analyses and visualizations.

This output is particularly useful when calculating user-defined summaries, propagating uncertainty through downstream analyses, or building custom graphics.

In contrast to `output = "summary"`, which reports median estimates and uncertainty intervals across all simulated draws, `output = "samples"` returns the complete draw-by-draw results used to construct those summaries.

```{r period-effect-samples}
epi_p_samples <- summarise_effects(
  fit = fit,
  data = epi_data,
  scale = "period",
  lag_periods = periods,
  effect_measure = "percent",
  uncertainty = TRUE,
  n_samples = 20,
  output = "samples"
)
```

Visualizing period-specific effects:

```{r plot-period-effects2, fig.width=9, fig.height=7}
plot_effects(
  data = epi_p_samples,
  scale = "period",
  vars = c(
    "tmean",
    "rain",
    "wetness"
  ),
  period_order = c(
    "Period4",
    "Period3",
    "Period2",
    "Period1"
  ),
  vars_order = c(
    "tmean",
    "rain",
    "wetness"
  ),
  period_response = "eta",
  period_ylab = "Effect"
)
```

Inspect a subset of the sample-level output:

```{r inspect-period-samples, echo=FALSE}
knitr::kable(
  utils::head(
    epi_p_samples,
    10L
  ),
  digits = 3,
  align = "c"
)
```

The sample output preserves individual uncertainty realizations. It can support
custom summaries, probability calculations, sensitivity analyses, and
user-defined visualizations.

The rows belonging to the same draw should remain associated when comparing
periods, exposures, scenarios, or contrasts.

## Comparing period-specific effects

Period-specific effects can be compared against a selected reference period using `compare_periods()`. Comparisons are made for the same exposure variable and the same evaluated exposure value, ensuring that differences among periods are not confounded by differences in exposure level.

When uncertainty is included, `compare_periods()` requires the sample-level output from `summarise_effects()`. Target and reference periods are first matched within each joint parameter draw. Differences and ratios are calculated draw by draw and summarized only afterward, preserving the covariance among period-specific effects.

The following workflow compares all periods against `Period1`, which represents the most recent retrospective exposure interval in this example:

```{r compare-periods, eval=FALSE}
epi_p_samples <- summarise_effects(
  fit = fit,
  data = epi_data,
  scale = "period",
  lag_periods = periods,
  effect_measure = "percent",
  uncertainty = TRUE,
  n_samples = 20,
  output = "samples"
)

period_comparison <- compare_periods(
  period_df = epi_p_samples,
  period_ref = "Period1",
  periods = periods,
  output = "summary"
)
```

The main comparison columns are:

- `eta_diff`: difference between the target and reference periods on the fitted
  link scale;
- `diff`: arithmetic difference between the displayed period-specific effects;
- `ratio`: ratio of period-specific response ratios for log-link models or
  period-specific odds ratios for logit-link models;
- `ratio_percent`: percentage representation of the period-relative ratio;
- `predicted_diff`: difference between the period-specific expected responses;
- `delta_diff`: difference between the absolute response-scale changes relative
  to the common exposure reference profile;
- `lag_start`, `lag_end`, and `n_lags`: temporal boundaries and widths of the
  compared periods;
- columns ending in `_lower` and `_upper`: empirical uncertainty limits
  calculated after the draw-by-draw comparisons.

For the fitted model with a logit link, `ratio` compares the
period-specific odds ratios. A value above 1 indicates a larger odds ratio in the target period than in `Period1`, whereas a value below 1 indicates a smaller odds ratio.

Because the expected Beta response is expressed as a proportion,
`predicted_diff` can be multiplied by 100 to obtain the difference in
percentage points between periods.

Period-specific effects are cumulative over the lags included in each period.
Consequently, a period comparison may reflect both the fitted lag-response
pattern and differences in the number of included lags. The results should
therefore be interpreted according to the biological meaning and temporal
width of the predefined periods.


# Reducing the fitted DLNM association

## Why reduce an exposure-lag association?

A fitted DLNM represents a two-dimensional association across exposure values
and retrospective lags. Although this complete surface is useful, researchers
may also need a one-dimensional representation of the fitted association.

`reduce_effects()` uses `dlnm::crossreduce()` to re-express the fitted
cross-basis association in one dimension. The function supports three
complementary reductions:

- `"overall"` summarizes the cumulative exposure-response association across
  the complete fitted lag interval;
- `"lag"` summarizes the exposure-response association at one selected lag;
- `"var"` summarizes the lag-response association at one selected exposure
  value.

The reduction is algebraic. It uses the cross-basis and coefficient mapping
stored in the fitted EpiExposure model and does not fit a new epidemiological
model. Knots, boundary knots, basis dimensions, and lag definitions are not
re-estimated from the supplied data.

The `data` argument is used to validate the temporal profiles, determine
method-based reference values, and verify exposure support. It is not used to
construct a new cross-basis.

::: {.tutorial-note}
**Reduction and prediction answer different questions.** `reduce_effects()`
returns a centered association contrast from the fitted DLNM. It does not
return an absolute expected disease response. Use `summarise_effects()` or
`predict_outcomes()` when baseline, predicted, or response-scale quantities are
required.
:::

## Overall cumulative exposure-response association

The following example reduces the fitted temperature association across the
complete lag interval.

Because the fitted Beta model uses a logit link, `scale = "percent"` represents
the percentage change in the modeled odds relative to the selected temperature
reference. It is not a percentage-point change in the expected disease
proportion.

```{r reduce-overall-temperature}
reduced_tmean <- reduce_effects(
  fit = fit,
  data = epi_data,
  vars = "tmean",
  group = "epi_id",
  time = "time",
  type = "overall",
  scale = "percent",
  uncertainty = TRUE,
  output = "summary",
  n_samples = 10,
  seed = 123,
  ref = list(
    method = "median",
    value = NULL
  ),
  at = seq(
    15,
    35,
    length.out = 20
  )
)
```

The median observed temperature is used as the reference. At that value, the
centered association is neutral:

```text
eta = 0
percent effect = 0
```

Values above zero indicate higher modeled odds than at the reference
temperature, whereas values below zero indicate lower modeled odds.

Inspect the reduced association:

```{r inspect-reduced-temperature, echo=FALSE}
knitr::kable(
  utils::head(
    reduced_tmean,
    10L
  ),
  digits = 3,
  align = "c"
)
```

The main columns are:

- `x`: temperature value at which the reduced association is evaluated;
- `eta`: median centered association on the linear-predictor scale;
- `low` and `high`: empirical uncertainty limits for `eta`;
- `effect`: median transformed association on the requested scale;
- `low_eff` and `high_eff`: empirical uncertainty limits for the transformed
  association;
- `reference`: temperature value used for centering.

The uncertainty summaries are calculated after transforming each coherent
parameter draw. They therefore describe uncertainty in the reduced fitted
association and do not include observation-level or posterior-predictive noise.

## Visualizing the overall reduction

```{r plot-reduced-temperature, fig.width=7, fig.height=5}
ggplot(
  reduced_tmean,
  aes(
    x = x,
    y = effect
  )
) +
  geom_ribbon(
    aes(
      ymin = low_eff,
      ymax = high_eff
    ),
    fill = "#C44E52",
    alpha = 0.20
  ) +
  geom_hline(
    yintercept = 0,
    color = "grey50",
    linetype = "dashed"
  ) +
  geom_line(
    color = "#C44E52",
    linewidth = 1
  ) +
  theme_bw() +
  labs(
    x = "Mean temperature (°C)",
    y = "Change in modeled odds (%)",
    title = "Overall cumulative temperature association"
  ) +
  theme(
    text = element_text(
      size = 10,
      face = "bold"
    )
  )
```

The solid curve represents the median cumulative association across the fitted
lag interval. The shaded region represents the empirical parameter-uncertainty
interval. The horizontal zero line represents the median temperature reference.

This curve is cumulative across lags. It should not be interpreted as the
association at one specific lag.

## Exposure-response association at a selected lag

A `"lag"` reduction evaluates the exposure-response association at one
retrospective lag. The following example evaluates rainfall at lag 10:

```{r reduce-rainfall-selected-lag}
reduced_rain_lag10 <- reduce_effects(
  fit = fit,
  data = epi_data,
  vars = "rain",
  group = "epi_id",
  time = "time",
  type = "lag",
  value = 10,
  scale = "percent",
  uncertainty = TRUE,
  output = "summary",
  n_samples = 10,
  seed = 123,
  ref = list(
    method = "median",
    value = NULL
  ),
  at = seq(
    0,
    15,
    length.out = 20
  )
)
```

Here:

```r
type = "lag"
value = 10
```

requests the fitted rainfall association ten time units before the disease
assessment. Other lag coordinates are not part of this one-dimensional
reduction.

```{r plot-reduced-rainfall-lag, fig.width=7, fig.height=5}
ggplot(
  reduced_rain_lag10,
  aes(
    x = x,
    y = effect
  )
) +
  geom_ribbon(
    aes(
      ymin = low_eff,
      ymax = high_eff
    ),
    fill = "#4C72B0",
    alpha = 0.20
  ) +
  geom_hline(
    yintercept = 0,
    color = "grey50",
    linetype = "dashed"
  ) +
  geom_line(
    color = "#4C72B0",
    linewidth = 1
  ) +
  theme_bw() +
  labs(
    x = "Rainfall",
    y = "Change in modeled odds (%)",
    title = "Rainfall association at lag 10"
  ) +
  theme(
    text = element_text(
      size = 10,
      face = "bold"
    )
  )
```

This reduction differs from the overall curve because it describes one selected
lag rather than the cumulative association across the complete lag interval.

## Lag-response association at a selected exposure value

A `"var"` reduction reverses the perspective. Instead of showing how the
association changes across exposure values, it shows how the association
changes across lags at one selected exposure value.

The following example evaluates leaf wetness at a fixed value of 10:

```{r reduce-wetness-selected-value}
reduced_wetness_10 <- reduce_effects(
  fit = fit,
  data = epi_data,
  vars = "wetness",
  group = "epi_id",
  time = "time",
  type = "var",
  value = 10,
  scale = "percent",
  uncertainty = TRUE,
  output = "summary",
  n_samples = 10,
  seed = 123,
  ref = list(
    method = "median",
    value = NULL
  )
)
```

For this reduction:

```text
x = retrospective lag
value = selected leaf wetness exposure
```

The resulting curve describes how the centered association for leaf wetness
equal to 10 is distributed across the fitted lag interval.

```{r plot-reduced-wetness-value, fig.width=7, fig.height=5}
ggplot(
  reduced_wetness_10,
  aes(
    x = x,
    y = effect
  )
) +
  geom_ribbon(
    aes(
      ymin = low_eff,
      ymax = high_eff
    ),
    fill = "#55A868",
    alpha = 0.20
  ) +
  geom_hline(
    yintercept = 0,
    color = "grey50",
    linetype = "dashed"
  ) +
  geom_line(
    color = "#55A868",
    linewidth = 1
  ) +
  scale_x_reverse(
    breaks = seq(
      0,
      85,
      by = 15
    )
  ) +
  theme_bw() +
  labs(
    x = "Retrospective lag",
    y = "Change in modeled odds (%)",
    title = "Lag-response association for leaf wetness = 10"
  ) +
  theme(
    text = element_text(
      size = 10,
      face = "bold"
    )
  )
```

Lag 0 represents the most recent exposure observation, whereas increasing lag
values represent progressively older exposure conditions.

## Summary versus sample output

As with other EpiExposure uncertainty functions, draw-level output can be
requested with:

```r
uncertainty = TRUE
output = "samples"
```

For example:

```{r reduce-effects-samples, eval=FALSE}
reduced_tmean_samples <- reduce_effects(
  fit = fit,
  data = epi_data,
  vars = "tmean",
  group = "epi_id",
  time = "time",
  type = "overall",
  scale = "percent",
  uncertainty = TRUE,
  output = "samples",
  n_samples = 40,
  seed = 123,
  ref = list(
    method = "median",
    value = NULL
  ),
  at = seq(
    15,
    35,
    length.out = 100
  )
)
```

Each `sample` identifies one coherent joint parameter draw. Rows belonging to
the same sample should remain associated when constructing custom curves or
downstream uncertainty calculations.

With `output = "summary"`, `eta` and `effect` are medians across parameter
draws. With `output = "samples"`, they retain the draw-specific reduced
associations.

## Interpreting reduced associations

The three reduction types answer different questions:

- `type = "overall"` asks how the cumulative association across the complete
  lag window changes over exposure values;
- `type = "lag"` asks how the exposure-response association changes at one
  selected lag;
- `type = "var"` asks how the lag-response association changes at one selected
  exposure value.

These reductions should not be interpreted as new model fits or as independent
effects. All three are reparameterizations of the same fitted cross-basis
association.

For a logit-link model:

- `scale = "link"` reports the centered log-odds contrast;
- `scale = "response"` reports an odds ratio;
- `scale = "percent"` reports the percentage change in odds.

None of these transformations alone represents an absolute expected disease
proportion. Absolute baseline, predicted, and response-scale difference
quantities require the broader prediction information supplied by
`summarise_effects()` or `predict_outcomes()`.

# Exposure Cumulative Impact

## Why use ECI?

Disease responses depend on complete exposure profiles rather than isolated
observations.

Two epidemic profiles may have similar average rainfall or temperature but
different modeled epidemiological implications because favorable conditions
occurred at different times.

Exposure Cumulative Impact, or ECI, summarizes a complete exposure profile
while retaining information from the fitted exposure-lag-response
relationship.

ECI complements the lag-specific and period-specific summaries:

- lag-specific effects examine individual lags;
- period-specific effects combine predefined lag intervals;
- ECI summarizes the complete observed exposure profile of each epidemic.

## Calculating ECI

```{r compute-eci}
eci <- compute_eci(
  data = epi_data,
  group = "epi_id",
  fit = fit,
  vars = c(
    "tmean",
    "rain",
    "wetness"
  ),
  uncertainty = TRUE,
  output = "summary",
  n_samples = 10
)
```

Inspect the resulting summaries:

```{r inspect-eci, echo=FALSE}
knitr::kable(
  utils::head(
    eci,
    10L
  ),
  digits = 3,
  align = "c"
)
```

## Interpreting ECI

ECI provides two complementary quantities:

- `ECI_raw` describes the accumulated exposure profile without weighting by
  the fitted exposure-lag association;
- `ECI_weighted` incorporates the weighting implied by the fitted
  exposure-lag-response relationship.

`ECI_raw` describes exposure accumulation. It does not represent a modeled
disease effect.

`ECI_weighted` describes how the complete exposure profile aligns with the
association estimated by the DLNM. Larger or smaller values should be
interpreted relative to other profiles fitted under the same specification,
exposure definition, reference conditions, and scale.

ECI is a model-derived summary. It should not automatically be interpreted as a
causal impact or as a directly observed biological quantity.

## Comparing raw and weighted exposure profiles

tmean

```{r compare-eci-tmean, fig.width=7, fig.height=5}
eci[
  eci$var == "tmean",
  ,
  drop = FALSE
] |>
  ggplot(
    aes(
      x = ECI_raw,
      y = ECI_weighted
    )
  ) +
  geom_point(
    alpha = 0.65
  ) +
  theme_bw() +
  labs(
    x = "Raw ECI",
    y = "Weighted ECI",
    title = "tmean")
```

wetness

```{r compare-eci-wetness, fig.width=7, fig.height=5}
eci[
  eci$var == "wetness",
  ,
  drop = FALSE
] |>
  ggplot(
    aes(
      x = ECI_raw,
      y = ECI_weighted
    )
  ) +
  geom_point(
    alpha = 0.65
  ) +
  theme_bw() +
  labs(
    x = "Raw ECI",
    y = "Weighted ECI",
    title = "wetness")
```

rain

```{r compare-eci-rain, fig.width=7, fig.height=5}
eci[
  eci$var == "rain",
  ,
  drop = FALSE
] |>
  ggplot(
    aes(
      x = ECI_raw,
      y = ECI_weighted
    )
  ) +
  geom_point(
    alpha = 0.65
  ) +
  theme_bw() +
  labs(
    x = "Raw ECI",
    y = "Weighted ECI",
    title = "rain")
```

A strong relationship between the two quantities indicates that accumulated
exposure and model-based weighting produce similar rankings for the displayed
profiles.

Deviations from that relationship may indicate that exposure timing changes
the modeled importance of profiles with similar raw accumulation.

# Decomposing ECI by lag

## Why decompose ECI?

Overall ECI provides one summary for the complete profile, but researchers may
also want to identify the lags that contribute most strongly to that summary.

`compute_ecilag()` decomposes ECI into lag-specific contributions for a selected
epidemic or grouping level.

This decomposition answers a different question from lag-specific effect
curves:

- a lag-specific effect curve evaluates modeled contrasts across exposure
  values at a lag;
- ECI decomposition evaluates how the exposure values actually observed in a
  selected profile contribute to that profile's ECI.

## Computing lag contributions

```{r compute-eci-lag}
eci_lag <- compute_ecilag(
  data = epi_data,
  group = "epi_id",
  group_level = 1,
  fit = fit,
  var = c(
    "tmean",
    "rain",
    "wetness"
  ),
  uncertainty = TRUE,
  output = "summary",
  n_samples = 10
)
```

In this example:

```r
group_level = 1
```

selects the epidemic identified by level `1` of `epi_id`.

For a real analysis, select the epidemic identifier that corresponds to the
profile of scientific interest.

## Inspecting lag contributions

```{r inspect-eci-lag, echo=FALSE}
knitr::kable(
  utils::head(
    eci_lag$by_lag,
    10L
  ),
  digits = 3,
  align = "c"
)
```

## Plotting the contribution profile

```{r plot-eci, fig.width=9, fig.height=9}
plot_eci(
  eci_overall = eci,
  eci_lag = eci_lag,
  facet_scales = "free_y",
  overall_nrow = 3,
  lag_ncol = 1,
  sample_smooth = TRUE,
  linewidth = 0.7,
  alpha = 0.20,
  panel_labels = c(
    "(a)",
    "(b)",
    "(c)"
  ),
  overall_col = "ECI_weighted",
  lag_col = "ECI_percent"
)
```

The overall panels summarize complete profiles, whereas the lag panels show
how the selected profile is distributed across retrospective lags.

Large positive or negative lag contributions should be interpreted in the
context of:

- the exposure values observed at those lags;
- the fitted exposure-response shape;
- the fitted lag-response shape;
- the selected reference conditions;
- uncertainty in the fitted coefficients.

# How the summaries complement one another

Lag-specific effects, period-specific effects, ECI, and ECI decomposition are
different views of the same fitted exposure-lag-response structure.

- **Lag-specific effects** describe modeled exposure contrasts at individual
  lags.
- **Period-specific effects** summarize modeled exposure contrasts across
  predefined lag intervals.
- **ECI** summarizes complete observed exposure profiles.
- **ECI lag decomposition** identifies how individual lags contribute to ECI
  for a selected profile.

These summaries should not be expected to answer the same question or produce
identical rankings.

For example, a lag may show a strong modeled effect over part of the exposure
range but contribute little to ECI for a particular epidemic if the observed
exposure at that lag is close to its reference value.

Conversely, a moderate modeled effect can contribute substantially when an
epidemic contains a pronounced exposure contrast at that lag.

# Interpretation checklist

Before reporting an effect summary, verify:

1. which response family and link were fitted;
2. which exposure serves as the focus of interpretation;
3. which reference profile or centering condition is being used;
4. whether lag order is retrospective;
5. how epidemiological periods were defined;
6. whether the result is a summary or a sample-level output;
7. whether uncertainty intervals are sufficiently precise;
8. whether the evaluated exposure values are supported by the observed data;
9. whether the interpretation is associational or supported by a separate
   causal design.

::: {.tutorial-note}
**Avoid interpreting cross-basis coefficients individually.** Epidemiological
interpretation should be based on reconstructed lag-specific, period-specific,
or cumulative summaries rather than isolated `cb_*` estimates.
:::

# Next steps

The effect summaries presented in this section describe the direction,
magnitude, and temporal distribution of modeled exposure associations. However,
researchers may also want to identify the exposure regions in which the
predicted response changes most rapidly.

The next section, *Sensitivity Analysis and Decision Support*, introduces:

- local response sensitivity;
- elasticity;
- model-derived critical regions;
- comparisons among environmental gradients;
- interpretation of sensitivity results for monitoring and decision support.

These tools extend effect interpretation by examining the rate of change along
model-based prediction curves.

The subsequent *Simulation and Prediction* section provides a broader
introduction to constructing complete hypothetical exposure profiles,
predicting expected disease outcomes, and comparing environmental scenarios.
