bayesTLS R PackagebayesTLS is an R package for fitting joint Bayesian
four-parameter logistic (4PL) models to thermal death time (TDT) and
thermal load sensitivity (TLS) data. It works with raw counts or
continuous proportions, extracts classical quantities such as
z, CTmax, Tcrit, and LT curves as posterior
summaries, and provides tools for uncertainty propagation, group
contrasts, heat-injury prediction, and bundled case-study data.
Please cite the companion paper when using bayesTLS:
Noble, D.W.A., Arnold, P.A., Nakagawa, S. & Pottier, P. (in preparation). A flexible modelling framework for estimating thermal tolerance and sensitivity.
This paper is the primary citation for both the statistical framework
and the bayesTLS package. Citation details will be updated
here when the paper is published. You can also run
citation("bayesTLS") in R for the formatted reference and a
BibTeX entry.
bayesTLS packageThe analytical workflow ships as an installable R package at the root of this repository. Install from GitHub:
install.packages("remotes") # if needed
remotes::install_github("daniel1noble/bayesTLS")
library(bayesTLS)The package depends on brms (which needs
a Stan backend; cmdstanr is
recommended). All other imported dependencies (dplyr,
ggplot2, MASS, patchwork,
posterior, tibble) are CRAN packages and
resolve automatically. The classical two-stage beta-binomial Stage 1
additionally uses the suggested glmmTMB
package.
bayesTLSThe coding workflow is decoupled — each step is a standalone function so users can stop, swap, or skip at any stage:
| Function | Role |
|---|---|
standardize_data() |
Rename user columns to standard names; supports count responses (survived/dead/total) and continuous proportions; records response type + metadata. |
make_4pl_priors() /
make_4pl_formula() |
Disjoint-bounds reparameterised 4PL; asymptote bounds adjustable for sublethal/PSII ranges. |
fit_4pl() |
Joint Bayesian 4PL via brms. Family resolved from the
response — beta_binomial(identity) for counts,
Beta(identity) for proportions. Centred temperature;
temp_effects selects which 4PL parameters depend on
temperature (all four by default; "mid" for sparse
designs). Two parameterisations: midpoint (default) and
direct CTmax/z (supply
ctmax =/z = formulas). To compare moderator
groups (species, life stage, …) in one joint fit, use
by = "<moderator>" (midpoint — fits
~ temp_c * moderator on all four sub-parameters) or
ctmax = ~ 0 + <moderator> (direct); the moderator is
recorded so downstream readers auto-group. mid = gives
explicit control of the midpoint sub-model. |
tls() / tls_z() / tls_ctmax()
/ tls_tcrit() |
One call to derive z, CTmax, and (lethal data only,
lethal = TRUE) Tcrit per
moderator group (by =; sex, life stage, clone, …)
from any fitted 4PL — a bayes_tls workflow or a
hand-written brms 4PL — all from one consistent posterior.
z and CTmax share one posterior subsample; seed =
makes the subsample + Tcrit draws reproducible.
target_surv picks the relative (default) or absolute
threshold. |
derive_z(), derive_tdt_curve(),
derive_temperature_for_duration(),
derive_tdt_landscape() |
Exported TDT primitives (the building blocks tls()
composes, and available directly for advanced use such as the
per-temperature local z(T) profile from
derive_z()); all support per-group results via
by =. |
extract_4pl_pars(), tdt_parameter_table(),
tdt_quantile(),
summarise_observed_survival() |
Per-draw 4PL parameters, natural-scale posterior parameter tables
(group-aware via by =), TDT-friendly quantile summaries,
and observed-survival cell summaries (mean ± SE per temp ×
duration). |
predict_survival_curves(),
predict_heat_injury(),
repair_rate_schoolfield() |
Posterior survival curves and heat-injury accumulation under a
temperature trace (both per-group via by =), with an
optional Sharpe–Schoolfield repair kernel supplied by
repair_rate_schoolfield(). |
make_temperature_scenarios(),
planted_dose_from_trace() |
Reference temperature traces and the analytical HI integral for validation. |
ts_stage1(), ts_stage2(),
ts_ci(), ts_curve() |
The classical two-stage TDT pipeline for
side-by-side comparison: per-temperature dose-response
(stats::glm binomial or glmmTMB beta-binomial)
→ OLS of log10(LT50) on temperature → z, CTmax,
Tcrit, with delta-method (Normal/t) or MVN
intervals. One implementation, shared by the manuscript tutorial, case
studies, and the bias simulation. |
diagnose_tdt_fit(), bayes_R2_tls() |
Sampling diagnostics (R-hat, ESS, divergences) and Bayesian R^2 summaries for a fitted workflow. |
plot_survival_curves(), plot_tdt_curve(),
plot_tdt_landscape(), plot_heat_injury(),
plot_temperature_scenarios(),
plot_temperature_density(),
plot_repair_rate(), theme_tdt() |
Plotting helpers for survival curves, TDT curves, tolerance
landscapes, heat injury, temperature traces/densities, and repair TPCs,
with a shared project theme. Where a fitted curve/surface is overlaid on
data (plot_survival_curves(),
plot_tdt_landscape(), plot_tdt_curve()), it is
by default capped at each group’s longest observed exposure (shorter
durations still shown) and, for grouped fits, faceted with free
per-group axes (clip_to_observed,
facet_scales); pass clip_to_observed = FALSE
for the full prediction grid. |
get_brmsfit(), get_tls_est(),
get_4pl_est(), get_surv_draws(),
get_hi_draws(), has_fit(), … |
Accessors for the underlying fit, posterior draws, and posterior
summaries. get_tls_est() pulls draws or summary
for any/all TLS quantities from a tls() object, merged on
.draw so quantities keep their joint pairing (for contrasts
and bivariate plots); get_4pl_est() is its 4PL-shape
counterpart (draws or summary of
low/up/k/mid from a
fitted workflow). |
clock_to_minutes(), format_interval() |
Utilities: parse clock-time strings to elapsed minutes; format a
posterior median with its interval as
median [lower, upper]. |
Full reference: ?fit_4pl, ?tls,
?predict_heat_injury, etc.
bayesTLS DataFour publicly available datasets are included with the
bayesTLS package to make it easier to reproduce analyses
and results in the paper and for testing purposes. These datasets
are:
| Dataset | Help | Endpoint |
|---|---|---|
snowgum_psii |
?snowgum_psii |
Snowgum leaf PSII (continuous proportion) |
dsuzukii |
?dsuzukii |
Drosophila suzukii multi-trait TDT (lethal, knockdown, fertility; per individual) |
zebrafish_o2 |
?zebrafish_o2 |
Zebrafish lethal TDT across an oxygen gradient (survival counts) |
aphid_tdt |
?aphid_tdt |
Cereal-aphid lethal TDT — three species × ages, heat + cold branches (survival counts) |
Each dataset can be loaded easily using data(aphid_tdt)
(as an example of loading the aphid_tdt dataset). If you
want other datasets loaded then simply replace aphid_tdt.
If you want to learn more about a dataset you can explore it’s helpful
?aphid_tdt.
This repository also contains the code needed to reproduce the
companion paper, its supplement, and the simulation results. To do this,
install the package from this repository, render the Quarto documents
through the Makefile, and use the tests to verify the
package functions used by the manuscript and supplement. All code chunks
are provided in ms/ms.qmd and
ms/supplement.qmd; use make supp to render the
supplement and scripts/simulations/run_simulations.R to
rerun the full two-stage-bias simulation suite. The large cached
artifacts the renders read (simulation outputs and brms
model fits) are not stored in the repository; make data
downloads them from the project’s public OSF deposit (see Fetching cached outputs
below) so you need not re-fit or re-simulate. Run all scenarios with
Rscript scripts/simulations/run_simulations.R, or a subset
by passing scenario labels,
e.g. Rscript scripts/simulations/run_simulations.R scen9_tmax_060.
Each scenario and the per-simulation pipeline are visible in that one
script; the reusable building blocks live in
scripts/simulations/sim_functions.R.
Use this map to find the files and outputs involved in reproduction:
Makefile — main entry point for rendering the
manuscript and supplement.ms/ms.qmd — manuscript source file; renders to
_output/ms.html, _output/ms.docx, and
_output/ms.pdf.ms/supplement.qmd — supplement source file; renders to
_output/supp.html, _output/supp.docx, and
_output/supp.pdf.R/ — package source for the analysis functions used by
the paper; see Key
functions.data/ — bundled package datasets as .rda
files.inst/extdata/ — source CSV files used to build the
bundled datasets.data-raw/make_datasets.R — script that rebuilds the
.rda datasets from the source CSV files.output/models/ — cached brms fits
(.rds) created and reused during renders.scripts/simulations/ — the two-stage-bias simulation:
run_simulations.R (scenarios + runner) and
sim_functions.R (reusable building blocks).scripts/ — other support scripts (presentation figures,
document cleanup).tests/testthat/ — fast unit tests plus optional
brms integration tests.bib/ — bibliography and the Ecology Letters CSL
file.notes/ — dated development notes for derivations,
literature checks, and simulations.man/ — roxygen-generated package help files._output/ — final rendered manuscript and supplement
files; created by the render commands below.Install the package from this repository so the renders use the same code you are reproducing:
# install.packages("devtools") # if needed
devtools::install()Fetch the cached artifacts the renders read (simulation outputs
and brms model fits), which are not stored in the
repository:
make data # results + model fits (~85 MB) -- enough to render the paper
make data-full # ALSO the 2.6 GB raw/draws tier (only to re-aggregate sims)make data is safe to re-run: a tier already present
locally is skipped. No credentials are needed (the OSF deposit is
public).
Render the manuscript, supplement, or both from the repository root:
make all # manuscript and supplement, all formats
make ms # manuscript only: _output/ms.{html,docx,pdf}
make supp # supplement only: _output/supp.{html,docx,pdf}You can also render one format at a time, for example
make ms-pdf or make supp-html.
The first supplement render may take several minutes because it fits
or checks cached models. Subsequent renders reuse the .rds
files in output/models/ and should be much faster.
Inspect the rendered files in _output/. Use
make clean to remove only _output/, or
make build-clean to also remove the out-of-tree Quarto
build cache at ~/Library/Caches/tls-render/.
The simulation outputs and brms model fits the
manuscript reads are large and are not committed to the
repository. They live in the project’s public OSF deposit (node c6dxy) as tiered zip
archives, fetched with make data:
| Command | Downloads | Size | Use |
|---|---|---|---|
make data |
results.zip + models.zip |
~85 MB | render the paper (default) |
make data-full |
the above plus sim_full.zip |
+2.6 GB | re-aggregate the raw simulation |
make data is idempotent — a tier already present under
output/ is skipped (pass TIER=--force to
re-download), each download is md5-verified against
data-raw/osf_manifest.json, and the archives unpack
straight into output/. No credentials are required.
Maintainers refresh the deposit with make osf-push (needs
an OSF_PAT token); see
scripts/osf_publish.R.
Run the package tests if you want to verify the analysis functions separately from the manuscript render:
devtools::test()
Sys.setenv(RUN_BRMS_TESTS = "true")
devtools::test()The first command runs the fast unit tests. The second also runs the
gated brms integration tests, which fit small cached models
and check parameter recovery.
The manuscript and supplement are independent Quarto documents. There
is no project-level _quarto.yml; each .qmd
file carries its own YAML so the files can be rendered separately. The
Makefile renders outside the Dropbox-synced project
directory, then copies only the final HTML, DOCX, and PDF files back to
_output/. This avoids conflicted intermediate files while
preserving cached model fits in output/models/.
Within a document, use Quarto’s @ references as normal
(@fig-X, @tbl-X, @eq-X,
@sec-X). Between the manuscript and supplement, use plain
text, such as “Equation 7 of the manuscript” in the supplement or
“Figure S2” in the manuscript. The supplement render automatically
labels figures, tables, and equations with an “S” prefix.
See CLAUDE.md
§8a for more detail on the render architecture, cross-reference
handling, and the brms cache.
The supplement works through the same workflow on simulated data and four empirical examples:
life_stage as a covariate.The supplement also contains the two-stage-bias simulation results and sensitivity sweeps used to check the modelling framework.