Priors and Boundaries
For the workflow guidance behind these controls, start with Stage 2: Model and Priors. This page is the technical contract for dsambayesplus prior and boundary behaviour.
Use this page when you need exact dsambayesplus semantics: supported prior families, override syntax, default generation rules, and scaling behaviour. Do not use it as the main argument for why a prior is reasonable. That reasoning belongs in the workflow pages and in your modelling rationale.
Purpose
This page defines how dsambayesplus specifies, defaults, overrides, and scales coefficient priors and parameter boundaries for all model classes. It covers the prior schema, supported families, default-generation logic, YAML override contract, and the interaction between priors, boundaries, and the scale=TRUE pathway.
How to read this page
- Use Minimal-Prior Policy if you want the short recommended operating rule.
- Use this page when you need to know exactly how dsambayesplus will interpret a prior or boundary specification.
- Return to Stage 2: Model and Priors if the question is whether a custom prior should be added at all.
Prior schema
Each model object carries a .prior tibble with one row per parameter. The columns are:
| Column | Type | Meaning |
|---|---|---|
parameter |
character | Parameter name (matches design-matrix column or special name) |
description |
character | Human-readable label |
distribution |
call | R distribution call, e.g. normal(0, 5) |
is_default |
logical | Whether the row was generated by default_prior() |
Supported prior families
| Family | Stan encoding | Use case |
|---|---|---|
normal(mean, sd) |
Default (prior_family_noise_sd = 0) |
Coefficient priors (location–scale) |
lognormal_ms(mean, sd) |
Encoded with log-transformed parameters | Positive noise_sd and hierarchical sd_<idx>[<term>] priors |
All coefficient priors use normal(). The lognormal_ms family is parameterised by the mean and standard deviation on the original (non-log) scale; dsambayesplus converts these internally to log-space parameters.
Default prior generation
BLM and hierarchical (population terms)
default_prior.blm() calls standard_prior_terms(). On the reporting scale,
the intercept prior is normal(ybar, sy), each slope prior is
normal(0, sy / sx), and the residual-SD prior is normal(0, sy), where
sy and sx are the response and term standard deviations. These defaults
therefore map to unit-scale priors after internal standardisation and respond
coherently when measurement units change.
Hierarchical (group-level standard deviations)
default_prior.hierarchical() additionally generates sd_<idx>[<term>] rows
for each group factor. Each constrained group SD receives a zero-centred normal
prior whose scale matches the corresponding coefficient scale: sy for a
group intercept and sy / sx for a random slope. Because the SD parameter is
constrained positive in Stan, this acts as a half-normal prior. It remains
positive when observed group outcome means happen to be equal, and random-slope
defaults change coherently when predictor measurement units change.
Specify hierarchical standard-deviation priors in reporting-scale units. With
scale = TRUE, dsambayesplus transforms them to the Stan scale: intercept
heterogeneity is divided by the response standard deviation, while slope
heterogeneity is multiplied by the predictor-to-response standard-deviation
ratio. The group intercept is defined at the internally centred predictor
reference point. It is not a group intercept at raw predictor values of zero.
With the defaults above, these transformations produce unit-scale group-SD
priors in Stan space. Explicit user overrides retain their supplied
reporting-scale meaning and are transformed by the same rules.
Default population and group-SD scales use the same population-model complete-case frame. This keeps the reporting-to-Stan transformation exact when a population term contains missing values. Random-slope terms must be numeric. Group-only random-slope terms are evaluated on the retained population rows. dsambayesplus aborts rather than deriving a group-SD default when a group term would drop additional rows or when a factor random slope is unsupported.
BLM from lm (Bayesian updating)
default_prior.bayes_lm_updater() initialises coefficient priors from the OLS point estimates (mean) and standard errors (sd), enabling informative Bayesian updating.
Pooled
default_prior.pooled() uses the BLM defaults for non-pooled terms (intercept, base regressors, noise_sd) and normal(0, 5) for each dimension-level pooled coefficient. Default pooled boundaries remain unconstrained; add explicit boundaries if a pooled dimension should be sign-restricted.
Boundary schema
Each model object carries a .boundaries tibble with one row per parameter:
| Column | Type | Meaning |
|---|---|---|
parameter |
character | Parameter name |
description |
character | Human-readable label |
boundary |
list-column | List with $lower and $upper (numeric scalars) |
is_default |
logical | Whether the row was generated by default_boundary() |
Default boundaries are lower = -Inf, upper = Inf for all terms. No sign constraints are imposed by default.
YAML override contract
Prior overrides
Each override replaces the distribution call for the named parameter with normal(mean, sd). Overrides are sparse: only the listed parameters are changed; all other parameters keep their defaults.
In M1, use_defaults must remain true. The v2 runner is default-first: it always starts from the generated prior table, then applies sparse grouped aliases and explicit overrides.
The friendly YAML surface also accepts an explicit alias style:
or:
HalfNormal is implemented by compiling to normal(0, sigma) plus an implied lower bound of 0 on targeted parameters that are otherwise unconstrained. The priors.likelihood.sigma alias compiles to the dsambayesplus noise_sd prior family.
Boundary overrides
Each override replaces the boundary entry for the named parameter. YAML infinity tokens (.Inf, -.Inf) are coerced during config resolution.
Scale semantics (scale = TRUE)
When model.scale: true (the default), the response and predictors are standardised before Stan fitting. Centring applies only to population formulae with an intercept. Through-origin formulae divide by the same standard deviations without centring. This affects both priors and boundaries.
Coefficient prior scaling
For BLM and hierarchical population terms, the fitted intercept refers to centred predictors on the standardised model-response scale. The reported population intercept is back-transformed to original predictor zero. For a log-response model, the unstandardised model response is log-KPI, not KPI.
Let cy and sy be the centre and SD of the model response, and cx[j] and
sx[j] the corresponding predictor quantities. For authored normal locations
m_alpha, m_beta[j] and prior SDs sd_alpha, sd_beta[j], scale_.prior()
implements:
These locations are the parameters of normal kernels; with finite bounds they
are not generally the means of the truncated distributions. Stan assigns
independent normal priors to the population coefficients, restricted by their
bounds. For noise_sd, the normal location and SD, or the lognormal_ms
mean and SD, are divided by sy.
The reported coefficients use the inverse map:
The current conversion does not generally preserve an independently authored
raw-intercept prior jointly with the slopes. The inverse intercept depends
on the slope draws, but prior scaling divides its SD only by sy and introduces
no intercept-slope covariance. For example, normal(10, 2) for the intercept
and normal(3, 4) for one slope, with cy=10, sy=2, cx=5, sx=1, give
independent internal priors normal(7.5, 1) and normal(1.5, 2). Without bounds,
the reported intercept then has variance 404 rather than the authored 4, and
covariance -80 with the reported slope. This is an algebraic consequence of the
implementation, not a fitted result.
See R/scale.R (scale_.prior() and unscale_coef_vector()), the preparation
paths in R/blm.R and R/hierarchy.R, and the Stan population-prior blocks.
Boundary scaling
- Zero slope boundaries (
0) are preserved by positive multiplicative scaling. - Infinite boundaries (
±Inf) are invariant under scaling. - Finite non-zero boundaries for slope terms are scaled using
scale_boundary_for_parameter(), which applies the samesx / syratio used for slope priors. - Population-intercept boundaries in BLM and hierarchical models: with
scale = TRUE, finite non-zero bounds are rejected. Zero and infinite bounds pass through unchanged. A zero lower bound constrains the internal centred intercept, not necessarily the reported raw-zero intercept. In the example above,alpha_stan=0.1andbeta_stan=2satisfy that internal bound but back-transform toalpha=-9.8. - If a finite non-zero boundary is specified for a parameter without a matching scale factor in the design matrix, dsambayesplus aborts with a validation error.
Practical implication
State the model-response units, scaling flag and intercept reference explicitly.
Unstandardised coefficient reporting does not imply that centring preserved the
authored joint prior or an intercept bound at raw predictor zero. With
scale = FALSE, BLM and hierarchical population priors and bounds are passed to
the unstandardised fit without these conversions. Through-origin models have
no population intercept and retain zero centres when scaling.
Hierarchical group-intercept SDs have the separate centred-reference convention described above. Do not apply the population-intercept interpretation to group heterogeneity or generalise these boundary rules to pooled dimension terms.
Interaction with model classes
| Behaviour | BLM | Hierarchical | Pooled |
|---|---|---|---|
| Default priors | Data-dependent: normal(ybar, sy) intercept, normal(0, sy / sx) slopes, normal(0, sy) noise_sd (see Default prior generation above) |
Population: same as BLM; group SD: data-derived | Non-pooled: BLM defaults; pooled dimension coefficients only: normal(0, 5) per dimension |
| Boundary defaults | (-Inf, Inf) per term |
Same as BLM for population terms | Per-dimension boundaries for pooled terms |
| Prior scaling | Slope ratio sx / sy; population-intercept conversion and limitation above |
Same population conversion, computed on pooled model frame; group-SD rules above | Shared prior helper; dimension-level terms have a separate parameterisation |
| Boundary scaling | Slope ratio sx / sy; population-intercept exceptions above |
Same for population terms | Per-dimension boundary handling; do not infer population-intercept support |
Programmatic API
Inspect priors and boundaries
Override priors
Override boundaries
Minimal-prior policy
The recommended operating profile for MMM is documented in Minimal-Prior Policy. The policy keeps priors weak by default and uses hard constraints only when there is structural business knowledge.
Cross-references
- Model Classes, constructor and fit support per class
- Minimal-Prior Policy, governance guidance for prior specification
- Response Scale Semantics, link vs KPI scale behaviour
- Config Schema, YAML prior and boundary keys