Skip to contents

a ratio with its uncertainty kept

R-CMD-check Codecov test coverage License: MIT

Bayesian hierarchical models for ratios, rates, and proportions, with inference on the numerator and denominator rather than their quotient.

Give it the two counts, not the ratio. tulpaRatio fits the numerator and denominator processes jointly, with shared random effects between them, and derives the ratio posterior afterwards with uncertainty carried through from both components. Sampling runs on a native HMC/NUTS backend built on the tulpa engine, with no Stan or JAGS to install. The usual approach divides first and models the quotient (or pins the denominator into an offset); that discards the shared structure and mis-states the uncertainty.

library(tulpaRatio)

# catch-per-unit-effort: model catch and effort, derive CPUE
fit <- tratio(
  catch | effort ~ depth + season + (1 | site),
  data   = trawl_data,
  family = ratiod_poisson_gamma()
)

ratio(fit)                    # CPUE posteriors, uncertainty propagated
ratio_contrast(fit, ~ season) # compare seasons on the derived ratio

Derived, not divided

Dividing two measured quantities inherits the error of both and creates heteroscedasticity by construction: a site with more effort gives a more precise CPUE, yet a model fit to the quotient treats every ratio as equally informative. The offset fix assumes effort acts on catch with a coefficient of exactly 1 and that effort carries no structure of its own. tulpaRatio keeps both processes as what they are, models them together, and computes the ratio from the joint posterior.

# the offset approach assumes proportionality and a structureless denominator
glm(catch ~ depth + season + offset(log(effort)), family = poisson, data = df)

# tulpaRatio models both processes, derives the ratio post hoc
tratio(catch | effort ~ depth + season + (1 | site),
       data = df, family = ratiod_poisson_gamma())

See Why Ratios Are Not Data for the full argument.

Model families

Family Numerator Denominator Use case
ratiod_negbin_negbin() NegBin NegBin Count/count ratios (relative abundance)
ratiod_poisson_gamma() Poisson Gamma Count/continuous effort (CPUE)
ratiod_binomial() Binomial Known trials Success/trial proportions
ratiod_negbin_gamma() NegBin Gamma Overdispersed count/effort
ratiod_beta_binomial() Beta-Binomial Known trials Overdispersed proportions
ratiod_gamma_gamma() Gamma Gamma Continuous/continuous ratios
ratiod_lognormal() Lognormal Lognormal Continuous ratios on the log scale

Zero-inflation, one-inflation, hurdle, and zero-and-one-inflated variants are available for the relevant families.

Hierarchical, spatial, and temporal structure

Inference backends and tiers

mode = "auto" picks an exact or structured backend for the model and never silently drops to an approximation that lacks a convergence guarantee.

  • Tier 1 (exact): HMC/NUTS (default), elliptical slice sampling, Pólya-Gamma Gibbs for binomial models.
  • Tier 2 (structured): Laplace approximation for large datasets.
  • Tier 3 (optimized): variational inference and stochastic-gradient MCMC, available by explicit opt-in only.

LOO and WAIC are provided for model comparison. See [inference_mode_info()] for the tier system.

Process-specific predictors

The numerator and denominator can take different predictors:

fit <- tratio(
  species_count | total_count ~ (1 | site),
  formula_num   = ~ depth + temperature,   # numerator process
  formula_denom = ~ sampling_effort,        # denominator process
  data   = df,
  family = ratiod_negbin_negbin()
)

Installation

install.packages("pak")                   # development version
pak::pak("gcol33/tulpaRatio")

Support

“Software is like sex: it’s better when it’s free.” — Linus Torvalds

I’m a PhD student who builds R packages in my free time because I believe good tools should be free and open. I started these projects for my own work and figured others might find them useful too.

If this package saved you some time, buying me a coffee is a nice way to say thanks. It helps with my coffee addiction.

Buy Me A Coffee

License

MIT (see the LICENSE.md file)

Citation

@software{tulpaRatio,
  author = {Colling, Gilles},
  title  = {tulpaRatio: Bayesian Hierarchical Models for Ratios, Rates, and Proportions},
  year   = {2025},
  url    = {https://github.com/gcol33/tulpaRatio}
}