| glmbayes_bayestestR_prior_methods | R Documentation |
Methods implementing three of bayestestR's prior-related generics for
objects of class "glmb" (which includes lmb,
rglmb, rlmb, and rGamma_reg fits,
since these all inherit "glmb" in their class vector).
simulate_prior.glmb() delegates to the pfun stored in
x$pfamily (see pfamily and prior_simfuncs),
drawing n independent samples directly from the actual prior
specification in prior_list, rather than reconstructing an approximation
glmbayes_insight_methods's get_priors.glmb() flattened
Parameter/Distribution/Location/Scale table.
This matters when the coefficient prior is a genuine multivariate
normal (dNormal, dNormal_Gamma,
dIndependent_Normal_Gamma) with a non-diagonal covariance
matrix Sigma: the flattened table can only report each parameter's
marginal mean/SD, but simulate_prior.glmb() draws from the true
joint N(\mu, \Sigma) (via a Cholesky factor of the complete
Sigma), preserving any correlation between coefficients.
dBeta/dGamma priors are drawn from their exact
Beta/Gamma form rather than their Normal-moment surrogate. dGamma
with Inv_Dispersion = TRUE is a special case: that prior is on the
inverse dispersion (precision) only – beta is a fixed,
known input, not a modeled quantity – so simulate_prior.glmb()
returns only simulated dispersion draws for it, with no
coefficient columns at all (mirroring
glmbayes_insight_methods's get_parameters.glmb()
treatment of the posterior side).
dNormal_Gamma and dIndependent_Normal_Gamma
both place priors on both the coefficients (joint normal) and the
dispersion (inverse-gamma), and simulate_prior.glmb() simulates
both parts for either. For dIndependent_Normal_Gamma,
however, the dispersion prior is two-sided truncated to
x$pfamily$prior_list$disp_lower/disp_upper – bounds that
rindepNormalGamma_reg (and rglmb/
rlmb/glmb/lmb, which call it)
always compute and write back into the fitted object's pfamily
even when the user leaves disp_lower/disp_upper at their
default NULL at prior-specification time, because the
accept-reject envelope requires a bounded dispersion domain to construct
(lack of conjugacy between the independent coefficient and precision
priors rules out the closed-form, unbounded posterior available to
dNormal_Gamma). simulate_prior.glmb() draws from
this same truncated Inverse-Gamma via the exact inverse-CDF method
‘src/invgamma_ct.cpp’ uses internally, so it matches what the fit
actually assumed rather than the untruncated Inverse-Gamma(shape,
rate). dNormal_Gamma's dispersion prior has no
truncation concept at all (its prior_list has no
disp_lower/disp_upper fields; it is fully conjugate), and
dGamma's truncation is opt-in only (via explicit
disp_lower/disp_upper arguments at construction; the
default NULL is never overwritten after fitting) – both are
handled by the same helper, which falls back to the plain untruncated
Inverse-Gamma whenever disp_lower/disp_upper are NULL.
check_prior.glmb() compares those prior draws against the fit's
posterior draws (get_parameters), one parameter at a
time, using the same "gelman" (posterior SD vs. prior SD ratio) and
"lakeland" (fraction of posterior mass inside the prior's 95\
rules bayestestR uses for other model classes – reimplemented
locally so glmbayes does not depend on bayestestR's unexported
internal helpers. Because both rules only ever compare one parameter's
prior draws to that same parameter's posterior draws, the joint/marginal
distinction above never changes check_prior()'s verdicts; it only
matters if you use simulate_prior()'s draws directly (e.g. for
prior-predictive visualization).
describe_prior.glmb() does not route through
get_priors()'s flattened, marginal-only table (unlike
bayestestR's own describe_prior.stanreg(), which is a thin
wrapper around get_priors). Instead it returns
pfamily(model) directly, so it prints the exact same
Call / Prior Family / Prior List report as
pfamily(model) (via the package's existing
print.pfamily() method) – including the complete covariance
matrix for a multivariate normal coefficient prior, not just its
diagonal.
## S3 method for class 'glmb'
simulate_prior(model, n = 1000, ...)
## S3 method for class 'glmb'
check_prior(model, method = "gelman", simulate_priors = TRUE, ...)
## S3 method for class 'glmb'
describe_prior(model, parameters = NULL, ...)
model |
An object of class |
n |
Number of prior draws to simulate. |
... |
Not used; included for S3 signature compatibility with the bayestestR generics. |
method |
Either |
simulate_priors |
Ignored (prior draws are always simulated via
|
parameters |
Not used; included for signature compatibility with
|
simulate_prior.glmb() returns a data.frame with
n rows and one column per parameter (matching
get_parameters's shape).
check_prior.glmb() returns a data.frame with columns
Parameter and Prior_Quality.
describe_prior.glmb() returns the fit's "pfamily" object
(see pfamily).
glmbayes_insight_methods, pfamily,
prior_simfuncs; simulate_prior,
check_prior, describe_prior.
## bayestestR prior-checking methods for glmb/lmb fits (simulate_prior,
## check_prior, describe_prior). 'bayestestR' is a hard dependency (Imports)
## and these generics are re-exported by glmbayes, so no separate
## library(bayestestR) call is needed.
## ----setup: mtcars, a multivariate normal coefficient prior with real data----
## wt and cyl are strongly correlated in mtcars (heavier cars tend to have
## more cylinders), so Prior_Setup()'s data-driven Sigma -- based on
## (X'WX)^-1 -- has a substantial off-diagonal entry between c_wt and c_cyl:
## simulate_prior() draws from this exact joint N(mu, Sigma), not just the
## per-parameter marginals insight's usual get_priors() shape would report
## for other model classes.
##
## sd = c(10, 10, 0.5) gives the intercept and c_wt a deliberately vague
## prior (SD = 10) but c_cyl a tight, informative one (SD = 0.5) centered at
## 0 -- in tension with c_cyl's actual (negative) effect on mpg -- so
## check_prior() below reports a genuine mix of "informative"/"uninformative"
## (gelman) and "informative"/"misinformative" (lakeland) verdicts, rather
## than the same verdict for every coefficient. (A per-coefficient `pwt`
## vector, unlike `sd`, does not survive Prior_Setup()'s Gaussian
## dispersion-calibration step, which recomputes Sigma from (X'WX)^-1 times
## a single scalar dispersion; `sd` is passed straight through instead.)
data(mtcars)
mt <- mtcars
mt$c_wt <- as.numeric(scale(mtcars$wt, center = TRUE, scale = FALSE))
mt$c_cyl <- as.numeric(scale(mtcars$cyl, center = TRUE, scale = FALSE))
form <- mpg ~ c_wt + c_cyl
ps <- Prior_Setup(form, gaussian(), data = mt, sd = c(10, 10, 0.5), n_prior = 3)
fit <- lmb(
form,
dNormal(mu = ps$mu, Sigma = ps$Sigma, dispersion = ps$dispersion),
data = mt, n = 2000L, verbose = FALSE, use_parallel = FALSE
)
## ----simulate_prior-----------------------------------------------------------
prior_draws <- simulate_prior(fit, n = 5000)
dim(prior_draws) ## 5000 draws x 3 coefficients
cor(prior_draws$c_wt, prior_draws$c_cyl) ## recovers Sigma's off-diagonal correlation
## ----check_prior---------------------------------------------------------------
check_prior(fit) ## "gelman" rule (posterior SD vs. prior SD)
check_prior(fit, method = "lakeland") ## posterior mass inside the prior's 95% HDI
## ----describe_prior-------------------------------------------------------------
## describe_prior() and get_priors() both return pfamily(fit) directly -- the
## same full report (including the complete Sigma, not just its diagonal)
## shown by pfamily(fit) itself.
describe_prior(fit)
identical(describe_prior(fit), pfamily(fit)) ## TRUE
identical(get_priors(fit), pfamily(fit)) ## TRUE
## ----dIndependent_Normal_Gamma: priors on *both* coefficients and dispersion---
## dNormal_Gamma() and dIndependent_Normal_Gamma() both place a prior on the
## coefficients (joint normal) *and* a separate inverse-gamma prior on the
## dispersion, so simulate_prior() below returns both a coefficient block and
## a dispersion column. Unlike dNormal_Gamma() (fully conjugate, no
## truncation), dIndependent_Normal_Gamma()'s independent coefficient/
## precision priors are not jointly conjugate, so its accept-reject sampler
## needs a *bounded* dispersion domain -- the dispersion prior is therefore
## two-sided truncated to [disp_lower, disp_upper] (derived from
## max_disp_perc; here left at its default). simulate_prior() draws from this
## exact *truncated* Inverse-Gamma, not the wider untruncated one.
ps_ing <- Prior_Setup(form, gaussian(), data = mt, n_prior = 5)
fit_ing <- lmb(
form,
dIndependent_Normal_Gamma(mu = ps_ing$mu, Sigma = ps_ing$Sigma,
shape = ps_ing$shape_ING, rate = ps_ing$rate),
data = mt, n = 2000L, verbose = FALSE, use_parallel = FALSE
)
## The fit writes the envelope's actual bounds back into pfamily(fit_ing),
## even though disp_lower/disp_upper were left at their default NULL above.
fit_ing$pfamily$prior_list[c("disp_lower", "disp_upper")]
prior_draws_ing <- simulate_prior(fit_ing, n = 5000)
colnames(prior_draws_ing) ## coefficients *and* dispersion
range(prior_draws_ing$dispersion) ## stays within [disp_lower, disp_upper]
check_prior(fit_ing) ## "dispersion" is checked alongside the coefficients
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.