Skip to content

What can I fit today?

This page is the map of the model space DRM.jl covers — the overview for the Model Guides. It mirrors drmTMB's What can I fit today?, and points you at the guide or tutorial for each piece. Read it top to bottom for the big picture, or jump to the which page next table.

The one idea: a formula per parameter

DRM.jl is distributional regression — you put predictors on every parameter of the response distribution, not just the mean. Each parameter gets its own formula, bundled together with bf:

ParameterWhat it controlsFormula
μ (mean / location)where the response sitsthe response formula, y ~ …
sigma (scale / dispersion)how spread out it issigma ~ …
family extras — nu, zi, hu, zoi, coishape, zero-inflation, hurdle, boundary massnu ~ …, zi ~ …, …
rho12 (bivariate only)residual correlation between two responsesrho12 ~ …

Always write sigma (never tau) for the scale and rho12 for residual correlation. The same machinery drives every parameter: a formula → a linear predictor → a family-specific link. Which parameters are available depends on the family (Gaussian has no nu; only counts take zi / hu).

See Which scale are you modelling? for the difference between the residual sigma, a group-level SD, and a known sampling variance — they are distinct quantities DRM.jl keeps separate.

The bf(...) front end

bf (alias drm_formula) collects one formula per parameter and reads exactly like drmTMB and brms. It has two forms:

Univariate — positional. The first formula is the mean; the rest name their parameter on the left-hand side:

julia
bf(@formula(y ~ x), @formula(sigma ~ x))                 # mean + scale
bf(@formula(y ~ x), @formula(sigma ~ 1), @formula(nu ~ 1))   # + shape (Student)

Bivariate — keyword. Name each of the two responses' parameters explicitly, including the residual correlation rho12:

julia
bf(mu1 = @formula(y1 ~ x), mu2 = @formula(y2 ~ x),
   sigma1 = @formula(sigma1 ~ 1), sigma2 = @formula(sigma2 ~ 1),
   rho12 = @formula(rho12 ~ x))

You pass the bundle and a family to drm: drm(bf(...), Gaussian(); data = dat). ML is the default (REML likelihoods are not comparable across fixed-effect structures, so ML is what model selection needs). For the full grammar — including cbind(successes, failures) ~ … for binomial-type responses — see the model specification reference.

Supported families

Pick the family from the shape of the response; the Choosing response families guide has the full decision table and worked examples. DRM.jl implements drmTMB's complete family set:

FamilyResponseMean linksigma slot / extras
Gaussianreal-valued, symmetricidentityresidual SD σ (log)
Studentreal-valued, heavy tailsidentityscale σ + d.o.f. nu
LogNormalpositive, multiplicativeidentity on log ySD of log y
Gammapositive, continuouslogCV → shape α = 1/σ²
Tweediepositive with exact zeroslog√dispersion σ + power nu ∈ (1,2)
Poissoncounts (var ≈ mean)log— (+ zi / + hu)
NegBinomial2overdispersed counts (NB2)logdispersion θ (+ zi / + hu)
TruncatedNegBinomial2positive counts (≥ 1)logdispersion θ
Betaproportions in (0,1)logitprecision φ = 1/σ²
BetaBinomialsuccesses / trials, overdispersedlogitφ = 1/σ² (cbind)
Binomialsuccesses / trialslogit— (cbind or 0/1)
ZeroOneBetaproportions on [0,1] incl. 0 and 1logitφ + zoi / coi
CumulativeLogitordered categories 1..Klogit (cutpoints)K−1 ordered cutpoints

The count modifiers — zi (zero-inflation, ZIP / ZINB), hu (hurdle), and the beta boundary modifiers zoi / coi — are themselves formulas you add to the bundle, e.g. bf(@formula(y ~ x), @formula(zi ~ 1)).

Structured and random effects

On top of fixed effects, DRM.jl carries ordinary random effects and several structured effects whose covariance comes from a known matrix or geometry. Write them as terms in the mean formula:

