Biostatistics Support and Research Unit, IGTP
Institute of Social and Preventive Medicine (ISPM), University of Bern
Institut de Salut Global de Barcelona (ISGlobal)
Departament d’Estadística i Investigació Operativa, Universitat de València
Agència de Salut Pública de Barcelona (ASPB)
May 26, 2026
Climate change is intensifying extreme environmental conditions: heatwaves, cold spells are becoming more frequent and severe
Environmental exposures rarely act instantaneously, as their health impact unfolds over time:
A heatwave today may elevate mortality risk several days later
Cold temperatures can trigger cardiovascular events long after exposure
Air pollution accumulates biological damage across days or weeks
Standard regression approaches struggle to capture these delayed and usually non-linear effects simultaneously
DLNMs (Gasparrini et al. 2010) are the standard framework for capturing these dynamics, simultaneously modelling two dimensions of risk:
\(\times\)
\(=\)
\[\log(E(Y_t)) = \alpha + \underbrace{cb(x_t, \ldots, x_{t-L}) \cdot \boldsymbol{\beta}}_{\text{cross-basis}} + \sum_{k} \gamma_k u_{kt}\]
| Term | Description |
|---|---|
| \(cb(\cdot)\) | Cross-basis: tensor product of exposure and lag spline bases |
| \(\boldsymbol{\beta}\) | Coefficients of the cross-basis |
| \(u_{kt}\) | (Time-varying) confounders (e.g. seasonality, trend) |
| \(\gamma_k\) | Coefficients of the confounders |
| \(\alpha\) | Intercept |
Same model, with prior distributions placed on all parameters:
\[\log(E(Y_t)) = \alpha + \underbrace{cb(x_t, \ldots, x_{t-L}) \cdot \boldsymbol{\beta}}_{\text{cross-basis}} + \sum_{k} \gamma_k u_{kt}\]
\[\alpha, \boldsymbol{\beta}, \gamma_k \sim \text{(prior distributions)}\]
Every parameter now has its posterior distribution
This enables:
Full uncertainty quantification of all estimates via posterior distributions
Uncertainty propagation in derived measures (optimal exposure, attributable burden) without additional approximations
Hierarchical extensions to add layers of complexity in the model (e.g. Spatial Bayesian DLNMs, Quijal-Zamorano et al. (2024))
The goal of {bdlnm} is to extend frequentist DLNMs to all kinds of Bayesian DLNMs (B-DLNMs)
Built on {dlnm}, the reference package for frequentist DLNMs (Gasparrini et al. 2011)
Uses R-INLA (Rue et al. 2009) for efficient Bayesian inference
Published on CRAN since March 2026:
| Purpose | Function | Based on |
|---|---|---|
| Model fitting | bdlnm() |
New |
| Optimal exposure | optimal_exposure() plot.optimal_exposure |
New |
| Prediction | bcrosspred() |
dlnm::crosspred() |
| Visualisation | plot.bcrosspred() |
dlnm::plot.crosspred() |
| Attribution | attributable() |
attrdl() (Gasparrini and Leone 2014) |
We assess the immediate and delayed non-linear effect of daily mean temperature on mortality (age 75+) in London, 2000–2011
We will use the {bdlnm} built-in london dataset: one observation per day, containing mortality counts, mean temperature, and calendar variables:
| date | year | dow | tmean | mort_00_74 | mort_75plus | mort |
|---|---|---|---|---|---|---|
| 2000-01-01 | 2000 | Sat | 7.642016 | 101 | 226 | 327 |
| 2000-01-02 | 2000 | Sun | 8.351041 | 100 | 191 | 291 |
| 2000-01-03 | 2000 | Mon | 8.188446 | 107 | 205 | 312 |
| 2000-01-04 | 2000 | Tue | 6.320066 | 97 | 191 | 288 |
| 2000-01-05 | 2000 | Wed | 6.550981 | 92 | 213 | 305 |
| 2000-01-06 | 2000 | Thu | 8.728774 | 82 | 213 | 295 |
\[Y_t \sim \text{Poisson}(\mu_t), \quad \quad \log(\mu_t) = \alpha + cb(x_t, \ldots, x_{t-L}) \cdot \beta + \sum_{k} \gamma_k u_{kt}\]
Cross-basis (\(cb\))
Confounders (\(u_{kt}\))
bdlnm() handles two things internally:
List of 4 (class "bdlnm")
$ model : list [49] — fitted R-INLA model object
$ basis : list [1] — cross-basis
$ coefficients : num [123, 1000] — posterior samples
$ coefficients.summary: num [123, 6] — posterior summary
Now we have a matrix with the estimated posterior samples of the model coefficients, together with their summary across samples:
Posterior samples mod$coefficients
sample1 sample2 sample3 sample4 sample5
(Intercept) 5.177126982 5.078820055 5.087683979 5.240468411 5.259946480
cbv1.l1 -0.139254820 -0.154092463 -0.112435103 -0.110085718 -0.153345807
cbv1.l2 -0.007785162 0.008057831 0.001246025 -0.003957057 0.006234502
cbv1.l3 -0.057349056 -0.056023923 -0.045405679 -0.044017954 -0.055955602
cbv1.l4 0.048904544 0.057243423 0.025429828 0.028536089 0.049960368
Posterior summary mod$coefficients.summary
mean sd 0.025quant 0.5quant 0.975quant
(Intercept) 5.204972340 0.10244169 5.00329053 5.205428027 5.39781786
cbv1.l1 -0.134951449 0.02148864 -0.17689662 -0.134049849 -0.09601856
cbv1.l2 -0.006084204 0.01031606 -0.02556688 -0.006093614 0.01455691
cbv1.l3 -0.049708682 0.01141099 -0.07279473 -0.049392945 -0.02789958
cbv1.l4 0.049567985 0.01806032 0.01484373 0.050353168 0.08412770
* Visualizing only the first 5 coefficients and the first 5 posterior samples
The minimum mortality temperature (MMT) is the temperature at which the overall cumulative mortality risk is minimised. It is used as the reference value to center relative risk estimates, so that all effects are interpreted relative to the temperature associated with lowest mortality
We will use the optimal_exposure() function to calculate it:
List of 2 (class "optimal_exposure")
$ est : num [1:1000] — posterior samples of the MMT
$ summary: num [1:6] — posterior summary (mean, sd, quantiles)
The posterior is concentrated around 18.9°C and unimodal: the median is a stable centering value for the relative risk estimates
From the fitted model, bcrosspred() computes the full bivariate exposure-lag-response association. Relative risks will be centered at the MMT:
List (class "bcrosspred")
$ coefficients : num [20, 1000] — posterior samples of cross-basis coefficients
$ coefficients.summary: num [20, 6] — posterior summary of cross-basis coefficients
$ matRRfit : num [326, 22, 1000] — posterior samples of RR (exposure x lag x samples)
$ matRRfit.summary : num [326, 22, 6] — posterior summary of RR (exposure x lag x summaries)
$ allRRfit : num [326, 1000] — posterior samples of overall RR (exposure x samples)
$ allRRfit.summary : num [326, 6] — posterior summary of overall RR (exposure x summaries)
Now we have an array of estimated posterior RRs for each temperature–lag combination, together with their summary across samples:
Posterior samples cpred$matRRfit
, , sample1
lag0 lag1 lag2 lag3
-3.4 0.8489699 1.078465 1.144323 1.100592
-3.3 0.8496304 1.077665 1.143102 1.099767
-3.2 0.8502913 1.076867 1.141883 1.098942
-3.1 0.8509526 1.076069 1.140665 1.098119
*Visualizing only first 4 temperatures and lags and 1 sample
Posterior summary cpred$matRRfit.summary
, , mean
lag0 lag1 lag2 lag3
-3.4 0.8526728 1.071554 1.134939 1.094427
-3.3 0.8533699 1.070944 1.133932 1.093743
-3.2 0.8540676 1.070335 1.132926 1.093060
-3.1 0.8547656 1.069726 1.131921 1.092377
*Visualizing only first 4 temperatures and lags and 1 summary statistic
plot.bcrosspred(): visualise predictionsplot.bcrosspred(): visualise predictionsplot.bcrosspred(): visualise predictionsplot.bcrosspred(): visualise predictionsThe attributable() function estimates the mortality burden attributable to non-optimal temperature exposures:
If we have estimated \(\beta_x\) associated with a certain exposure (centered to an optimal reference one) we can calculate the attribution to non-optimal temperature exposure as:
\[\text{AF}_{x,t} = 1 - \exp(-\beta_x) \qquad \text{AN}_{x,t} = n_t \cdot \text{AF}_{x,t}\]
attributable() returns daily and aggregated AF and AN using either the forward or backward perspective:
List of 8
$ af : num [4383, 1000] — posterior samples of daily AF
$ an : num [4383, 1000] — posterior samples of daily AN
$ aftotal : num [1:1000] — posterior samples of total AF
$ antotal : num [1:1000] — posterior samples of total AN
$ af.summary : num [4383, 6] — posterior summary of daily AF
$ an.summary : num [4383, 6] — posterior summary of daily AN
$ aftotal.summary: num [1:6] — posterior summary of total AF
$ antotal.summary: num [1:6] — posterior summary of total AN
Time series of daily attributable fractions (AFs), together with the temperature exposition in that given day:
Total mortality burden attributable to non-optimal temperatures in the London 75+ population across 2000–2011:
| mean | sd | 0.025quant | 0.5quant | 0.975quant | mode | |
|---|---|---|---|---|---|---|
| Attributable fraction | 0.174 | 0.018 | 0.139 | 0.175 | 0.207 | 0.176 |
| Attributable number | 68878.817 | 7130.981 | 55093.340 | 69199.634 | 82015.701 | 69863.303 |
Be cautious about the interpretation of these results as we estimate an association from an observational study, and not a causal effect
The {bdlnm} package provides a complete and accessible implementation of Bayesian Distributed Lag Non-Linear Models in R
Combining the flexibility of DLNMs with full Bayesian inference enables researchers to fit more realistic and complex models
The posterior distribution of all estimates allows direct uncertainty quantification of derived measures (e.g., MMT, attributable fractions, attributable numbers) without additional approximations
Posterior summaries are fully compatible with frequentist workflows, making adoption straightforward for practitioners familiar with {dlnm}
{bdlnm} constitutes a valuable tool for environmental risk research and, more generally, for any time series analysis with delayed non-linear effects
Coming soon:
Multi-location analysis: model different exposure-lag-response curves across cities or regions within a single model (e.g., SB-DLNM)
Parallelization: faster inference via {futurize} for large datasets
Compatibility beyond INLA: use MCMC algorithm (e.g. NIMBLE, Stan) for Bayesian model estimation
SB-DLNMs (Quijal-Zamorano et al. 2024) adds a spatial structure to the cross-basis coefficients for reliable small-area estimation:
\[Y_{it} \sim \text{Poisson}(\mu_{it}) \qquad \log(\mu_{it}) = \alpha_i + \underbrace{cb(x_{it}, \ldots, x_{it-L}) \cdot \beta_i}_{\text{spatial cross-basis}} + \sum_{k} \gamma_k u_{kit}\]
\[\beta_i = \mu_\beta + \phi_i + \epsilon_i, \qquad \phi_i \mid \phi_{-i} \sim \mathcal{N}\!\left(\bar{\phi}_{\delta_i},\, \frac{\sigma^2_\phi}{|\delta_i|}\right)\]
| Term | Description |
|---|---|
| \(\beta_i\) | Location-specific cross-basis coefficients |
| \(\mu_\beta\) | Overall pooled exposure-lag-response association |
| \(\phi_i\) | Spatially structured random effect (ICAR prior) |
| \(\epsilon_i \sim \mathcal{N}(0, \sigma^2_\epsilon)\) | Unstructured random effect |
| \(\delta_i\) | Set of spatial neighbours of area \(i\) |
The full bivariate association can be represented as a 3-D surface over temperature and lag, giving the RR at each specific temperature-lag combination: