This developer article documents the supported
drm_formula() grammar, including response blocks,
distributional-parameter formulae, and validation rules.
bf() remains a short alias. It assumes you have already
written a first formula from a family tutorial and now need the complete
grammar and status table, not another worked example.
The design reference is
docs/design/01-formula-grammar.md.
Fixed-effect formulas use base R’s ordinary formula machinery.
Transformations and interaction expansions such as
poly(x1, 2), I(x1^2), x1 * x2,
and (x1 + x2 + x3)^2 work for implemented fixed-effect
distributional-parameter formulas. For ecological and evolutionary
examples, second-order terms are usually the practical default;
third-order polynomials should be treated as exceptional and justified
by the question and data.
Current status map
Use this table before copying syntax into an analysis. “Implemented” means the syntax is parsed and has a fitted likelihood path for the family named in the notes. “Reserved” means the syntax is part of the public design vocabulary but should currently give a clear unsupported-feature error rather than a fit. “Planned” means the syntax is shown only to explain the roadmap.
In this table, “coscale” means a model for residual correlation,
currently rho12 in two-response Gaussian models.
If the family itself is missing from this table, the gap is not a formula question – see Adding distribution families for how a new distribution enters the package.
| Syntax | Current status | Notes |
|---|---|---|
drm_formula() and bf()
|
Implemented |
drm_formula() is the explicit constructor;
bf() is a short alias. |
y ~ x1 + x2, sigma ~ x1
|
Implemented | Univariate Gaussian location-scale model. |
y ~ x1 + x2, sigma ~ x1,
nu ~ x2
|
Implemented | Fixed-effect univariate Student-t location-scale-shape model. |
y ~ x1 + (1 | id) + (0 + x1 | id),
sigma ~ x2, nu ~ 1,
family = student()
|
Implemented first slice | Ordinary Student-t mu random intercepts and independent
numeric slopes enter the identity-location predictor. A single
unlabelled spatial(1 + x | id, coords = coords) one-slope
structured effect on mu is recovery grade – trust the point
estimate, not the interval. The intercept-only spatial mu
route and exact nu ~ phylo(1 | id, tree = tree)
structured-intercept route are diagnostic grade only. Correlated slopes,
labelled covariance blocks, sigma random effects, other
nu random effects, other structured providers
(animal()/relmat() on mu;
spatial()/animal()/relmat() on
nu), additional structured slopes and labelled q2/q4
blocks, known covariance, and bivariate Student-t models remain
planned. |
y ~ x1 + (1 | id) + (0 + x1 | id),
sigma ~ x2, nu ~ x3,
family = skew_normal()
|
Implemented first slice | Skew-normal ordinary mu random intercepts and
independent numeric slopes enter the response-mean predictor. The exact
independent-slope ledger cell is inference-ready with caveats for true
SD 0.50 and M>=16. Public sigma is response SD and
nu is residual slant. Correlated or labelled slopes, random
effects outside mu, structured effects, bivariate routes,
and broader calibration remain planned. |
y ~ x1 + x2, sigma ~ x1,
family = lognormal()
|
Implemented | Fixed-effect univariate lognormal model for positive responses;
mu and sigma are on the log-response
scale. |
y ~ x1 + (1 | id) + (0 + x1 | id),
sigma ~ x2, family = lognormal()
|
Implemented first slice | Ordinary lognormal mu random intercepts and independent
numeric slopes enter the log-response location. Arc 3a also admits
recovery-grade unlabelled q1 phylo(1 | id, tree = tree) and
relmat(1 | id, K/Q = ...) intercepts in mu.
Correlated or labelled slopes, other structured effects, known
covariance, and bivariate lognormal models remain planned. |
y ~ x1, sigma ~ x2 + (1 | id),
family = lognormal()
|
Implemented first slice | An ordinary lognormal sigma random intercept enters
log-sigma; only its exact ledger domain is inference-ready
with caveats. This scale route cannot be combined with a mu
random effect, and sigma slopes or labels remain
unsupported. |
y ~ x1 + x2, sigma ~ x1,
family = Gamma(link = "log")
|
Implemented | Fixed-effect univariate Gamma mean-CV model for positive responses;
mu is the response mean and sigma is the
coefficient of variation. |
y ~ x1 + (1 | id) + (0 + x1 | id),
sigma ~ x2, family = Gamma(link = "log")
|
Implemented first slice | Ordinary Gamma mu random intercepts and independent
numeric slopes enter the log-mean predictor. A single unlabelled
relmat(1 | id, K = K) or
relmat(1 + x | id, K = K) structured intercept or one-slope
on mu is implemented at recovery grade. Arc 3a also admits
a recovery-grade unlabelled q1 phylo(1 | id, tree = tree)
intercept. Correlated or labelled slopes, new-route slopes, other
structured providers (spatial()/animal()),
known covariance, and bivariate or mixed Gamma models remain
planned. |
y ~ x1, sigma ~ x2 + (1 | id),
family = Gamma(link = "log")
|
Implemented first slice | An ordinary Gamma sigma random intercept enters log-CV.
Its ML-Laplace profile interval is inference-ready with caveats only at
true SD 0.40, n_each=12, and M >= 32
(M=16 borderline). This scale route cannot be combined with
a mu random effect; sigma slopes, labels,
REML, and supported remain outside the claim. |
y ~ x1 + x2 + (1 | id) + (0 + x1 | id),
sigma ~ x1, nu ~ 1,
family = tweedie()
|
Implemented first slice | Tweedie model for non-negative semicontinuous responses with exact
zeros; ordinary mu random intercepts and independent
numeric slopes are fitted. The exact independent-slope ledger cell is
inference-ready with caveats for true SD 0.50 and M>=16. Public
sigma maps to phi = sigma^2, and
nu is constrained to 1 < nu < 2.
Predictor-dependent nu, distributional random effects
beyond ordinary mu, structured effects, zero-inflation
aliases, and hurdle aliases remain planned. |
y ~ x1 + x2, sigma ~ x1,
family = beta()
|
Implemented | Fixed-effect beta mean-scale model for strict continuous proportions
in (0, 1); public sigma maps internally to
phi = 1 / sigma^2. |
y ~ x1 + (1 | id) + (0 + x1 | id),
sigma ~ x2, family = beta()
|
Implemented first slice | Ordinary beta mu random intercepts and independent
numeric slopes enter the logit-mean predictor for strict
(0, 1) responses. Row-specific structured exceptions are
the recovery-grade animal() routes and the exact unlabelled
q1 phylo(1 | species, tree = tree) intercept in
mu documented below; family sigma remains
fixed-effect-only for the phylogenetic cell. Correlated slopes, labelled
covariance blocks, ordinary sigma random effects, exact 0/1
boundary mass, zoi/coi,
spatial()/relmat(), phylogenetic slopes or
scale-side structure, labelled q2/q4 or joint
mu+sigma structured blocks, known covariance,
beta-binomial denominators, and bivariate or mixed bounded-response
models remain planned. |
y ~ x1 + (1 | id) + (0 + x1 | id),
sigma ~ x2, zoi ~ x3, coi ~ x4,
family = zero_one_beta()
|
Implemented first slice | Zero-one beta model for continuous proportions on
[0, 1] with exact structural boundary mass and ordinary
mu random intercepts or independent numeric slopes. The
exact independent-slope ledger cell is inference-ready with caveats for
true SD 0.50 and M>=16 under its generator-qualified evidence; it
does not establish a general boundary-mass calibration claim.
mu and sigma describe the interior beta
component, zoi is exact-boundary probability,
coi is the probability of an exact one conditional on the
boundary, and fitted() includes boundary mass. Random
effects in sigma, zoi, or coi,
correlated or labelled covariance, structured effects, denominators, and
bivariate or mixed bounded-response models remain planned. |
y01 ~ x1 + x2 + (1 | id) + (0 + x1 | id),
family = stats::binomial(link = "logit")
|
Implemented first slice | Plain Bernoulli response model for explicit 0/1 event data.
mu is the event probability and there is no public
sigma; ordinary mu random intercepts and
independent numeric slopes are fitted. Only the exact ledger domain for
the independent slope is inference-ready with caveats. Non-logit links,
factor responses, proportions with trial weights, correlated or labelled
slopes, structured effects, bivariate responses, and the halted
engine = "julia" bridge remain unavailable; Julia support
is future work. |
cbind(success, failure) ~ x1 + x2 + (1 | id) + (0 + x1 | id),
family = stats::binomial(link = "logit")
|
Implemented first slice | Plain binomial response model for counted events out of known
trials, with trials = success + failure, fixed effects plus
ordinary mu random intercepts and independent slopes, and
ordinary binomial sampling variation. Use beta_binomial()
instead when extra-binomial variation is part of the scientific
model. |
cbind(success, failure) ~ x1 + (1 | id) + (0 + x1 | id),
sigma ~ x2, family = beta_binomial()
|
Implemented first slice | Ordinary beta-binomial mu random intercepts and
independent numeric slopes enter the logit success-probability predictor
for counted successes out of known trials. Correlated slopes, labelled
covariance blocks, sigma random effects,
zoi/coi, structured effects, known covariance,
and bivariate or mixed bounded-response models remain planned. |
y ~ x1 + x2,
family = poisson(link = "log")
|
Implemented | Fixed-effect univariate Poisson mean model for non-negative integer counts. |
y ~ x1 + (1 | id) + (0 + x1 | id),
family = poisson(link = "log")
|
Implemented first slice | Ordinary Poisson mu random intercepts and independent
numeric slopes on the log-mean scale. Correlated Poisson slope blocks,
labelled covariance blocks, zero-inflated Poisson random effects beyond
the exact diagnostic-only q=1
zi ~ spatial(1 | id, coords = coords) intercept, and
cross-parameter covariance remain planned. |
y ~ x1 + offset(log(exposure)),
family = poisson(link = "log")
|
Implemented | Exposure/rate Poisson model using standard R offset()
syntax in the mu formula. |
y ~ x1 + x2, zi ~ x1,
family = poisson(link = "log")
|
Implemented | Fixed-effect zero-inflated Poisson model; mu is the
conditional count mean and zi is the structural-zero
probability. |
y ~ x1 + x2, sigma ~ x1,
family = nbinom2()
|
Implemented | Fixed-effect univariate negative-binomial 2 model for overdispersed
counts; sigma is an overdispersion scale. |
y ~ x1 + (1 | id) + (0 + x1 | id),
sigma ~ x2, family = nbinom2()
|
Implemented first slice | Ordinary NB2 mu random intercepts and independent
numeric slopes on the log-mean scale. Correlated NB2 slope blocks,
labelled covariance blocks, zero-inflated NB2 random effects outside the
exact fixed-zi spatial structured-mu local-fit
gate, and joint mu/sigma random effects remain
planned. |
y ~ x1, sigma ~ x2 + (1 | id),
family = nbinom2()
|
Implemented first slice | Ordinary NB2 grouped overdispersion random intercepts on the
log-sigma scale. Exact q1 structured sigma
intercept-plus-one-slope routes for phylo(),
spatial(), animal(), and relmat()
are also fitted at recovery grade. Ordinary NB2 sigma
slopes, labelled covariance blocks, joint
mu/sigma random effects,
zero-inflated/truncated/hurdle scale random effects, richer structured
sigma blocks, and structured-sigma intervals/coverage remain
planned. |
y ~ x1 + offset(log(exposure)),
sigma ~ x2, family = nbinom2()
|
Implemented | Exposure/rate NB2 model; the offset enters the mu
linear predictor and sigma remains overdispersion. |
y ~ x1 + x2, sigma ~ x1,
zi ~ x2, family = nbinom2()
|
Implemented | Fixed-effect zero-inflated NB2 model; mu and
sigma describe the conditional count component and
zi is structural-zero probability. |
y ~ x1 + spatial(1 | site, coords = coords),
sigma ~ 1, zi ~ 1,
family = nbinom2()
|
Implemented diagnostic-only gate | Row-specific Q-Series v1.0 fit/extractor evidence for
fixed-covariance spatial structured mu with fixed zero
inflation. It exposes sdpars$mu,
ranef("spatial_mu"), and a direct
profile_targets() row, but it does not establish
point-estimate recovery; intervals, coverage,
inference_ready, supported, labelled q2/q4
count covariance, zero-inflated NB2 structured zi,
structured sigma, REML, AI-REML, and bridge support remain
unavailable. |
y ~ x1 + x2, sigma ~ x1,
family = truncated_nbinom2()
|
Implemented | Fixed-effect zero-truncated NB2 model for positive counts;
mu and sigma describe the untruncated count
component and fitted() is the positive-count mean. |
y ~ x1 + (1 | id) + (0 + x1 | id),
sigma ~ x2, family = truncated_nbinom2()
|
Implemented first slice | Ordinary zero-truncated NB2 mu random intercepts and
independent numeric slopes enter the log-mean predictor while
sigma remains fixed-effect overdispersion. One exact q1
hu ~ relmat(K/Q) intercept is diagnostic-only when the
hurdle route is active; ordinary count-side mu random
effects then remain blocked. Correlated slopes, labelled covariance
blocks, hurdle-side random effects beyond that exact gate,
sigma random effects, structured effects on
mu/sigma, and bivariate count models remain
planned. |
y ~ x1 + x2, sigma ~ x1,
hu ~ x2, family = truncated_nbinom2()
|
Implemented | Fixed-effect hurdle NB2 model; hu is the hurdle-zero
probability and nonzero counts come from the zero-truncated NB2
component. A single unlabelled hu ~ relmat(1 | id, K = K)
or hu ~ relmat(1 | id, Q = Q) q=1 structured intercept on
the hurdle side is also implemented as diagnostic-only (local-fit only;
no coverage or intervals), inherited by the hurdle_nbinom2
alias. Structured
phylo()/spatial()/animal(),
structured slopes, labelled q2/q4 blocks, and structured
mu/sigma remain planned. |
(1 | id) in mu
|
Implemented | Ordinary Gaussian location random intercept. |
(0 + x1 | id) in mu
|
Implemented | Independent numeric location random slope. |
(1 + x1 | id) in mu
|
Implemented | Correlated ordinary intercept-slope block. |
(1 + x1 | p | id) in mu
|
Implemented for naming |
p labels the group-level covariance block for output
and future matching. |
(1 | id) in sigma
|
Implemented | Residual-scale random intercept in the univariate Gaussian
sigma formula. |
(1 | p | id) in both mu and
sigma
|
Implemented | First univariate location-scale covariance slice; p
labels one mean-scale random-intercept covariance block. |
sd(id) ~ x_group |
Implemented | Models the SD of an unlabelled Gaussian mu random
intercept; predictors must be group-level. |
meta_V(V = V) |
Implemented | Preferred spelling for known diagonal, block-diagonal, or dense
sampling covariance in a Gaussian model; bivariate Gaussian known
V uses a complete-row 2n by 2n
row-paired matrix. |
meta_known_V(V = V) |
Deprecated compatibility alias | Warns and then uses the same additive known-covariance path. New
code should use meta_V(V = V). |
mu1, mu2, sigma1,
sigma2, rho12
|
Implemented for fixed effects | Bivariate Gaussian location-coscale model with predictor-dependent residual correlation. |
(1 | p | id) in both bivariate mu1 and
mu2
|
Implemented | First bivariate group-level covariance slice; p labels
a mu1/mu2 random-intercept covariance
block. |
(1 | p | id) in both bivariate sigma1 and
sigma2
|
Implemented | First bivariate residual-scale covariance slice; p
labels a sigma1/sigma2 random-intercept
covariance block on the log-sigma scale. |
(0 + x | p | id) in both bivariate sigma1
and sigma2
|
Implemented first slice |
p labels a sigma1/sigma2
scale-slope block on the log-sigma scale, reported as
cor(sigma1:x,sigma2:x | p | id). |
(0 + x | p | id) in same-response bivariate
mu1 and sigma1, or mu2 and
sigma2
|
Implemented first slice | Matching slope-only terms create one response-specific
mean-scale-slope covariance row, such as
cor(mu1:x,sigma1:x | p | id). Cross-response slope labels
remain planned. |
(1 | p | id) in same-response bivariate
mu1 and sigma1, with optional independent
(1 | q | id) in mu2 and
sigma2
|
Implemented first slice | Each labelled random-intercept pair creates its own
response-specific mean-scale covariance block; residual
rho12 stays separate. |
(1 | p | id) in all four bivariate mu1,
mu2, sigma1, and sigma2
formulas |
Implemented first slice | One ordinary q=4 location-scale covariance block reports all six latent random-effect correlations. |
(1 + x | p | id) in all four bivariate
mu1, mu2, sigma1, and
sigma2 formulas |
Implemented first diagnostic slice | One ordinary q8 endpoint block estimates eight endpoint SDs and reports 28 derived latent correlations. The Phase 18 smoke/recovery artifact lane reports bias, RMSE, MCSE, and interval unavailability; it is not coverage or power evidence. |
sd1(id) ~ x_group, sd2(id) ~ x_group
|
Implemented | Family B direct SD formulas for labelled bivariate location random intercepts; not for residual-scale random effects. |
family = c(gaussian(), gaussian()) |
Implemented | Routes to the bivariate Gaussian engine; mixed composed families are planned. |
biv_gaussian() |
Implemented legacy helper | Kept for compatibility while composed families become the public direction. |
mvbind(y1, y2) ~ x1 |
Implemented | Shorthand for identical bivariate location formulas; explicit
mu1/mu2 remains preferred for different
predictors. |
phylo(1 | species, tree = tree) in mu
and/or sigma
|
Implemented | Intercept-only univariate Gaussian phylogenetic location and
residual-scale effect; matching mu/sigma terms
estimate one latent structured correlation. Requires an ultrametric tree
with branch lengths. |
y ~ x + phylo(1 | species, tree = tree),
sigma ~ z, family = beta()
|
Implemented exact q1 recovery slice | One unlabelled intercept-only phylogenetic location effect in Beta
mu; family sigma remains fixed-effect-only and
controls phi = sigma^(-2). Point recovery passed only in
the exact tested g = 1024, m = 4 regime. This is not
g >= 1024; slopes, labels/q2+, phylogeny in family
sigma, direct latent-sd() regression, REML,
intervals, and coverage remain deferred. |
animal(1 | id, pedigree = pedigree),
animal(1 | id, A = A), or
animal(1 | id, Ainv = Ainv) in mu and/or
sigma
|
Implemented first slice | Univariate Gaussian animal-model random intercept from a dense
pedigree-derived additive relationship matrix, precomputed additive
relatedness, or inverse-relatedness matrix. Matching
mu/sigma terms estimate one latent structured
correlation. One numeric mu slope is fitted; the exact
A-matrix q1 sigma one-slope route is also fitted and
inference-ready with caveats under raw log-SD Wald-z intervals.
Pedigree/Ainv bridge marshalling, sparse large-pedigree construction,
additional multiple or labelled structured-slope layouts outside the
exact fitted ledger cells, structured slope correlations,
predictor-dependent corpair(), and direct-SD grammar remain
planned. |
matching labelled
animal(1 | p | id, pedigree = pedigree),
animal(1 | p | id, A = A), or
animal(1 | p | id, Ainv = Ainv) in bivariate
mu1 and mu2
|
Implemented first q=2 slice | Estimates two latent animal-model location scales and one animal
mean-mean correlation from the same pedigree-derived or precomputed
matrix. Individual marginal SDs also include
sqrt(A[i, i]). |
matching labelled
animal(1 | p | id, pedigree = pedigree),
animal(1 | p | id, A = A), or
animal(1 | p | id, Ainv = Ainv) in all four bivariate
mu1, mu2, sigma1, and
sigma2 formulas |
Implemented first q=4 slice | Estimates four latent animal-model endpoint scales and six constant
latent location-location, location-scale, and scale-scale correlations
from the same matrix. Individual marginal SDs also include
sqrt(A[i, i]). |
relmat(1 | id, K = K) or
relmat(1 | id, Q = Q) in mu and/or
sigma
|
Implemented first slice | Lower-level univariate Gaussian random intercept from a
user-supplied latent relatedness covariance or precision matrix.
Matching mu/sigma terms estimate one latent
structured correlation. Keep observation-level known sampling covariance
in meta_V(V = V). |
matching labelled relmat(1 | p | id, K = K) or
relmat(1 | p | id, Q = Q) in bivariate mu1 and
mu2
|
Implemented first q=2 ML slice; exact supplied-K
intercept-only REML cell at point_fit_recovery
|
Estimates two latent relatedness location scales and one mean-mean
correlation from the same user-supplied matrix. Native
REML = TRUE requires biv_gaussian(), the
identical named K, group ordering, and label in both
location formulas, intercept-only sigma1,
sigma2, and rho12, complete pairs, unit
weights, and no other random, scale-side, meta_V(),
direct-SD, or corpair() layer. Q, slopes, q4+,
intervals, and coverage remain outside this REML cell. Level-specific
marginal SDs also include the known diagonal multiplier. |
matching labelled relmat(1 | p | id, K = K) or
relmat(1 | p | id, Q = Q) in all four bivariate
mu1, mu2, sigma1, and
sigma2 formulas |
Implemented first q=4 slice | Estimates four latent relatedness endpoint scales and six constant latent location-location, location-scale, and scale-scale correlations from the same matrix. Level-specific marginal SDs also include the known diagonal multiplier. |
matching phylo(1 | species, tree = tree) in bivariate
mu1 and mu2
|
Implemented first slice | Estimates two phylogenetic location SDs and one phylogenetic mean-mean correlation. |
labelled phylo(1 | p | species, tree = tree) in
matching bivariate mu1 and mu2
|
Implemented | The label is preserved in SD, correlation, corpairs(),
and profile-target names for the phylogenetic mean-mean path. |
labelled phylo(1 | p | species, tree = tree) in all
four bivariate mu1, mu2, sigma1,
and sigma2 formulas |
Implemented first slice | One constant q=4 phylogenetic location-scale block estimates four endpoint SDs and six latent phylogenetic correlations. Partial, unlabelled, mismatched, and slope forms remain rejected. |
count ~ x + phylo(1 | species, tree = tree) or
count ~ x + spatial(1 | site, coords = coords),
family = poisson(link = "log")
|
Implemented first slice | Ordinary non-zero-inflated Poisson q=1 structured mu
intercept on the log-mean scale for one of phylo(),
spatial(), animal(), or relmat();
unlabelled intercept-plus-one-slope terms are also fitted for those four
providers. Pure, labelled, or multiple structured count slopes, q=2/q=4
count blocks, zero-inflated structured effects outside exact
row-specific local-fit gates, simultaneous structured types within
Poisson, and combinations with ordinary count random effects remain
planned. |
count ~ x + phylo(1 | species, tree = tree) or
count ~ x + relmat(1 | id, Q = Q), sigma ~ z,
family = nbinom2()
|
Implemented first slice | Ordinary non-zero-inflated NB2 q=1 structured mu
intercept on the log-mean scale for one of phylo(),
spatial(), animal(), or relmat(),
while sigma remains fixed-effect overdispersion unless
using a separate fitted sigma route; unlabelled intercept-plus-one-slope
mu terms are also fitted for those four providers. Exact q1
structured sigma intercept-plus-one-slope routes for those
four providers are recovery grade. One exact crossed
mu ~ spatial(1 | site, coords = coords) + relmat(1 | id, Q = Q)
route is recovery-only. Pure, labelled, or multiple structured count
slopes, labelled q=2/q=4 count blocks, zero-inflated NB2 structure
outside the exact local-fit gate, richer or labelled structured sigma,
structured-sigma intervals/coverage, simultaneous structured types
beyond that exact crossed gate, and joint
mu/sigma random effects remain planned. |
count ~ x + phylo_interaction(1 | partner1:partner2, tree1 = tree1, tree2 = tree2)
or Gaussian y ~ x + phylo_interaction(...)
|
Implemented first slice | Single q=1 location random intercept for a two-partner phylogenetic
interaction in univariate Gaussian mu and ordinary
Poisson/NB2 mu. Internally this builds a sparse Kronecker
precision from the two augmented phylogenetic precisions.
relmat(1 | pair, Q = Q_pair) remains the lower-level escape
hatch. Binary/Bernoulli incidence models and additive models that
combine partner main phylogenies plus phylo_interaction()
remain planned. |
y ~ x1 + x2 + (1 | id) + (0 + x1 | id),
family = cumulative_logit()
|
Implemented first slice | Univariate ordinal model for ordered scores with cutpoints; ordinary
mu random intercepts and independent numeric slopes are
fitted, and the exact mc-0227 slope cell is inference-ready
with caveats under its recorded M>=80 design. A single unlabelled
phylo(1 | species, tree = tree) structured mu
intercept is diagnostic-only (fit/extractor feasibility, not
point-estimate recovery or coverage). Correlated or labelled slopes,
other structured routes
(spatial()/animal()/relmat()),
and scale/discrimination formulas are planned. |
cbind(successes, failures) ~ x1,
family = beta_binomial()
|
Implemented | Fixed-effect denominator-aware model for success counts with known
trial totals; sigma is extra-binomial variation. |
phylo(1 + x1 | species, tree = tree) |
Implemented first one-slope slice | Univariate Gaussian mu path with independent
phylogenetic intercept and slope fields; ordinary Poisson and NB2 also
fit one unlabelled q1 intercept-plus-one-slope phylogenetic
mu route at recovery/source-test grade. Pure, multiple, or
labelled count slopes and labelled structured slope blocks such as
phylo(1 + x | p | species, tree = tree) remain rejected
until their covariance and recovery contracts are designed. |
animal(1 + x | id, pedigree = ped) |
Implemented first one-slope slice | Univariate Gaussian mu path with independent
animal-model intercept and slope fields; additional multiple-slope
layouts and slope correlations remain planned outside the exact fitted
bivariate ledger cells. A labelled block in this univariate q1 route is
rejected; use only the exact labelled bivariate layouts recorded as
fitted in the ledger. |
spatial(1 | site, coords = coords) |
Implemented first slice | Univariate Gaussian mu spatial random intercept using a
fixed coordinate covariance foundation; mesh/SPDE paths remain
planned. |
spatial(1 + x | site, coords = coords) |
Implemented first one-slope slice | Univariate Gaussian mu spatial random intercept plus
one numeric spatial slope. The two coordinate fields are independent and
have separate SDs. A labelled block in this univariate q1 route is
rejected; use only the exact labelled bivariate layouts recorded as
fitted in the ledger. |
spatial(1 | p | site, coords = coords) in matching
bivariate mu1 and mu2 formulas |
Implemented q=2 slice; exact intercept-only native REML cell at
point_fit_recovery
|
Bivariate Gaussian location covariance for two coordinate-spatial
random intercept fields. corpairs(level = "spatial")
reports the spatial mean-mean row separately from residual
rho12. Native REML = TRUE requires matching
labels; intercept-only sigma1, sigma2, and
rho12; complete response pairs; unit weights; no known
meta_V() covariance; and no additional ordinary random,
direct-SD, or corpair() layer. Slopes, range estimation,
intervals, and coverage remain planned. |
spatial(1 | p | site, coords = coords) in all four
bivariate mu1, mu2, sigma1, and
sigma2 formulas |
Implemented first q=4 slice | One constant coordinate-spatial location-scale block estimates four endpoint SDs and six latent spatial correlations. Partial, unlabelled, mismatched, and slope forms remain rejected. |
relmat(1 + x | id, K = K) |
Implemented first one-slope slice | Univariate Gaussian mu path with independent
lower-level relatedness intercept and slope fields; additional
multiple-slope layouts and slope correlations remain planned outside the
exact fitted bivariate ledger cells. A labelled block in this univariate
q1 route is rejected; use only the exact labelled bivariate layouts
recorded as fitted in the ledger. |
corpair(id, level = "group", block = "p", from = "mu1", to = "mu2") ~ x_group |
Implemented | Predictor-dependent ordinary q=2 location-location latent
random-effect correlation regression for matching labelled
mu1/mu2 random intercepts. Predictors must be
constant within id. |
corpair(species, level = "phylogenetic", block = "p", from = "mu1", to = "mu2") ~ ecology |
Implemented | Predictor-dependent phylogenetic q=2 location-location latent
random-effect correlation regression for matching labelled
mu1/mu2 phylo() terms. Predictors
must be constant within species. Location-scale,
scale-scale, q=4, and spatial corpair() regressions remain
planned. |
Matching slope-only (0 + x | p | id) in bivariate
mu1 and mu2
|
Implemented first bivariate slope slice | Estimates the ordinary slope1-slope2 plasticity-syndrome correlation without intercept-slope correlations; broader bivariate slope blocks remain planned. |
Matching one-slope intercept-plus-slope
(1 + x | p | id) blocks in bivariate mu1 and
mu2
|
Implemented first q=4 location slice | Estimates two location-intercept SDs, two location-slope SDs, and six group-level latent correlations; the SDs are direct profile targets and the correlations are derived-unavailable interval rows. |
Matching two-slope (1 + x + z | p | id) blocks in
bivariate mu1 and mu2
|
Implemented q=6 location slice with smoke artifact routing | Estimates six location SDs and 15 group-level latent correlations; the SDs are direct profile targets and the correlations are derived-unavailable interval rows. |
p8 endpoint blocks, q8 variants beyond the first matching all-four
ordinary endpoint slice, labelled or cross-formula residual-scale slope
blocks, broader bivariate residual-scale blocks beyond the matching q2
sigma1/sigma2 scale-slope slice, non-Gaussian
cross-parameter covariance, predictor-dependent q=4 phylogenetic/spatial
correlations, or rho12 random effects |
Planned | These need a larger covariance parameterization, simulation, and
naming checks before fitting. Unlabelled ordinary univariate correlated
sigma blocks are already fitted. Intercept-slope
corpair() rows are distant-future; broader
slope-correlation regressions need coefficient-aware syntax. |
corpairs(fit) |
Implemented for current fitted correlations | Reports residual rho12, ordinary and bivariate
group-level covariance rows including ordinary q=4 blocks, bivariate
phylogenetic mean-mean or q=4 rows, bivariate coordinate-spatial q=2 or
constant q=4 rows, and the animal/relmat() q=2 or constant
q=4 rows. |
Current implemented univariate Gaussian random-effect forms include:
drm_formula(y ~ x + (1 | id), sigma ~ z)
drm_formula(y ~ x + (0 + x | id), sigma ~ z)
drm_formula(y ~ x + (1 + x | id), sigma ~ z)
drm_formula(y ~ x + (1 + x | p | id), sigma ~ z)
drm_formula(y ~ x + (1 | id), sigma ~ z + (1 | id) + (0 + w | id))
drm_formula(y ~ x, sigma ~ z + (1 + w | id))
drm_formula(y ~ x + (1 | p | id), sigma ~ z + (1 | p | id))
drm_formula(y ~ x + (1 | id), sigma ~ z, sd(id) ~ x_group)
drm_formula(y ~ x + phylo(1 | species, tree = tree), sigma ~ z)
drm_formula(y ~ x + animal(1 | id, Ainv = Ainv), sigma ~ z)
drm_formula(y ~ x + relmat(1 | line, Q = Q), sigma ~ z)
drm_formula(
y ~ x + (1 | id) + (1 | site),
sigma ~ z,
sd(id) ~ x_group,
sd(site) ~ site_type
)Current implemented Student-t form:
drm_formula(y ~ x, sigma ~ z, nu ~ 1)
drm_formula(y ~ x, sigma ~ z, nu ~ x)
drm_formula(y ~ x + (1 | id) + (0 + x | id), sigma ~ z, nu ~ 1)Student-t ordinary mu random intercepts and independent
numeric slopes are a first location slice, joined by a
spatial(1 | id, coords = coords) structured mu
intercept (diagnostic grade only; it confirms fit/extractor feasibility
but does not establish point-estimate recovery) and a
phylo(1 | id, tree = tree) structured nu
intercept (diagnostic grade only). Correlated Student-t slopes,
sigma random effects, other nu random effects,
known sampling covariance, other structured providers on
mu/nu, and bivariate Student-t models are
later phases.
Future skew-normal and skew-t formulas should also start with
fixed-effect residual-shape terms such as nu ~ x. A later
latent-effect spelling such as skew(id) ~ x_group would ask
a different question about the distribution of group effects and should
not be taught as an alias for residual nu.
Current implemented lognormal form:
drm_formula(biomass ~ habitat, sigma ~ treatment)paired with:
family = lognormal()The response must be positive and finite. mu and
sigma are defined on the log-response scale, and
fitted() returns the arithmetic response mean
exp(mu + sigma^2 / 2).
Current implemented Gamma form:
drm_formula(biomass ~ habitat, sigma ~ treatment)paired with:
family = Gamma(link = "log")Here mu is the response mean and sigma is
the coefficient of variation. Gamma mu random intercepts
and independent numeric slopes are an implemented first slice at
recovery grade. A separate ordinary sigma random intercept
is also fitted at recovery grade; it cannot be combined with a
mu random effect. A single unlabelled
relmat(1 | id, K = K) intercept or one-slope structured
effect on mu is fitted at recovery grade. Correlated or
labelled slopes, sigma slopes, known sampling covariance,
phylo()/spatial()/animal()
structured terms, and bivariate or mixed Gamma models are later
phases.
The middle p is a group-level covariance-block label. It
is not residual rho12, and reserved distributional
parameter names such as rho12 should not be used as labels.
Matching (1 | p | id) terms in univariate Gaussian
mu and sigma fit the first mean-scale
covariance block; larger cross-formula blocks with slopes remain future
work.
Current implemented bivariate form:
drm_formula(
mu1 = y1 ~ x1 + x2,
mu2 = y2 ~ x1,
sigma1 = ~ x1 + x2,
sigma2 = ~ x1,
rho12 = ~ x1 + x2
)When both responses share the same location predictors, the shorter form is also implemented:
drm_formula(
mvbind(y1, y2) ~ x1 + x2,
sigma1 = ~ x1 + x2,
sigma2 = ~ x1,
rho12 = ~ x1 + x2
)This expands internally to mu1 = y1 ~ x1 + x2 and
mu2 = y2 ~ x1 + x2. Use the explicit mu1 and
mu2 formulas when the two responses need different location
predictors.
The first fitted structured-effect marker examples are phylogenetic location effects:
drm_formula(y ~ x + phylo(1 | species, tree = tree), sigma ~ z)
drm_formula(y ~ x + phylo(1 + x | species, tree = tree), sigma ~ z)phylo() uses an ultrametric branch-length tree and adds
tree-structured Gaussian random intercept and one-slope fields to the
mu predictor. Matching intercept-only phylo()
terms in bivariate mu1 and mu2 formulas fit
the first phylogenetic mean-mean correlation slice:
drm_formula(
mu1 = y1 ~ x + phylo(1 | species, tree = tree),
mu2 = y2 ~ x + phylo(1 | species, tree = tree),
sigma1 = ~ 1,
sigma2 = ~ 1,
rho12 = ~ 1
)Matching labelled phylo() terms across all four
bivariate Gaussian endpoints fit the constant q=4 phylogenetic
location-scale block. A single shared label estimates one full q4 tree
block; using one label for mu1/mu2 and another
for sigma1/sigma2 estimates the block-diagonal
fallback:
drm_formula(
mu1 = y1 ~ x + phylo(1 | pl | species, tree = tree),
mu2 = y2 ~ x + phylo(1 | pl | species, tree = tree),
sigma1 = ~ z + phylo(1 | ps | species, tree = tree),
sigma2 = ~ z + phylo(1 | ps | species, tree = tree),
rho12 = ~ 1
)Additional multiple or labelled phylogenetic-slope layouts outside
the exact fitted ledger cells, richer residual-scale structured slopes
beyond the exact q1 routes, partial or mismatched bivariate phylogenetic
scale terms, structured effects in rho12, multiple
animal-model slopes, multiple lower-level relmat() slopes,
multiple spatial slopes, and mesh-based spatial terms are still
planned:
# planned; drmTMB() will currently reject these
drm_formula(y ~ x + phylo(1 + x1 + x2 | species, tree = tree), sigma ~ z)
drm_formula(y ~ x + phylo(1 + x | p | species, tree = tree), sigma ~ z)
drm_formula(y ~ x + animal(1 + x1 + x2 | id, pedigree = ped), sigma ~ z)
drm_formula(y ~ x + animal(1 + x | p | id, pedigree = ped), sigma ~ z)
drm_formula(y ~ x + relmat(1 + x1 + x2 | id, K = K), sigma ~ z)
drm_formula(y ~ x + relmat(1 + x | p | id, K = K), sigma ~ z)
drm_formula(y ~ x + spatial(1 + x | p | site, coords = coords), sigma ~ z)
drm_formula(y ~ x + spatial(1 | site, mesh = mesh), sigma ~ z)The first fitted spatial() paths use coordinates
directly for univariate Gaussian mu coefficient fields:
drmTMB(
bf(y ~ x + spatial(1 | site, coords = coords), sigma ~ z),
family = gaussian(),
data = dat
)
drmTMB(
bf(y ~ x + spatial(1 + x | site, coords = coords), sigma ~ z),
family = gaussian(),
data = dat
)coords can have one row per site or one row per
observation, but coordinates must be constant within each site. A
precomputed mesh remains planned. Mesh is not the
scientific sampling level. It is the computational scaffold that will
keep a future SPDE/GMRF spatial field scalable. These structured effects
are separate from residual rho12.
For structured slopes, the fitted coordinate-spatial path now
supports one numeric mu slope as independent intercept and
slope fields with separate SDs. Additional structured slopes remain the
advanced path after more recovery evidence. Multiple random factors
should remain separate additive blocks. The first slope models should
not estimate predictor-dependent intercept-slope corpair()
rows. The first fitted bivariate targets are the slope1-slope2
correlation and the q4/q6 location blocks with smoke artifact routing
for the same covariates across responses.
The first bivariate group-level covariance syntax is explicit about
the distinction between group-level covariance labels and residual
rho12:
drm_formula(
mu1 = y1 ~ x1 + x2 + (1 | p | ID),
mu2 = y2 ~ x1 + (1 | p | ID),
sigma1 = ~ x1 + x2 + (1 | q | ID),
sigma2 = ~ x1 + (1 | q | ID),
rho12 = ~ x1 + x2
)The shared p label fits a group-level random-intercept
covariance block for the two response means. The shared q
label fits a separate scale-scale block for the two residual-scale
random intercepts on the log-sigma scale. The same-response
mean-scale bridge is also implemented for one or both responses: a
shared label in mu1 and sigma1 gives a
response-1 mean-scale row, while a different shared label in
mu2 and sigma2 gives a separate response-2
mean-scale row. Reusing the same label and group in all four bivariate
formulas fits the first ordinary q=4 location-scale block:
drm_formula(
mu1 = y1 ~ x + (1 | p | ID),
mu2 = y2 ~ x + (1 | p | ID),
sigma1 = ~ z + (1 | p | ID),
sigma2 = ~ z + (1 | p | ID),
rho12 = ~ w
)That q=4 block reports one location-location row, four location-scale
rows, and one scale-scale row in corpairs(). Fitted rows
still use the older mean-mean and mean-scale
class names, but corpairs() accepts
location-location and location-scale as filter
aliases to match the reserved corpair() formula wording.
The first fitted corpair() route is the ordinary q=2
location-location model:
corpair(ID, level = "group", block = "p", from = "mu1", to = "mu2") ~ w.
The predictor w must be constant within ID,
and corpairs() reports the mean, range, and number of
fitted group-level correlations. Later location-scale routes should also
be endpoint-specific, for example
corpair(ID, level = "group", block = "p", from = "mu1", to = "sigma2") ~ w,
because the four location-scale pairs in q=4 models do not have
identical interpretation. For phylogenetic life-history trade-off
models, the same grammar now also covers the fitted q=2
location-location route:
corpair(species, level = "phylogenetic", block = "p", from = "mu1", to = "mu2") ~ ecology.
The phylogenetic formula has an extra design gate: because the tree
couples all species, drmTMB needs a positive-definite
covariance contract for the full species block before a species-level
predictor can change the latent phylogenetic correlation. The selected
q=2 contract uses two independent unit phylogenetic fields and
species-specific loadings, so variable rho_l is a
nonstationary phylogenetic covariance model rather than a residual-style
correlation row. It covers mu1-mu2 only;
phylogenetic location-scale and scale-scale correlation regressions
remain q=4 extensions. Multiple-slope bivariate location blocks beyond
the smoke-routed ordinary q4/q6 lanes, bivariate spatial slope blocks,
predictor-dependent q=4 phylogenetic or spatial correlations, p8
endpoint slope covariance, q8 variants beyond the first ordinary
diagnostic lane, and rho12 random effects remain planned.
Double-hierarchical bivariate fits should continue to report correlation
pairs in a long table, not just as unlabeled matrices. The design note
docs/design/20-coscale-correlation-pairs.md records the
planned labels: correlation level, group, covariance block,
distributional parameters, responses, and random-effect coefficients.
The current corpairs(fit) helper already uses this table
shape for residual rho12, ordinary univariate Gaussian
mu random-effect correlations, and the implemented
bivariate mean-mean, scale-scale, response-specific mean-scale, ordinary
q=4, and phylogenetic mean-mean and q=4 random-intercept
correlations.