EffectTermWhat it encodes
Random intercept / slope(1 | g), (0 + x | g), (1 + x | g)exchangeable group variation; correlated slopes
Crossed / nested RE(1 | g) + (1 | h)multiple grouping factors
phylophylo(1 | species)covariance from a phylogenetic tree
spatialspatial(1 | site)exponential kernel over coordinates, estimated range
animalanimal(1 | id)additive-genetic covariance from a pedigree A
relmatrelmat(1 | id)a user-supplied relatedness matrix K
meta_Vmeta_V(v)known sampling (co)variances for meta-analysis

Which families route which effects. Gaussian gets the full set — random intercept/slope, correlated and crossed RE, phylo / spatial / animal / relmat structure, meta_V, and a random effect on sigma — fit in closed form or via a sparse augmented-state Laplace approximation. The non-Gaussian families (Poisson, NB2, Binomial, Gamma, Beta, Student-t, LogNormal, Beta-binomial, Tweedie and CumulativeLogit) carry random intercepts via Gauss–Hermite marginals, and random slopes for every one of them except Binomial(), which supports (1 | g) on the mean only. The capability matrix records which slope form — independent or correlated — each family admits. Phylogenetic (phylo) effects go via a sparse Laplace path for Poisson, NB2, Binomial, Gamma, Beta, Beta-binomial and CumulativeLogit. On that path NB2, Gamma and Beta accept a covariate dispersion formula sigma ~ x (a per-observation log σ, #164), while BetaBinomial() requires a constant sigma and Binomial() carries no dispersion parameter at all; Student() rejects meta_V and every structured marker. LogNormal() is the exception: because log y is exactly Gaussian, its phylo/relmat structured markers on the mean delegate WHOLESALE to Gaussian() on log y (exact, not a Laplace approximation) rather than the shared non-Gaussian sparse path; animal/spatial are not implemented for LogNormal(). So put predictors on sigma for Gaussian freely; for the count/proportion families, vary the mean and keep dispersion constant when adding a structured or phylogenetic effect.

CumulativeLogit (ordinal) carries an ordinary random intercept (1 | g) or an independent random slope (0 + x | g) on mu via the same Gauss–Hermite scheme, and an intercept-only phylo(1 | species) through the same sparse Laplace engine (src/cumulative.jl:518, test/test_cumlogit_phylo.jl); the correlated form (1 + x | g) and the other structured (phylo/relmat/animal/spatial) effects are not implemented yet.

For the verified engine behind the phylogenetic models — the q=4 phylogenetic bivariate location–scale model, which matches drmTMB's fit and still returns usable Wald and bootstrap intervals where drmTMB's Hessian is singular — see HANDOVER.md and report/comparison-grid.md.

After the fit

Every fitted model supports the same post-fit surface: coef, stderror, Wald and profile-likelihood confint, fitted / residuals, predict, simulate, parametric bootstrap_ci, summary / coeftable, and aic / bic for ML model selection. Variance components come back via re_sd (one SD per grouping) and vc (the RE covariance). See Checking and using fitted models for the workflow, and Which scale are you modelling? for honest inference at a variance boundary (where drmTMB's sdreport returns all-NaN).

Which page next

If you want to…Go to
Fit your first model, end to endGet started
Choose the right response familyChoosing response families
Tell residual σ, group SD, and known V apartWhich scale are you modelling?
Extract coefficients, CIs, predictionsChecking and using fitted models
Diagnose convergenceConvergence
Scale to large dataLarge data
Choose the marginal method (Laplace vs VA)Marginal: LA vs VA
Model variability as signal (location–scale)When variance carries signal
Predictors on a random effect's SD (location–scale–scale, incl. climate-dependent phylogenetic SD)Part 2: location–scale–scale
Change residual coupling with rho12Changing residual coupling with rho12
Robust continuous responsesRobust continuous responses
Counts and extra zerosCount abundance and extra zeros
Proportions and success ratesProportions and success rates
Phylogenetic / spatial / animal modelsPhylogenetic · Spatial · Animal
Meta-analysis with known variancesMeta-analysis
The full API referenceModel specification · Fitting & post-fit
What's planned nextthe roadmap