This document is the canonical checklist for extending glmbayes with a new
conjugate or semi-conjugate prior family (pfamily) and its associated
simulation function. Follow every step in order; each step depends on the
previous one being correct.
Every pfamily object is a list with exactly these named slots:
| Slot | Type | Role |
|---|---|---|
| pfamily | character | Name tag (e.g. "dBeta") |
| prior_list | list | All prior hyperparameters, plus mu, Sigma surrogates |
| okfamilies | character vector | GLM family names this prior supports |
| plinks | function(family) | Returns allowed link names for a given family; NULL if unsupported |
| simfun | function | Low-level sampler; called by rglmb() dispatch |
| call | call | Matched call from the constructor |
Before writing any code:
p(y | θ) for the new family/link.p(θ).p(θ | y) ∝ p(y | θ) p(θ).| Likelihood | Link | Prior on | Fixed | Update |
|---|---|---|---|---|
| Poisson | identity | rate λ | — | Gamma(α + Σy, β + n) |
| Gamma | identity | rate β | shape k (lik_shape) | Gamma(α + nk, β + Σy) |
| Binomial | identity | prob θ | — | Beta(α + Σ successes, β + Σ failures) |
| Gaussian | identity | precision τ | mean μ | Gamma(α + n/2, β + RSS/2) |
R/pfamily.R: write the constructorAdd a new exported function at the bottom of pfamily.R.
Required elements:
- Validate all hyperparameter inputs (type, length, positivity/range).
- Build the Normal-style surrogate mu and Sigma matrices from the prior
moments (used by glmb() pre-simulation and summary() reporting).
- Set okfamilies (character vector of supported family names).
- Define plinks(family) closure that returns allowed links per family.
- Set simfun to the new simulation function (written in Step 3).
- Build prior_list storing all hyperparameters plus mu and Sigma.
- Set attr(prior_list, "Prior Type") and attr(outlist, "Prior Type").
- Set class(outlist) <- "pfamily" and outlist$call <- match.call().
Roxygen tags needed:
#' @export
#' @rdname pfamily
#' @order N # next available integer
All @param entries must be documented — R CMD check will flag any
undocumented argument.
R/simfunction.R: write rXxx_reg()Model the new function on rGamma_Conjugate_reg(). Key structural requirements:
rXxx_reg <- function(n, y, x, prior_list, offset = NULL,
weights = 1, family = gaussian(),
Gridtype = 2, n_envopt = NULL,
use_parallel = TRUE, use_opencl = FALSE,
verbose = FALSE, progbar = FALSE)
rGamma_Conjugate_reg)call <- match.call()weights → wt, offset → alphay, x, wt, alphaprior_listokfamilies <- c(...)
# Check family$family %in% okfamilies and family$link %in% oklinks
Call .check_gamma_conjugate_scalar_design() or add an inline guard if
the error messages specific to your prior name matter. The guard enforces:
- ncol(x) == 1L (intercept-only)
- prior_list$beta is 1×1
- All offsets are zero
- Weights are constant (unless the conjugate update handles heterogeneous
weights explicitly — verify this from the math)
Enforce any response constraints (e.g. y ∈ [0,1] for binomial, y > 0 for Gamma/exponential).
# Compute posterior hyperparameters
# ...
# Draw n_draw IID samples
coef_out <- matrix(rXxx(n_draw, ...), nrow = n_draw, ncol = 1L)
disp_out <- rep(dispersion_value, n_draw)
draws_out <- matrix(1L, nrow = n_draw, ncol = 1L) # each draw accepted in 1 step
Provide an analytic posterior mode where it exists; fall back to the posterior mean otherwise.
rGamma_Conjugate_reg structure exactly)outlist <- list(
coefficients = coef_out,
coef.mode = coef_mode_out,
dispersion = disp_out,
Prior = list(mean = ..., Precision = ..., ...),
prior.weights = wt,
y = y,
x = x,
famfunc = glmbfamfunc(family), # requires Step 4
iters = draws_out,
Envelope = NULL
)
# then append: family, offset2, formula, model, data, call
class(outlist) <- c(outlist$class, "rglmb", "glmb", "glm", "lm")
#' @family simfuncs
R/simulationpipeline.R: add a glmbfamfunc branchglmbfamfunc must have a branch for every family/link that a simulation
function uses — without it, DIC, logLik(), and directional_tail() will
fail with "object 'f1' not found".
Add the new branch just before out = list(f1=f1, ...) at the bottom of the
function. Each branch must define all five closures:
| Closure | Role | Signature |
|---|---|---|
| f1 | Negative log-likelihood | f1(b, y, x, alpha=0, wt=1) |
| f2 | Negative log-posterior | f2(b, y, x, mu, P, alpha=0, wt=1) |
| f3 | Gradient of f2 w.r.t. b | f3(b, y, x, mu, P, alpha=0, wt=1) |
| f4 | Deviance (2 × NLL contrast vs saturated) | f4(b, y, x, alpha=0, wt=1, dispersion=1) |
| f7 | Fisher information matrix | f7(b, y, x, mu, P, alpha=0, wt=1) |
Common derivations:
- f3 = −∂L/∂b + P(b−μ) where ∂L/∂b = X' diag(wt) ∂ℓ/∂η
- f7 = X' diag(wt × w_i) X where w_i = (∂μ/∂η)² / V(μ_i) (GLM weight)
- f4 = 2 × f1(b,y,x,α,wt/φ) + 2 × Σ log p(y_i | ŷ_i=y_i) (saturated NLL)
If glmbfamfunc needs an extra parameter (e.g. lik_shape), add it as an
optional argument with a sensible default.
Update the documentation table in the roxygen header listing all implemented family/link combinations.
R/prior.R: add conj_Xxx to Prior_Setup()If the new prior supports calibration via Prior_Setup():
conj_Xxx <- NULL initialization near the Poisson block.ncol(x) == 1L, scalar pwt).n_prior = (pwt / (1 - pwt)) * n_effn_prior and the data summary statistic.conj_Xxx <- list(...) with at minimum beta, plus the
hyperparameters needed by the pfamily constructor.conj_Xxx in the returned prior_list.conj_Xxx branch to print.PriorSetup() (search for the
conj_poisson print block to find the right location).@return roxygen docs for Prior_Setup to document
conj_Xxx.devtools::document() after writing all roxygen blocks.spelling::spell_check_package() and add any new legitimate words to
inst/WORDLIST.R CMD check produces no warnings about undocumented arguments.tests/testthat/)Add at least one test file covering:
summary() runs without error.logLik() and DIC_Info() run without error (validates glmbfamfunc).Prior_Setup() produces non-NULL conj_Xxx under the right conditions.inst/examples/Ex_dXxx.R (for @example in
roxygen).Chapter-02-S03.Rmd for Beta–Binomial, Chapter-02-S05.Rmd for Gamma–Gamma)
following the pattern of the existing conjugate sections.When you name a new prior dXxx, search for every occurrence of
dBeta or dGamma(Inv_Dispersion=FALSE) (or the nearest analogue) in the files below and create
the corresponding dXxx entry:
| File | What to add |
|---|---|
| R/pfamily.R | Constructor dXxx() |
| R/simfunction.R | Simulation function rXxx_reg() |
| R/simulationpipeline.R | glmbfamfunc branch + doc table row |
| R/prior.R | conj_Xxx block in Prior_Setup() + print method |
| inst/WORDLIST | Any new technical terms flagged by spell check |
| tests/testthat/ | test-dXxx.R |
| inst/examples/ | Ex_dXxx.R |
| vignettes/Chapter-02-S*.Rmd | New section in matching conjugate vignette |
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.