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:
These approaches help researchers investigate when associations are strongest, compare biologically meaningful lag periods, and summarize complete exposure profiles.
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.
This section uses the same example dataset and basic model specification introduced in the Get Started section
Define the exposure-lag structures:
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:
Prepare the response:
Fit the 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.
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:
expresses modeled contrasts as percentage effects relative to the selected reference profile.
The interpretation of effect direction depends on the response and contrast:
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 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:
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.
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:
| var | lag | scale | value | eta | eta_sd | eta_lower | eta_upper | effect | effect_sd | effect_lower | effect_upper | baseline | baseline_sd | baseline_lower | baseline_upper | predicted | predicted_sd | predicted_lower | predicted_upper | delta | delta_sd | delta_lower | delta_upper |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| tmean | 0 | lag | 15.000 | -0.149 | 0.021 | -0.182 | -0.116 | -13.861 | 1.830 | -16.596 | -10.964 | 0.145 | 0.013 | 0.125 | 0.163 | 0.128 | 0.011 | 0.110 | 0.144 | -0.017 | 0.003 | -0.022 | -0.014 |
| tmean | 0 | lag | 15.202 | -0.147 | 0.021 | -0.178 | -0.115 | -13.652 | 1.773 | -16.304 | -10.858 | 0.145 | 0.013 | 0.125 | 0.163 | 0.128 | 0.011 | 0.111 | 0.144 | -0.017 | 0.003 | -0.022 | -0.014 |
| tmean | 0 | lag | 15.404 | -0.144 | 0.020 | -0.175 | -0.114 | -13.442 | 1.716 | -16.010 | -10.751 | 0.145 | 0.013 | 0.125 | 0.163 | 0.129 | 0.011 | 0.111 | 0.145 | -0.017 | 0.003 | -0.021 | -0.014 |
| tmean | 0 | lag | 15.606 | -0.142 | 0.019 | -0.171 | -0.113 | -13.231 | 1.659 | -15.715 | -10.644 | 0.145 | 0.013 | 0.125 | 0.163 | 0.129 | 0.011 | 0.111 | 0.145 | -0.016 | 0.003 | -0.021 | -0.014 |
| tmean | 0 | lag | 15.808 | -0.139 | 0.018 | -0.167 | -0.111 | -13.019 | 1.603 | -15.419 | -10.535 | 0.145 | 0.013 | 0.125 | 0.163 | 0.129 | 0.011 | 0.111 | 0.145 | -0.016 | 0.003 | -0.020 | -0.013 |
| tmean | 0 | lag | 16.010 | -0.137 | 0.018 | -0.164 | -0.110 | -12.806 | 1.546 | -15.122 | -10.426 | 0.145 | 0.013 | 0.125 | 0.163 | 0.129 | 0.011 | 0.112 | 0.145 | -0.016 | 0.003 | -0.020 | -0.013 |
| tmean | 0 | lag | 16.212 | -0.135 | 0.017 | -0.160 | -0.109 | -12.592 | 1.490 | -14.823 | -10.312 | 0.145 | 0.013 | 0.125 | 0.163 | 0.130 | 0.011 | 0.112 | 0.146 | -0.015 | 0.002 | -0.020 | -0.013 |
| tmean | 0 | lag | 16.414 | -0.132 | 0.016 | -0.157 | -0.108 | -12.376 | 1.433 | -14.523 | -10.191 | 0.145 | 0.013 | 0.125 | 0.163 | 0.130 | 0.011 | 0.112 | 0.146 | -0.015 | 0.002 | -0.019 | -0.013 |
| tmean | 0 | lag | 16.616 | -0.130 | 0.016 | -0.153 | -0.106 | -12.159 | 1.378 | -14.222 | -10.069 | 0.145 | 0.013 | 0.125 | 0.163 | 0.130 | 0.011 | 0.112 | 0.146 | -0.015 | 0.002 | -0.019 | -0.012 |
| tmean | 0 | lag | 16.818 | -0.127 | 0.015 | -0.150 | -0.105 | -11.940 | 1.323 | -13.919 | -9.944 | 0.145 | 0.013 | 0.125 | 0.163 | 0.130 | 0.011 | 0.113 | 0.146 | -0.014 | 0.002 | -0.018 | -0.012 |
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.
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:
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.
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.
periods
#> period lag_start lag_end
#> 1 Period1 0 20
#> 2 Period2 21 40
#> 3 Period3 41 60
#> 4 Period4 61 85The selected cut points divide the fitted lag interval into four periods:
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.
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:
| var | period | scale | value | eta | eta_sd | eta_lower | eta_upper | effect | effect_sd | effect_lower | effect_upper | baseline | baseline_sd | baseline_lower | baseline_upper | predicted | predicted_sd | predicted_lower | predicted_upper | delta | delta_sd | delta_lower | delta_upper |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| tmean | Period1 | period | 18.979 | -1.688 | 0.152 | -1.997 | -1.456 | -81.515 | 2.738 | -86.416 | -76.681 | 0.141 | 0.019 | 0.118 | 0.186 | 0.029 | 0.004 | 0.023 | 0.035 | -0.108 | 0.018 | -0.154 | -0.091 |
| tmean | Period1 | period | 19.241 | -1.629 | 0.139 | -1.909 | -1.419 | -80.385 | 2.669 | -85.172 | -75.791 | 0.141 | 0.019 | 0.118 | 0.186 | 0.031 | 0.004 | 0.025 | 0.036 | -0.106 | 0.017 | -0.151 | -0.090 |
| tmean | Period1 | period | 19.506 | -1.571 | 0.128 | -1.821 | -1.379 | -79.213 | 2.601 | -83.792 | -74.806 | 0.141 | 0.019 | 0.118 | 0.186 | 0.032 | 0.004 | 0.027 | 0.038 | -0.104 | 0.017 | -0.149 | -0.088 |
| tmean | Period1 | period | 19.752 | -1.514 | 0.118 | -1.738 | -1.340 | -77.994 | 2.544 | -82.393 | -73.808 | 0.141 | 0.019 | 0.118 | 0.186 | 0.034 | 0.004 | 0.029 | 0.040 | -0.102 | 0.017 | -0.147 | -0.087 |
| tmean | Period1 | period | 19.965 | -1.464 | 0.110 | -1.667 | -1.300 | -76.867 | 2.499 | -81.083 | -72.736 | 0.141 | 0.019 | 0.118 | 0.186 | 0.036 | 0.004 | 0.030 | 0.043 | -0.101 | 0.016 | -0.145 | -0.086 |
| tmean | Period1 | period | 20.171 | -1.411 | 0.103 | -1.609 | -1.258 | -75.607 | 2.463 | -79.972 | -71.570 | 0.141 | 0.019 | 0.118 | 0.186 | 0.038 | 0.004 | 0.032 | 0.045 | -0.099 | 0.016 | -0.142 | -0.084 |
| tmean | Period1 | period | 20.362 | -1.361 | 0.097 | -1.557 | -1.218 | -74.368 | 2.436 | -78.893 | -70.421 | 0.141 | 0.019 | 0.118 | 0.186 | 0.040 | 0.004 | 0.033 | 0.047 | -0.097 | 0.016 | -0.140 | -0.083 |
| tmean | Period1 | period | 20.547 | -1.316 | 0.092 | -1.504 | -1.179 | -73.180 | 2.418 | -77.771 | -69.238 | 0.141 | 0.019 | 0.118 | 0.186 | 0.042 | 0.004 | 0.035 | 0.050 | -0.095 | 0.016 | -0.138 | -0.082 |
| tmean | Period1 | period | 20.737 | -1.269 | 0.087 | -1.450 | -1.138 | -71.888 | 2.409 | -76.530 | -67.945 | 0.141 | 0.019 | 0.118 | 0.186 | 0.044 | 0.005 | 0.037 | 0.052 | -0.094 | 0.015 | -0.135 | -0.080 |
| tmean | Period1 | period | 20.902 | -1.227 | 0.084 | -1.402 | -1.101 | -70.697 | 2.409 | -75.379 | -66.756 | 0.141 | 0.019 | 0.118 | 0.186 | 0.046 | 0.005 | 0.038 | 0.055 | -0.092 | 0.015 | -0.133 | -0.078 |
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:
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.
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.
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:
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:
| sample | var | period | scale | value | eta | effect | baseline | predicted | delta |
|---|---|---|---|---|---|---|---|---|---|
| 1 | tmean | Period1 | period | 18.979 | -1.631 | -80.428 | 0.145 | 0.032 | -0.113 |
| 1 | tmean | Period1 | period | 19.241 | -1.580 | -79.396 | 0.145 | 0.034 | -0.112 |
| 1 | tmean | Period1 | period | 19.506 | -1.526 | -78.262 | 0.145 | 0.036 | -0.110 |
| 1 | tmean | Period1 | period | 19.752 | -1.475 | -77.120 | 0.145 | 0.037 | -0.108 |
| 1 | tmean | Period1 | period | 19.965 | -1.429 | -76.056 | 0.145 | 0.039 | -0.106 |
| 1 | tmean | Period1 | period | 20.171 | -1.385 | -74.957 | 0.145 | 0.041 | -0.105 |
| 1 | tmean | Period1 | period | 20.362 | -1.342 | -73.869 | 0.145 | 0.043 | -0.103 |
| 1 | tmean | Period1 | period | 20.547 | -1.300 | -72.742 | 0.145 | 0.044 | -0.101 |
| 1 | tmean | Period1 | period | 20.737 | -1.255 | -71.503 | 0.145 | 0.046 | -0.099 |
| 1 | tmean | Period1 | period | 20.902 | -1.216 | -70.360 | 0.145 | 0.048 | -0.097 |
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.
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:
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;_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.
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.
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.
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.
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:
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:
| var | type | value | reference | scale | x | eta | eta_sd | low | high | effect | effect_sd | low_eff | high_eff |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| tmean | overall | NA | 24.971 | percent | 15.000 | -0.319 | 0.886 | -1.052 | 1.368 | -26.580 | 132.561 | -65.011 | 300.709 |
| tmean | overall | NA | 24.971 | percent | 16.053 | -0.711 | 0.725 | -1.300 | 0.709 | -50.617 | 64.450 | -72.725 | 106.752 |
| tmean | overall | NA | 24.971 | percent | 17.105 | -1.073 | 0.572 | -1.523 | 0.087 | -65.725 | 31.521 | -78.190 | 10.593 |
| tmean | overall | NA | 24.971 | percent | 18.158 | -1.375 | 0.431 | -1.696 | -0.465 | -74.711 | 15.872 | -81.653 | -36.431 |
| tmean | overall | NA | 24.971 | percent | 19.211 | -1.583 | 0.309 | -1.795 | -0.908 | -79.466 | 8.408 | -83.393 | -59.301 |
| tmean | overall | NA | 24.971 | percent | 20.263 | -1.682 | 0.212 | -1.835 | -1.208 | -81.392 | 4.820 | -84.029 | -69.914 |
| tmean | overall | NA | 24.971 | percent | 21.316 | -1.648 | 0.145 | -1.765 | -1.328 | -80.756 | 3.181 | -82.888 | -73.382 |
| tmean | overall | NA | 24.971 | percent | 22.368 | -1.390 | 0.105 | -1.539 | -1.213 | -75.078 | 2.681 | -78.525 | -70.248 |
| tmean | overall | NA | 24.971 | percent | 23.421 | -0.953 | 0.072 | -1.070 | -0.860 | -61.451 | 2.752 | -65.691 | -57.686 |
| tmean | overall | NA | 24.971 | percent | 24.474 | -0.320 | 0.026 | -0.365 | -0.292 | -27.388 | 1.841 | -30.560 | -25.315 |
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.
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.
A "lag" reduction evaluates the exposure-response
association at one retrospective lag. The following example evaluates
rainfall at lag 10:
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:
requests the fitted rainfall association ten time units before the disease assessment. Other lag coordinates are not part of this one-dimensional reduction.
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.
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:
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:
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.
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.
As with other EpiExposure uncertainty functions, draw-level output can be requested with:
For example:
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.
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().
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:
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:
| epi_id | var | reference_value | max_lag | n_exposure_values | ECI_raw | ECI_raw_centered | baseline | baseline_sd | baseline_lower | baseline_upper | predicted | predicted_sd | predicted_lower | predicted_upper | ECI_weighted | ECI_weighted_sd | ECI_weighted_lower | ECI_weighted_upper | scale |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | tmean | 24.971 | 85 | 86 | 2060.099 | -87.432 | 0.152 | 0.023 | 0.123 | 0.185 | 0.049 | 0.003 | 0.046 | 0.055 | -1.243 | 0.125 | -1.358 | -1.030 | link |
| 1 | rain | 0.000 | 85 | 86 | 372.093 | 372.093 | 0.152 | 0.023 | 0.123 | 0.185 | 0.720 | 0.031 | 0.666 | 0.751 | 2.643 | 0.103 | 2.504 | 2.795 | link |
| 1 | wetness | 10.335 | 85 | 86 | 810.230 | -78.577 | 0.152 | 0.023 | 0.123 | 0.185 | 0.110 | 0.018 | 0.087 | 0.136 | -0.361 | 0.017 | -0.392 | -0.345 | link |
| 2 | tmean | 24.971 | 85 | 86 | 2037.798 | -109.734 | 0.152 | 0.023 | 0.123 | 0.185 | 0.032 | 0.002 | 0.028 | 0.033 | -1.700 | 0.165 | -1.890 | -1.451 | link |
| 2 | rain | 0.000 | 85 | 86 | 476.946 | 476.946 | 0.152 | 0.023 | 0.123 | 0.185 | 0.739 | 0.025 | 0.698 | 0.774 | 2.776 | 0.071 | 2.635 | 2.839 | link |
| 2 | wetness | 10.335 | 85 | 86 | 546.175 | -342.632 | 0.152 | 0.023 | 0.123 | 0.185 | 0.045 | 0.008 | 0.038 | 0.058 | -1.274 | 0.056 | -1.355 | -1.197 | link |
| 3 | tmean | 24.971 | 85 | 86 | 2093.533 | -53.998 | 0.152 | 0.023 | 0.123 | 0.185 | 0.050 | 0.003 | 0.047 | 0.057 | -1.194 | 0.122 | -1.334 | -1.033 | link |
| 3 | rain | 0.000 | 85 | 86 | 224.391 | 224.391 | 0.152 | 0.023 | 0.123 | 0.185 | 0.355 | 0.037 | 0.300 | 0.409 | 1.120 | 0.033 | 1.087 | 1.189 | link |
| 3 | wetness | 10.335 | 85 | 86 | 1052.515 | 163.708 | 0.152 | 0.023 | 0.123 | 0.185 | 0.252 | 0.029 | 0.215 | 0.292 | 0.633 | 0.038 | 0.596 | 0.699 | link |
| 4 | tmean | 24.971 | 85 | 86 | 2072.810 | -74.721 | 0.152 | 0.023 | 0.123 | 0.185 | 0.039 | 0.002 | 0.035 | 0.041 | -1.510 | 0.167 | -1.674 | -1.239 | link |
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.
tmean
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
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
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.
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:
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:
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.
| epi_id | var | lag | exposure | reference_value | exposure_minus_reference | ECI_weighted | ECI_percent | ECI_absolute | ECI_weighted_sd | ECI_weighted_lower | ECI_weighted_upper | ECI_percent_sd | ECI_percent_lower | ECI_percent_upper | ECI_percent_n | ECI_absolute_sd | ECI_absolute_lower | ECI_absolute_upper |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | tmean | 0 | 21.605 | 24.971 | -3.367 | -0.059 | 3.239 | 0.059 | 0.003 | -0.062 | -0.052 | 0.183 | 2.797 | 3.332 | 10 | 0.003 | 0.052 | 0.062 |
| 1 | tmean | 1 | 21.894 | 24.971 | -3.077 | -0.053 | 2.902 | 0.053 | 0.003 | -0.056 | -0.047 | 0.153 | 2.553 | 2.988 | 10 | 0.003 | 0.047 | 0.056 |
| 1 | tmean | 2 | 21.258 | 24.971 | -3.713 | -0.062 | 3.422 | 0.062 | 0.004 | -0.066 | -0.055 | 0.204 | 2.947 | 3.555 | 10 | 0.004 | 0.055 | 0.066 |
| 1 | tmean | 3 | 21.887 | 24.971 | -3.084 | -0.051 | 2.811 | 0.051 | 0.003 | -0.054 | -0.046 | 0.142 | 2.488 | 2.896 | 10 | 0.003 | 0.046 | 0.054 |
| 1 | tmean | 4 | 21.948 | 24.971 | -3.023 | -0.049 | 2.708 | 0.049 | 0.002 | -0.053 | -0.045 | 0.133 | 2.411 | 2.803 | 10 | 0.002 | 0.045 | 0.053 |
| 1 | tmean | 5 | 21.986 | 24.971 | -2.986 | -0.048 | 2.631 | 0.048 | 0.002 | -0.051 | -0.044 | 0.126 | 2.352 | 2.728 | 10 | 0.002 | 0.044 | 0.051 |
| 1 | tmean | 6 | 21.356 | 24.971 | -3.616 | -0.056 | 3.119 | 0.056 | 0.003 | -0.059 | -0.050 | 0.165 | 2.714 | 3.188 | 10 | 0.003 | 0.050 | 0.059 |
| 1 | tmean | 7 | 22.080 | 24.971 | -2.891 | -0.045 | 2.471 | 0.045 | 0.002 | -0.048 | -0.041 | 0.112 | 2.220 | 2.567 | 10 | 0.002 | 0.041 | 0.048 |
| 1 | tmean | 8 | 23.713 | 24.971 | -1.258 | -0.019 | 1.074 | 0.019 | 0.001 | -0.022 | -0.018 | 0.062 | 0.988 | 1.169 | 10 | 0.001 | 0.018 | 0.022 |
| 1 | tmean | 9 | 24.900 | 24.971 | -0.071 | -0.001 | 0.055 | 0.001 | 0.000 | -0.001 | -0.001 | 0.004 | 0.049 | 0.062 | 10 | 0.000 | 0.001 | 0.001 |
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:
Lag-specific effects, period-specific effects, ECI, and ECI decomposition are different views of the same fitted exposure-lag-response structure.
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.
Before reporting an effect summary, verify:
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.
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:
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.