| Title: | Bayesian Linear Mixed-Effects Models via Two-Block Gibbs Sampling |
|---|---|
| Description: | Provides Bayesian linear and generalized linear mixed-effects model fitting with near-independent posterior samples. The main functions mirror lme4's lmer() and glmer() interfaces (X/beta for fixed effects, Z/b for random effects, D for the random-effects covariance) while adding prior family specifications for Gaussian, Poisson, binomial, and Gamma models with log-concave likelihoods. Sampling uses efficient two-block Gibbs sampling procedures with parallel chains and theoretically driven stopping rules. Gibbs sampling engines are provided by the 'glmbayesCore' package. |
| Authors: | Kjell Nygren [aut, cre], The R Core Team [ctb, cph] (R Mathlib sources, R stats modeling code, and derived/adapted routines), The R Foundation [cph] (Portions of R Mathlib and R source code), Ross Ihaka [ctb, cph] (R Mathlib and original R modeling infrastructure), Robert Gentleman [ctb, cph] (Portions of R Mathlib), Simon Davies [ctb] (Original R glm implementation), Morten Welinder [ctb, cph] (Portions of R Mathlib), Martin Maechler [ctb] (Portions of R Mathlib) |
| Maintainer: | Kjell Nygren <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 0.1.0 |
| Built: | 2026-06-21 21:34:06 UTC |
| Source: | https://github.com/knygren/lmebayes |
Two-block Gibbs samplers for Bayesian linear and generalized linear mixed-effects models, following lme4 notation. Builds on glmbayes for iid GLM sampling within blocks.
Row-block interfaces include lmbBlock and glmbBlock;
mixed-model setup from lme4 formulas via model_setup.
Lower-level simulation uses simfunction and envelope
utilities from glmbayesCore.
See the package README at https://github.com/knygren/lmebayes for examples.
In interactive sessions, attaching the package with library(lmebayes)
may emit a short packageStartupMessage
when has_opencl() is FALSE (typical for CRAN binaries) but a
GPU or OpenCL stack appears available on the host. OpenCL modelling paths
require a source install with OpenCL at compile time;
has_opencl() then reports whether that build succeeded.
Set options(glmbayes.quiet_opencl_startup = TRUE) to suppress attach
notes (recommended for CI and R CMD check).
Kjell Nygren
There are no references for Rd macro \insertAllCites on this help page.
lmerb, model_setup, lmbBlock, glmbBlock;
simfunction, EnvelopeBuild;
lmb and glmb for fixed-effects-only Bayesian
linear and generalized linear models;
rlmb and rglmb for iid
posterior draws.
Useful links:
set.seed(333) ## Dobson (1990) Page 93: Randomized Controlled Trial : counts <- c(18, 17, 15, 20, 10, 20, 25, 13, 12) outcome <- gl(3, 1, 9) treatment <- gl(3, 3) print(d.AD <- data.frame(treatment, outcome, counts)) glm.D93 <- glm(counts ~ outcome + treatment, family = poisson()) ps <- glmbayesCore::Prior_Setup(counts ~ outcome + treatment, family = poisson()) rglmb.D93 <- glmbayesCore::rglmb( n = 200, y = ps$y, x = as.matrix(ps$x), pfamily = glmbayesCore::dNormal(mu = ps$mu, Sigma = ps$Sigma), family = poisson(), weights = rep(1, nrow(ps$x)) ) print(rglmb.D93) summary(rglmb.D93)set.seed(333) ## Dobson (1990) Page 93: Randomized Controlled Trial : counts <- c(18, 17, 15, 20, 10, 20, 25, 13, 12) outcome <- gl(3, 1, 9) treatment <- gl(3, 3) print(d.AD <- data.frame(treatment, outcome, counts)) glm.D93 <- glm(counts ~ outcome + treatment, family = poisson()) ps <- glmbayesCore::Prior_Setup(counts ~ outcome + treatment, family = poisson()) rglmb.D93 <- glmbayesCore::rglmb( n = 200, y = ps$y, x = as.matrix(ps$x), pfamily = glmbayesCore::dNormal(mu = ps$mu, Sigma = ps$Sigma), family = poisson(), weights = rep(1, nrow(ps$x)) ) print(rglmb.D93) summary(rglmb.D93)
Data with information on 17 overdoses of the drug amitriptyline
data(AMI)data(AMI)
This data frame contains the following columns:
TOTtotal TCAD plasma level
AMIamount of amitriptyline present in the TCAD plasma level
GENgender (male = 0, female = 1)
AMTamount of drug taken at time of overdose
PRPR wave measurement
DIAPdiastolic blood pressure
QRSQRS wave measurement
Each row is one overdose episode. Variables include total tricyclic antidepressant level, amitriptyline component, gender, reported amount ingested, and ECG-related measures (PR interval, QRS duration, diastolic blood pressure). The dataset is used in package examples for binomial and related regression; see (Dobson 1990) for analogous generalized linear modelling of clinical outcomes.
Dobson A~J (1990). An Introduction to Generalized Linear Models. Chapman and Hall, London.
############################### Start of AMI dataset example #################### data(AMI) summary(AMI) ############################################################################### ## End of AMI dataset example ############################################################################################################## Start of AMI dataset example #################### data(AMI) summary(AMI) ############################################################################### ## End of AMI dataset example ###############################################################################
A processed version of the UCI Bike Sharing Dataset (hourly data). The data include derived variables for part of day, quarter, and Fourier terms for cyclic effects of hour and month.
BikeSharingBikeSharing
A data frame with 17,379 observations and 25 variables (original plus derived):
Record index.
Date.
Season (1: spring, 2: summer, 3: fall, 4: winter).
Year (0: 2011, 1: 2012).
Month (1–12).
Hour (0–23).
Whether the day is a holiday (0/1).
Day of week (0–6).
Working day (0/1).
Weather situation (1–4).
Normalized temperature.
Normalized feeling temperature.
Normalized humidity.
Normalized wind speed.
Count of casual users.
Count of registered users.
Total count (casual + registered).
Hour as numeric (same as hr).
Month as integer.
Factor: Night (0–5h), Morning (6–11h), Afternoon (12–17h), Evening (18–23h).
Factor: Q1–Q4.
Sine term for 24-hour cycle.
Cosine term for 24-hour cycle.
Sine term for 12-month cycle.
Cosine term for 12-month cycle.
UCI Machine Learning Repository: Bike Sharing Dataset. https://archive.ics.uci.edu/dataset/275/bike+sharing+dataset
############################### Start of BikeSharing dataset example #################### data("BikeSharing") head(BikeSharing) dim(BikeSharing) ############################################################################### ## End of BikeSharing dataset example ############################################################################################################## Start of BikeSharing dataset example #################### data("BikeSharing") head(BikeSharing) dim(BikeSharing) ############################################################################### ## End of BikeSharing dataset example ###############################################################################
A copy of Boston where all predictors (every column except
medv) have been mean-centered (subtract column means, no scaling).
data("Boston_centered")data("Boston_centered")
A data frame with 506 observations and 14 variables (same names as
Boston). See ?MASS::Boston for variable
descriptions.
Derived from MASS::Boston. Original data described in Harrison
and Rubinfeld (1978); see ?Boston in MASS.
############################### Boston_centered dataset example #################### data("Boston_centered") head(Boston_centered) summary(Boston_centered) ## Predictors are mean-centered (column means ~0) predictors <- setdiff(names(Boston_centered), "medv") colMeans(Boston_centered[predictors]) form <- medv ~ crim + zn + indus + chas + nox + age + dis + rad + tax + ptratio + black + lstat + rm lm.boston <- lm(form, data = Boston_centered, x = TRUE, y = TRUE) summary(lm.boston) ############################################################################### ## End of Boston_centered dataset example ############################################################################################################## Boston_centered dataset example #################### data("Boston_centered") head(Boston_centered) summary(Boston_centered) ## Predictors are mean-centered (column means ~0) predictors <- setdiff(names(Boston_centered), "medv") colMeans(Boston_centered[predictors]) form <- medv ~ crim + zn + indus + chas + nox + age + dis + rad + tax + ptratio + black + lstat + rm lm.boston <- lm(form, data = Boston_centered, x = TRUE, y = TRUE) summary(lm.boston) ############################################################################### ## End of Boston_centered dataset example ###############################################################################
The data give the Canadian automobile insurance experience for policy years 1956 and 1957 as of June 30, 1959. The data includes virtually every insurance company operating in Canada and was collated by the Statistical Agency (Canadian Underwriters' Association - Statistical Department) acting under instructions from the Superintendent of Insurance. The data given here is for private passenger automobile liability for non-farmers for all of Canada excluding Saskatchewan.
data(carinsca)data(carinsca)
A data frame with 20 observations on the following 6 variables:
MeritMerit Rating:
3 - licensed and accident free 3 or more years
2 - licensed and accident free 2 years
1 - licensed and accident free 1 year
0 - all others
Class1 - pleasure, no male operator under 25
2 - pleasure, non-principal male operator under 25
3 - business use
4 - unmarried owner or principal operator under 25
5 - married owner or principal operator under 25
InsuredEarned car years
PremiumEarned premium in 1000's
(adjusted to what the premium would have been had all cars been written at 01 rates)
ClaimsNumber of claims
CostTotal cost of the claim in 1000's of dollars
One could apply Poisson regression to the number of claims and gamma regression to the cost per claim.
Bailey, R. A., and Simon, LeRoy J. (1960). Two studies in automobile insurance ratemaking. ASTIN Bulletin, 192-217.
Data downloaded from http://www.statsci.org/data/general/carinsca.html. That site also contains classical Poisson and Gamma regression examples.
############################### Start of carinsca dataset example #################### data(carinsca) str(carinsca) head(carinsca) ############################################################################### ## End of carinsca dataset example ############################################################################################################## Start of carinsca dataset example #################### data(carinsca) str(carinsca) head(carinsca) ############################################################################### ## End of carinsca dataset example ###############################################################################
A cleaned version of the Cleveland heart disease dataset from the UCI Machine
Learning Repository. This version contains only complete cases and includes a
derived binary outcome variable hd indicating the presence ("Yes")
or absence ("No") of heart disease.
data("Cleveland")data("Cleveland")
A data frame with 297 observations and 15 variables:
Age in years (numeric).
Sex (0 = female, 1 = male).
Chest pain type (numeric code 1–4).
Resting blood pressure (mm Hg).
Serum cholesterol (mg/dl).
Fasting blood sugar > 120 mg/dl (1 = true, 0 = false).
Resting electrocardiographic results (numeric code).
Maximum heart rate achieved.
Exercise-induced angina (1 = yes, 0 = no).
ST depression induced by exercise relative to rest.
Slope of the peak exercise ST segment.
Number of major vessels colored by fluoroscopy (0–3).
Thalassemia status (numeric code).
Original UCI disease score (0–4).
Binary heart disease indicator: "No" (num = 0) or "Yes" (num > 0).
UCI Machine Learning Repository: Heart Disease Data Set. https://archive.ics.uci.edu/dataset/45/heart+disease
############################### Start of Cleveland dataset example #################### data("Cleveland") head(Cleveland) summary(Cleveland) ############################################################################### ## End of Cleveland dataset example ############################################################################################################## Start of Cleveland dataset example #################### data("Cleveland") head(Cleveland) summary(Cleveland) ############################################################################### ## End of Cleveland dataset example ###############################################################################
Computes the directional tail probability based on posterior draws and prior mean, using whitening transformation and projection onto the direction of disagreement. This diagnostic identifies directional disagreement between posterior and prior, and is especially useful for visualizing rejection regions in whitened space. The whitening uses Mahalanobis distance (Mahalanobis 1936) in posterior-precision-scaled coordinates.
directional_tail(fit, mu0 = NULL)directional_tail(fit, mu0 = NULL)
fit |
A fitted model object of class 'glmb' or 'lmb' |
mu0 |
An optional argument containing a reference vector relative to which the directional tail is computed. Defaults to the prior mean. |
An object of class 'directional_tail' containing:
mahalanobis_shift |
Measures the standardized Mahalanobis distance between the posterior and prior means, using posterior precision for scaling. In the Gaussian case, this directly determines the directional tail probability via Phi(-||w||). |
p_directional |
Directional tail probability (proportion of draws in the direction of disagreement) |
delta |
Mean shift in whitened space |
draws |
List containing whitened draws, raw draws, and tail flags |
Mahalanobis PC (1936).
“On the generalized distance in statistics.”
Proceedings of the National Institute of Sciences of India, 2(1), 49–55.
Nygren K (2025).
“Chapter A04: Directional Tail Diagnostics for Prior-Posterior Disagreement.”
Vignette in the glmbayes R package.
R vignette name: Chapter-A04.
glmb is used to fit Bayesian generalized linear models, specified by giving a symbolic descriptions of
the linear predictor, the error distribution, and the prior distribution.
glmb( formula, family = binomial, pfamily = dNormal(mu, Sigma, dispersion = 1), n = 1000, data, weights, use_parallel = TRUE, use_opencl = FALSE, verbose = FALSE, subset, offset, na.action, Gridtype = 2, n_envopt = NULL, start = NULL, etastart, mustart, control = list(...), model = TRUE, method = "glm.fit", x = FALSE, y = TRUE, contrasts = NULL, ... )glmb( formula, family = binomial, pfamily = dNormal(mu, Sigma, dispersion = 1), n = 1000, data, weights, use_parallel = TRUE, use_opencl = FALSE, verbose = FALSE, subset, offset, na.action, Gridtype = 2, n_envopt = NULL, start = NULL, etastart, mustart, control = list(...), model = TRUE, method = "glm.fit", x = FALSE, y = TRUE, contrasts = NULL, ... )
formula |
an object of class |
family |
a description of the error distribution and link
function to be used in the model. For |
pfamily |
a description of the prior distribution and associated constants to be used in the model. This
should be a pfamily function (see |
n |
number of draws to generate. If |
data |
an optional data frame, list or environment (or object
coercible by |
weights |
an optional vector of ‘prior weights’ to be used
in the fitting process. Should be |
use_parallel |
Logical. Whether to use parallel processing during simulation. |
use_opencl |
Logical. Whether to use OpenCL acceleration during Envelope construction. |
verbose |
Logical. Whether to print progress messages. |
subset |
an optional vector specifying a subset of observations to be used in the fitting process. |
offset |
this can be used to specify an a priori known component to be included in the linear
predictor during fitting. This should be |
na.action |
a function which indicates what should happen when the data contain |
Gridtype |
an optional argument specifying the method used to determine the number of tangent points used to construct the enveloping function. |
n_envopt |
Effective sample size passed to EnvelopeOpt for grid
construction. Defaults to match |
start |
starting values for the parameters in the linear predictor. |
etastart |
starting values for the linear predictor. |
mustart |
starting values for the vector of means. |
control |
a list of parameters for controlling the fitting
process. For |
model |
a logical value indicating whether model frame should be included as a component of the returned value. |
method |
the method to be used in fitting the model. The default
method User-supplied fitting functions can be supplied either as a function
or a character string naming a function, with a function which takes
the same arguments as |
x, y
|
For For |
contrasts |
an optional list. See the |
... |
For For |
The function glmb is a Bayesian version of the classical
glm function. The original R implementation of
glm was written by Simon Davies (under Ross Ihaka at the
University of Auckland) and has since been extensively rewritten by
members of the R Core Team; its design was inspired by the S
function described in (Hastie and Pregibon 1992), which in turn relies on the
formula framework described in (Wilkinson and Rogers 1973).
Setup (including the use of formulas and families) mirrors that of glm but adds a
required pfamily argument to specify the prior distribution. The design of the pfamily family of
functions was created by Kjell Nygren and is modeled on how glm
uses family to specify the likelihood.
For any implemented combination of family, link, and pfamily,
glmb generates independent draws from the posterior density-
no MCMC chains are required. Results can be printed or summarized
with methods that mirror those for glm (e.g.\ print.glmb,
summary.glmb), as well as all the usual glm/lm
generics (predict, residuals, etc.).
A helper, Prior_Setup, assists users in choosing prior
parameters. It ships with sensible defaults but also allows full
customization. In particular, the default for dNormal is a
reparameterization of Zellner's g-prior (Zellner 1986).
Currently supported response families are
gaussian (identity link), poisson and quasipoisson
(log link), gamma (log link), and binomial and
quasibinomial (logit, probit, cloglog). All families support a
dNormal prior; the Gaussian family also offers
dNormalGamma and dIndependent_Normal_Gamma.
Two conjugate pfamilies add closed-form IID sampling for intercept-only
models with an identity link: dBeta for
binomial(link = "identity") (Beta–Binomial conjugacy) and
dGamma(Inv_Dispersion = FALSE) for
poisson(link = "identity") and Gamma(link = "identity")
(Gamma–Poisson and Gamma–Gamma rate conjugacy).
For dispersion estimation with fixed coefficients, dGamma
(default Inv_Dispersion = TRUE) places a Gamma prior on the
inverse dispersion for Gaussian and Gamma(log) models.
For the Gaussian family, draws under dNormal and
dNormalGamma come from posterior distributions resulting from conjugate
prior distributions (Raiffa and Schlaifer 1961). For all other priors or response families,
we use an accept-reject sampler built on the likelihood-subgradient envelope
method (Nygren and Nygren 2006). The
Gridtype argument controls how many tangent points are used
in the envelope-trading off envelope tightness against construction
cost-and iters reports candidate counts before acceptance.
By default, glmb draws n = 1000 samples, uses parallel
CPU simulation, and-if use_opencl = TRUE-GPU-accelerated
envelope building. "glmb" comes with many of the same kinds of method functions
that come with "glm" and "lm", so you can still call extractAIC,
fitted.values, or any other standard method.
The lmb function is a Bayesian version of the lm function that can
be used to estimate models from the Gaussian family without the need for a family argument.
rglmb and rlmb are functions with more minimalistic interfaces for estimating the same
models without most of the internal overhead (these functions are called internally by glmb and lmb).
The reduced overhead may be beneficial for Gibbs sampling implementations.
glmb returns an object of class "glmb". The function summary (i.e.,
summary.glmb) can be used to obtain or print a summary of the results. The generic accessor functions
coefficients, fitted.values, residuals, and extractAIC can be used
to extract various useful features of the value returned by glmb.
An object of class "glmb" is a list containing at least the following components:
glm |
an object of class |
coefficients |
a matrix of dimension |
coef.means |
a vector of |
coef.mode |
a vector of |
dispersion |
Either a constant provided as part of the call, or a vector of length |
Prior |
A list with the priors specified for the model in question. Items in list may vary based on the type of prior |
fitted.values |
a matrix of dimension |
family |
the |
linear.predictors |
an |
deviance |
an |
pD |
An Estimate for the effective number of parameters |
Dbar |
Expected value for minus twice the log-likelihood function |
Dthetabar |
Value of minus twice the log-likelihood function evaluated at the mean value for the coefficients |
DIC |
Estimated Deviance Information criterion |
prior.weights |
a vector of weights specified or implied by the model |
y |
a vector with the dependent variable |
x |
a matrix with the implied design matrix for the model |
model |
if requested (the default),the model frame |
call |
the matched call |
formula |
the formula supplie |
terms |
the |
data |
the |
famfunc |
Family functions used during estimation process |
iters |
an |
contrasts |
(where relevant) the contrasts used. |
xlevels |
(where relevant) a record of the levels of the factors used in fitting |
digits |
the number of significant digits to use when printing. |
In addition, non-empty fits will have (yet to be implemented) components qr, R
and effects relating to the final weighted linear fit for the posterior mode.
Objects of class "glmb" are normall of class c("glmb","glm","lm"),
that is inherit from classes glm and lm and well-designed
methods from those classed will be applied when appropriate.
If a binomial glmb model was specified by giving a two-column
response, the weights returned by prior.weights are the total number of
cases (factored by the supplied case weights) and the component of y
of the result is the proportion of successes.
Hastie T~J, Pregibon D (1992).
“Generalized Linear Models.”
In Chambers J~M, Hastie T~J (eds.), Statistical Models in S, chapter 6.
Wadsworth & Brooks/Cole, Belmont, CA.
Nygren K~N, Nygren L~M (2006).
“Likelihood Subgradient Densities.”
Journal of the American Statistical Association, 101(475), 1144–1156.
doi:10.1198/016214506000000357.
Raiffa H, Schlaifer R (1961).
Applied Statistical Decision Theory.
Clinton Press, Inc., Boston.
Wilkinson GN, Rogers CE (1973).
“Symbolic Descriptions of Factorial Models for Analysis of Variance.”
Applied Statistics, 22(3), 392–399.
doi:10.2307/2346786.
Zellner A (1986).
“On Assessing Prior Distributions and Bayesian Regression Analysis with g‐Prior Distributions.”
In Goel P~K, Zellner A (eds.), Bayesian Inference and Decision Techniques: Essays in Honor of Bruno de Finetti, volume 6 of Studies in Bayesian Econometrics and Statistics, 233–243.
Elsevier.
Dobson A~J (1990).
An Introduction to Generalized Linear Models.
Chapman and Hall, London.
lm, glm, family, formula
for classical modeling functions, family objects, and formula syntax
pfamily for documentation of pfamily functions used to specify priors.
Prior_Setup, Prior_Check for functions used to initialize and to check priors,
EnvelopeBuild for envelope construction methods.
Further reading: (Nygren and Nygren 2006); (Nygren 2025, 2025); OpenCL/GPU: (Nygren 2025, 2025).
summary.glmb, predict.glmb, residuals.glmb, simulate.glmb,
extractAIC.glmb, dummy.coef.glmb and methods(class="glmb") for glmb
and the methods and generic functions for classes glm and lm from which class glmb inherits.
glmbayes Modeling Functions
lmb(),
rglmb(),
rlmb()
set.seed(333) ## Dobson (1990) Page 93: Randomized Controlled Trial : counts <- c(18,17,15,20,10,20,25,13,12) outcome <- gl(3,1,9) treatment <- gl(3,3) print(d.AD <- data.frame(treatment, outcome, counts)) ## Classical Model glm.D93 <- glm(counts ~ outcome + treatment, family = poisson(link=log)) summary(glm.D93) ## Poisson Prior and Model ps=Prior_Setup(counts ~ outcome + treatment,family = poisson()) mu=ps$mu V=ps$Sigma # Step 2: Call the glmb function glmb.D93<-glmb(counts ~ outcome + treatment, family=poisson(), pfamily=dNormal(mu=mu,Sigma=V)) summary(glmb.D93) # Menarche Binomial Data Example data(menarche,package="MASS") Age2=menarche$Age-13 ## Classical Model glm.out<-glm(cbind(Menarche, Total-Menarche) ~ Age2, family=binomial(logit), data=menarche) summary(glm.out) ## Logit Prior and Model ps1=Prior_Setup(cbind(Menarche, Total-Menarche) ~ Age2,family=binomial(logit), data=menarche) glmb.out1<-glmb(cbind(Menarche, Total-Menarche) ~ Age2, family=binomial(logit),pfamily=dNormal(mu=ps1$mu,Sigma=ps1$Sigma), data=menarche) summary(glmb.out1) ## Posterior mean fitted probabilities on the response scale (see also ## \code{vignette("Chapter-05", package = "glmbayes")}) require(graphics) pred1 <- predict(glmb.out1, type = "response") pred1_m <- colMeans(pred1) plot( Menarche / Total ~ Age, data = menarche, main = "Proportion with menarche (data and posterior mean fit)" ) lines(menarche$Age, pred1_m, col = "blue", lwd = 2) ## Probit Prior and Model ps2=Prior_Setup(cbind(Menarche, Total-Menarche) ~ Age2,family=binomial(probit), data=menarche) glmb.out2<-glmb(cbind(Menarche, Total-Menarche) ~ Age2, family=binomial(probit),pfamily=dNormal(mu=ps2$mu,Sigma=ps2$Sigma), data=menarche) summary(glmb.out2) ## clog-log Prior and Model ps3=Prior_Setup(cbind(Menarche, Total-Menarche) ~ Age2,family=binomial(cloglog), data=menarche) glmb.out3<-glmb(cbind(Menarche, Total-Menarche) ~ Age2, family=binomial(cloglog),pfamily=dNormal(mu=ps3$mu,Sigma=ps3$Sigma), data=menarche) summary(glmb.out3) ## Comparison of DIC Statistics DIC_Out=rbind(extractAIC(glmb.out1),extractAIC(glmb.out2),extractAIC(glmb.out3)) rownames(DIC_Out)=c("logit","probit","clog-log") colnames(DIC_Out)=c("pD","DIC") DIC_Out ### Gamma regression data(carinsca) carinsca$Merit <- ordered(carinsca$Merit) carinsca$Class <- factor(carinsca$Class) oldopt <- options(contrasts = c("contr.treatment", "contr.treatment")) Claims=carinsca$Claims Insured=carinsca$Insured Merit=carinsca$Merit Class=carinsca$Class Cost=carinsca$Cost out <- glm(Cost/Claims~Merit+Class,family=Gamma(link="log"),weights=Claims,x=TRUE) summary(out) disp=gamma.dispersion(out) ps=Prior_Setup(Cost/Claims~Merit+Class,family=Gamma(link="log"),weights=Claims) mu=ps$mu V=ps$Sigma out3 <- glmb(Cost/Claims~Merit+Class,family=Gamma(link="log"), pfamily=dNormal(mu=mu,Sigma=V,dispersion=disp),weights=Claims) summary(out) summary(out3) options(oldopt) ## glmb with dGamma prior (dispersion-only; coefficients fixed) ctl <- c(4.17, 5.58, 5.18, 6.11, 4.50, 4.61, 5.17, 4.53, 5.33, 5.14) trt <- c(4.81, 4.17, 4.41, 3.59, 5.87, 3.83, 6.03, 4.89, 4.32, 4.69) group <- gl(2, 10, 20, labels = c("Ctl", "Trt")) weight <- c(ctl, trt) ps_dg <- Prior_Setup(weight ~ group, family = gaussian()) rate_dg <- if (!is.null(ps_dg$rate_gamma)) ps_dg$rate_gamma else ps_dg$rate out_glmb_dGamma <- glmb(weight ~ group, family = gaussian(), pfamily = dGamma(shape = ps_dg$shape, rate = rate_dg, beta = ps_dg$coefficients)) summary(out_glmb_dGamma)set.seed(333) ## Dobson (1990) Page 93: Randomized Controlled Trial : counts <- c(18,17,15,20,10,20,25,13,12) outcome <- gl(3,1,9) treatment <- gl(3,3) print(d.AD <- data.frame(treatment, outcome, counts)) ## Classical Model glm.D93 <- glm(counts ~ outcome + treatment, family = poisson(link=log)) summary(glm.D93) ## Poisson Prior and Model ps=Prior_Setup(counts ~ outcome + treatment,family = poisson()) mu=ps$mu V=ps$Sigma # Step 2: Call the glmb function glmb.D93<-glmb(counts ~ outcome + treatment, family=poisson(), pfamily=dNormal(mu=mu,Sigma=V)) summary(glmb.D93) # Menarche Binomial Data Example data(menarche,package="MASS") Age2=menarche$Age-13 ## Classical Model glm.out<-glm(cbind(Menarche, Total-Menarche) ~ Age2, family=binomial(logit), data=menarche) summary(glm.out) ## Logit Prior and Model ps1=Prior_Setup(cbind(Menarche, Total-Menarche) ~ Age2,family=binomial(logit), data=menarche) glmb.out1<-glmb(cbind(Menarche, Total-Menarche) ~ Age2, family=binomial(logit),pfamily=dNormal(mu=ps1$mu,Sigma=ps1$Sigma), data=menarche) summary(glmb.out1) ## Posterior mean fitted probabilities on the response scale (see also ## \code{vignette("Chapter-05", package = "glmbayes")}) require(graphics) pred1 <- predict(glmb.out1, type = "response") pred1_m <- colMeans(pred1) plot( Menarche / Total ~ Age, data = menarche, main = "Proportion with menarche (data and posterior mean fit)" ) lines(menarche$Age, pred1_m, col = "blue", lwd = 2) ## Probit Prior and Model ps2=Prior_Setup(cbind(Menarche, Total-Menarche) ~ Age2,family=binomial(probit), data=menarche) glmb.out2<-glmb(cbind(Menarche, Total-Menarche) ~ Age2, family=binomial(probit),pfamily=dNormal(mu=ps2$mu,Sigma=ps2$Sigma), data=menarche) summary(glmb.out2) ## clog-log Prior and Model ps3=Prior_Setup(cbind(Menarche, Total-Menarche) ~ Age2,family=binomial(cloglog), data=menarche) glmb.out3<-glmb(cbind(Menarche, Total-Menarche) ~ Age2, family=binomial(cloglog),pfamily=dNormal(mu=ps3$mu,Sigma=ps3$Sigma), data=menarche) summary(glmb.out3) ## Comparison of DIC Statistics DIC_Out=rbind(extractAIC(glmb.out1),extractAIC(glmb.out2),extractAIC(glmb.out3)) rownames(DIC_Out)=c("logit","probit","clog-log") colnames(DIC_Out)=c("pD","DIC") DIC_Out ### Gamma regression data(carinsca) carinsca$Merit <- ordered(carinsca$Merit) carinsca$Class <- factor(carinsca$Class) oldopt <- options(contrasts = c("contr.treatment", "contr.treatment")) Claims=carinsca$Claims Insured=carinsca$Insured Merit=carinsca$Merit Class=carinsca$Class Cost=carinsca$Cost out <- glm(Cost/Claims~Merit+Class,family=Gamma(link="log"),weights=Claims,x=TRUE) summary(out) disp=gamma.dispersion(out) ps=Prior_Setup(Cost/Claims~Merit+Class,family=Gamma(link="log"),weights=Claims) mu=ps$mu V=ps$Sigma out3 <- glmb(Cost/Claims~Merit+Class,family=Gamma(link="log"), pfamily=dNormal(mu=mu,Sigma=V,dispersion=disp),weights=Claims) summary(out) summary(out3) options(oldopt) ## glmb with dGamma prior (dispersion-only; coefficients fixed) ctl <- c(4.17, 5.58, 5.18, 6.11, 4.50, 4.61, 5.17, 4.53, 5.33, 5.14) trt <- c(4.81, 4.17, 4.41, 3.59, 5.87, 3.83, 6.03, 4.89, 4.32, 4.69) group <- gl(2, 10, 20, labels = c("Ctl", "Trt")) weight <- c(ctl, trt) ps_dg <- Prior_Setup(weight ~ group, family = gaussian()) rate_dg <- if (!is.null(ps_dg$rate_gamma)) ps_dg$rate_gamma else ps_dg$rate out_glmb_dGamma <- glmb(weight ~ group, family = gaussian(), pfamily = dGamma(shape = ps_dg$shape, rate = rate_dg, beta = ps_dg$coefficients)) summary(out_glmb_dGamma)
Fits one glmb per observation block. Same row partition as
lmbBlock, but supports GLM family objects.
Counterpart to lmbBlock; see summary.bglmb for
the summary method and block_rNormalGLM for Gibbs sampling.
glmbBlock( formula, block, family = gaussian(), pfamily = NULL, pfamily_list = NULL, n = 1000, data, subset, weights, na.action, offset, contrasts = NULL, model = TRUE, x = FALSE, y = TRUE, Gridtype = 2, n_envopt = NULL, use_parallel = TRUE, use_opencl = FALSE, verbose = FALSE, ... ) ## S3 method for class 'bglmb' print(x, digits = max(3, getOption("digits") - 3), ...)glmbBlock( formula, block, family = gaussian(), pfamily = NULL, pfamily_list = NULL, n = 1000, data, subset, weights, na.action, offset, contrasts = NULL, model = TRUE, x = FALSE, y = TRUE, Gridtype = 2, n_envopt = NULL, use_parallel = TRUE, use_opencl = FALSE, verbose = FALSE, ... ) ## S3 method for class 'bglmb' print(x, digits = max(3, getOption("digits") - 3), ...)
formula |
an object of class |
block |
Block partition: |
family |
a description of the error distribution and link
function to be used in the model. For |
pfamily |
Recycled to all blocks, or use |
pfamily_list |
Optional list of |
n |
number of draws to generate. If |
data |
an optional data frame, list or environment (or object
coercible by |
subset |
an optional vector specifying a subset of observations to be used in the fitting process. |
weights |
an optional vector of weights to be used in the fitting
process. Should be |
na.action |
a function which indicates what should happen when the data contain |
offset |
this can be used to specify an a priori known component to be
included in the linear predictor during fitting. This should be |
contrasts |
an optional list. See the |
model, x, y
|
For |
Gridtype |
an optional argument specifying the method used to determine the number of tangent points used to construct the enveloping function. |
n_envopt |
Effective sample size passed to EnvelopeOpt for grid
construction. Defaults to match |
use_parallel |
Logical. Whether to use parallel processing during simulation. |
use_opencl |
Logical. Whether to use OpenCL acceleration during Envelope construction. |
verbose |
Logical. Whether to print progress messages. |
... |
For |
digits |
Number of significant digits to use when printing. |
A named list of class "bglmb" (list of "glmb" fits from glmbayes).
glmbBlock(): glmb fit per row block.
glmbayes Modeling Functions
lmbBlock()
Bayesian generalized linear mixed-effects model fit
glmerb( formula, data = NULL, family = gaussian(), pfamily_list, dispersion_ranef = NULL, n = 1000L, gap_tol = 0.0196, mode_gap_max = 1, tv_tol = 0.01, m_convergence = NULL, m_convergence_pilot = NULL, simulate = TRUE, REML = TRUE, control = NULL, start = NULL, verbose = 0L, subset, weights, na.action, offset, contrasts = NULL, devFunOnly = FALSE, fixef = NULL, progbar = FALSE, ... ) ## S3 method for class 'glmerb' print(x, digits = max(3L, getOption("digits") - 3L), ...)glmerb( formula, data = NULL, family = gaussian(), pfamily_list, dispersion_ranef = NULL, n = 1000L, gap_tol = 0.0196, mode_gap_max = 1, tv_tol = 0.01, m_convergence = NULL, m_convergence_pilot = NULL, simulate = TRUE, REML = TRUE, control = NULL, start = NULL, verbose = 0L, subset, weights, na.action, offset, contrasts = NULL, devFunOnly = FALSE, fixef = NULL, progbar = FALSE, ... ) ## S3 method for class 'glmerb' print(x, digits = max(3L, getOption("digits") - 3L), ...)
formula |
Mixed-model formula (single grouping factor; same constraints
as |
data |
Data frame containing all variables in |
family |
A |
pfamily_list |
Required named list of
|
dispersion_ranef |
Observation-level measurement dispersion, treated
as known during sampling. Required positive scalar for families with a
dispersion parameter (e.g. |
n |
Number of iid draws per group (default |
gap_tol |
Tolerated mode–mean gap in units of posterior standard
deviations (default |
mode_gap_max |
Maximum per-coordinate mode–mean gap (in posterior
standard deviation units) that |
tv_tol |
Total variation tolerance per stored draw, in (0, 1)
(default |
m_convergence |
Optional integer override for the number of inner
Gibbs sweeps per stored draw. When |
m_convergence_pilot |
Optional integer override for the number of
inner Gibbs sweeps used in each independent pilot chain. Applies only
when |
simulate |
Logical (default |
REML |
Logical; passed to |
control |
Optional |
start |
Optional starting values; passed to |
verbose |
Verbosity flag; passed to |
subset |
Optional subset; passed to |
weights |
Optional weights; passed to |
na.action |
Missing-data handler; passed to |
offset |
Optional offset; passed to |
contrasts |
Optional contrasts; passed to |
devFunOnly |
If |
fixef |
Optional named list of hyper-parameter vectors (Block 2 state).
When |
progbar |
Logical. When |
... |
Reserved for future use. |
x |
Object of class |
digits |
Number of significant digits to use when printing. |
Draft entry point for lmebayes GLMM models with a glmer-like
interface, analogous to lmerb for Gaussian responses and to
glmb for fixed-effects GLMs.
Currently a copy of lmerb with an additional family
argument. When family = gaussian(), behaviour matches
lmerb except that the embedded reference fit is from
glmer rather than lmer. Non-Gaussian
families use block_rNormalGLM for Block~1 Gibbs updates.
Object of class "glmerb": same fixef.* structure as
"lmerb", with additional family, glmer (reference
glmer fit), fixef.init (main-chain start from
pilot colMeans when a pilot runs; NULL for Gaussian or when
n_pilot = NULL), pilot_chisq (Hotelling chi-squared test of
pilot mean vs ICM mode), gap_tol, and mode_gap_max.
lmerb, glmerb_posterior_mode,
glmb; demo for the full sampling workflow
(demo("Ex_14_glmerb_airbnb_small", package = "lmebayes")).
## glmerb: neighborhood random effects on bayesrules::airbnb_small (Poisson) ## ## Fast man-page example: prior setup, glmer reference fit, and ICM posterior ## mode only (simulate = FALSE). No Gibbs draws — suitable for R CMD check. ## ## The full sampling workflow (pilot stage, main draws, centering diagnostics) ## is preserved as a demo: ## demo("Ex_14_glmerb_airbnb_small", package = "lmebayes") if (requireNamespace("bayesrules", quietly = TRUE)) { data(airbnb_small, package = "bayesrules") dat <- airbnb_small dat$rating_c <- dat$rating - mean(dat$rating, na.rm = TRUE) dat$walk_c <- dat$walk_score - mean(dat$walk_score, na.rm = TRUE) dat <- dat[complete.cases(dat[, c("reviews", "rating_c", "walk_c", "neighborhood")]), ] dat$neighborhood <- droplevels(factor(dat$neighborhood)) form <- reviews ~ walk_c + rating_c + (1 + rating_c || neighborhood) ps <- Prior_Setup_lmebayes(form, data = dat, family = poisson(), pwt = 0.01) fit <- glmerb( form, data = dat, family = poisson(), pfamily_list = pfamily_list(ps), simulate = FALSE ) lmebayes:::print_coef_means(fit) print(fit) lme4::fixef(fit$glmer) }## glmerb: neighborhood random effects on bayesrules::airbnb_small (Poisson) ## ## Fast man-page example: prior setup, glmer reference fit, and ICM posterior ## mode only (simulate = FALSE). No Gibbs draws — suitable for R CMD check. ## ## The full sampling workflow (pilot stage, main draws, centering diagnostics) ## is preserved as a demo: ## demo("Ex_14_glmerb_airbnb_small", package = "lmebayes") if (requireNamespace("bayesrules", quietly = TRUE)) { data(airbnb_small, package = "bayesrules") dat <- airbnb_small dat$rating_c <- dat$rating - mean(dat$rating, na.rm = TRUE) dat$walk_c <- dat$walk_score - mean(dat$walk_score, na.rm = TRUE) dat <- dat[complete.cases(dat[, c("reviews", "rating_c", "walk_c", "neighborhood")]), ] dat$neighborhood <- droplevels(factor(dat$neighborhood)) form <- reviews ~ walk_c + rating_c + (1 + rating_c || neighborhood) ps <- Prior_Setup_lmebayes(form, data = dat, family = poisson(), pwt = 0.01) fit <- glmerb( form, data = dat, family = poisson(), pfamily_list = pfamily_list(ps), simulate = FALSE ) lmebayes:::print_coef_means(fit) print(fit) lme4::fixef(fit$glmer) }
Returns whether this lmebayes installation was built with OpenCL
support (link-time / USE_OPENCL). This is independent of
has_opencl() in opencltools,
which probes the host runtime (ICD, drivers, headers).
For workstation diagnostics (drivers, PATH, ICD), use
diagnose_glmbayes() from
opencltools. For kernel loading from inst/cl/, use
load_kernel_source() with the
appropriate package argument once opencltools is installed.
has_opencl()has_opencl()
Logical scalar.
opencltools, glmbayes
lmb is used to fit Bayesian linear models, specified by giving a symbolic descriptions of the linear
predictor and the prior distribution.
lmb( formula, pfamily, n = 1000, data, subset, weights, na.action, method = "qr", model = TRUE, x = TRUE, y = TRUE, qr = TRUE, singular.ok = TRUE, contrasts = NULL, offset, Gridtype = 2, n_envopt = NULL, use_parallel = TRUE, use_opencl = FALSE, verbose = FALSE, ... )lmb( formula, pfamily, n = 1000, data, subset, weights, na.action, method = "qr", model = TRUE, x = TRUE, y = TRUE, qr = TRUE, singular.ok = TRUE, contrasts = NULL, offset, Gridtype = 2, n_envopt = NULL, use_parallel = TRUE, use_opencl = FALSE, verbose = FALSE, ... )
formula |
an object of class |
pfamily |
a description of the prior distribution and associated constants to be used in the model.
For a single-response formula this should be a single |
n |
number of draws to generate. If |
data |
an optional data frame, list or environment (or object
coercible by |
subset |
an optional vector specifying a subset of observations to be used in the fitting process. |
weights |
an optional vector of weights to be used in the fitting
process. Should be |
na.action |
a function which indicates what should happen when the data contain |
method |
the method to be used in fitting the classical model during a call to |
model, x, y, qr
|
logicals. If |
singular.ok |
logical. If |
contrasts |
an optional list. See the |
offset |
this can be used to specify an a priori known component to be
included in the linear predictor during fitting. This should be |
Gridtype |
an optional argument specifying the method used to determine the number of tangent points used to construct the enveloping function. |
n_envopt |
Effective sample size passed to EnvelopeOpt for grid
construction. Defaults to match |
use_parallel |
Logical. Whether to use parallel processing during simulation. |
use_opencl |
Logical. Whether to use OpenCL acceleration during Envelope construction. |
verbose |
Logical. Whether to print progress messages. |
... |
For |
The function lmb is a Bayesian extension of the classical lm function.
It retains the familiar formula interface and model setup used in lm, while introducing
posterior simulation and prior specification via the pfamily argument. Internally,
lmb calls lm to obtain the classical least squares fit, then generates independent
draws from the posterior distribution using either multivariate normal simulation (for Gaussian priors)
or accept-reject sampling via likelihood-subgradient envelopes (Nygren and Nygren 2006).
The symbolic formula interface follows (Wilkinson and Rogers 1973), and the overall design of lm was inspired by the S system
(Chambers 1992). lmb comes with many of the same types of generic methods
that are available to lm and glm, including predict, residuals, extractAIC,
and summary. Many of these are inherited from glmb.
Prior specification is handled via the pfamily argument, which defines the prior mean,
covariance, and dispersion. The design of the pfamily family of functions was created by Kjell Nygren
and is modeled on how glm uses family to specify the likelihood. A helper function,
Prior_Setup, assists users in choosing prior parameters. It ships with sensible defaults but
also allows full customization. All models support the dNormal prior; the Gaussian family also supports
dNormalGamma and dIndependent_Normal_Gamma, which allow for more flexible prior structures
including independent priors on variance components.
Posterior draws are generated using the prior specification provided via pfamily. For Gaussian models
with conjugate priors, draws are obtained directly from the posterior distribution using standard simulation
procedures for multivariate normal densities (Raiffa and Schlaifer 1961). For non-conjugate setups, the
function uses envelope-based accept-reject sampling, where the Gridtype parameter controls the granularity
of the envelope construction. The number of candidates generated before acceptance is returned in the
iters component.
The output includes both the classical lm fit and Bayesian diagnostics such as the Deviance
Information Criterion (DIC), effective number of parameters (pD), and posterior summaries.
The DIC, introduced by (Spiegelhalter et al. 2002), provides a Bayesian analog to AIC
by balancing model fit and complexity using posterior expectations. This dual structure allows users
to compare classical and Bayesian fits side-by-side, and to leverage familiar modeling workflows
while gaining access to richer inferential tools.
The lmb function is a specialized version of glmb for Gaussian models,
and does not require a family argument. For conjugate models, it uses standard simulation methods for
posterior draws, avoiding the need for envelope construction or subgradient sampling.
Like glmb, it returns objects compatible with many standard methods from lm and glm,
including extractAIC, fitted.values, and residuals.
For more minimalistic workflows, rlmb and rglmb offer stripped-down interfaces
for posterior sampling without the overhead of full model objects. rlmb is called from within
lmb. The functions rlmb might be useful in Gibbs sampling or simulation-heavy contexts.
lmb returns an object of class "lmb". The function summary (i.e.,
summary.glmb) can be used to obtain or print a summary of the results. The generic accessor functions
coefficients, fitted.values, residuals, and extractAIC can be used
to extract various useful features of the value returned by lmb.
An object of class "lmb" is a list containing at least the following components:
lm |
an object of class |
coefficients |
a matrix of dimension |
coef.means |
a vector of |
coef.mode |
a vector of |
dispersion |
Either a constant provided as part of the call, or a vector of length |
Prior |
A list with the priors specified for the model in question. Items in list may vary based on the type of prior |
residuals |
a matrix of dimension |
fitted.values |
a matrix of dimension |
linear.predictors |
an |
deviance |
an |
pD |
An Estimate for the effective number of parameters |
Dbar |
Expected value for minus twice the log-likelihood function |
Dthetabar |
Value of minus twice the log-likelihood function evaluated at the mean value for the coefficients |
DIC |
Estimated Deviance Information criterion |
weights |
a vector of weights specified or implied by the model |
prior.weights |
a vector of weights specified or implied by the model |
y |
a vector of observations of length |
x |
a design matrix of dimension |
model |
if requested (the default),the model frame |
call |
the matched call |
formula |
the formula supplied |
terms |
the |
data |
the |
famfunc |
family functions used during estimation and post processing |
iters |
an |
contrasts |
(where relevant) the contrasts used. |
xlevels |
(where relevant) a record of the levels of the factors used in fitting |
pfamily |
the prior family specified |
digits |
the number of significant digits to use when printing. |
In addition, non-empty fits will have (yet to be implemented) components qr, R
and effects relating to the final weighted linear fit for the posterior mode.
Objects of class "lmb" are normally of class c("lmb","glmb","glm","lm"),
that is inherit from classes glmb. glm and lm and well-designed
methods from those classed will be applied when appropriate.
Chambers JM (1992).
“Linear Models.”
In Chambers JM, Hastie TJ (eds.), Statistical Models in S, chapter 4, 85–124.
Wadsworth & Brooks/Cole, Pacific Grove, CA.
Nygren K~N, Nygren L~M (2006).
“Likelihood Subgradient Densities.”
Journal of the American Statistical Association, 101(475), 1144–1156.
doi:10.1198/016214506000000357.
Raiffa H, Schlaifer R (1961).
Applied Statistical Decision Theory.
Clinton Press, Inc., Boston.
Spiegelhalter DJ, Best NG, Carlin BP, van der Linde A (2002).
“Bayesian Measures of Model Complexity and Fit.”
Journal of the Royal Statistical Society: Series B (Statistical Methodology), 64(4), 583–639.
doi:10.1111/1467-9868.00353.
Wilkinson GN, Rogers CE (1973).
“Symbolic Descriptions of Factorial Models for Analysis of Variance.”
Applied Statistics, 22(3), 392–399.
doi:10.2307/2346786.
The classical modeling functions lm and glm.
glmb, rglmb, rlmb
for related Bayesian GLM/linear interfaces;
EnvelopeBuild for envelope construction when accept–reject sampling is used.
pfamily for documentation of pfamily functions used to specify priors.
Prior_Setup, Prior_Check for functions used to initialize and to check priors,
Further reading: (Nygren and Nygren 2006); (Nygren 2025, 2025); independent Normal–Gamma sampler: (Nygren 2025).
summary.glmb, predict.glmb, simulate.glmb,
extractAIC.glmb, dummy.coef.glmb and methods(class="glmb") for methods
inherited from class glmb and the methods and generic functions for classes glm and
lm from which class lmb also inherits.
glmbayes Modeling Functions
glmb(),
rglmb(),
rlmb()
## Annette Dobson (1990) "An Introduction to Generalized Linear Models". ## Page 9: Plant Weight Data. ctl <- c(4.17, 5.58, 5.18, 6.11, 4.50, 4.61, 5.17, 4.53, 5.33, 5.14) trt <- c(4.81, 4.17, 4.41, 3.59, 5.87, 3.83, 6.03, 4.89, 4.32, 4.69) group <- gl(2, 10, 20, labels = c("Ctl", "Trt")) weight <- c(ctl, trt) ps <- Prior_Setup(weight ~ group, gaussian()) # Prior_Setup supplies the prior mean and covariance components used below. ## Classical model lm.D9 <- lm(weight ~ group, x = TRUE, y = TRUE) summary(lm.D9) vcov(lm.D9) s <- summary(lm.D9) disp_classical <- s$sigma^2 cat("Classical lm dispersion (sigma^2 = RSS/(n-p)):", disp_classical, "\n") ## Conjugate Normal Prior (fixed dispersion) lmb.D9 <- lmb( weight ~ group, pfamily = dNormal(mu = ps$mu, ps$Sigma, dispersion = ps$dispersion) ) summary(lmb.D9) vcov(lmb.D9) ## Conjugate Normal_Gamma Prior (second argument is Sigma_0 from Prior_Setup) lmb.D9_v2 <- lmb( weight ~ group, pfamily = dNormal_Gamma( ps$mu, Sigma_0 = ps$Sigma_0, shape = ps$shape, rate = ps$rate ) ) summary(lmb.D9_v2) vcov(lmb.D9_v2) ## Independent_Normal_Gamma_Prior (same mu, Sigma, rate as dNormal_Gamma; shape = ps$shape_ING) lmb.D9_v3 <- lmb( weight ~ group, dIndependent_Normal_Gamma( ps$mu, ps$Sigma, shape = ps$shape_ING, rate = ps$rate ) ) summary(lmb.D9_v3) ## anova anova(lmb.D9) ## lmb with dGamma prior (dispersion-only; coefficients fixed) rate_dg <- if (!is.null(ps$rate_gamma)) ps$rate_gamma else ps$rate out_lmb_dGamma <- lmb( weight ~ group, pfamily = dGamma(shape = ps$shape, rate = rate_dg, beta = ps$coefficients)) summary(out_lmb_dGamma)## Annette Dobson (1990) "An Introduction to Generalized Linear Models". ## Page 9: Plant Weight Data. ctl <- c(4.17, 5.58, 5.18, 6.11, 4.50, 4.61, 5.17, 4.53, 5.33, 5.14) trt <- c(4.81, 4.17, 4.41, 3.59, 5.87, 3.83, 6.03, 4.89, 4.32, 4.69) group <- gl(2, 10, 20, labels = c("Ctl", "Trt")) weight <- c(ctl, trt) ps <- Prior_Setup(weight ~ group, gaussian()) # Prior_Setup supplies the prior mean and covariance components used below. ## Classical model lm.D9 <- lm(weight ~ group, x = TRUE, y = TRUE) summary(lm.D9) vcov(lm.D9) s <- summary(lm.D9) disp_classical <- s$sigma^2 cat("Classical lm dispersion (sigma^2 = RSS/(n-p)):", disp_classical, "\n") ## Conjugate Normal Prior (fixed dispersion) lmb.D9 <- lmb( weight ~ group, pfamily = dNormal(mu = ps$mu, ps$Sigma, dispersion = ps$dispersion) ) summary(lmb.D9) vcov(lmb.D9) ## Conjugate Normal_Gamma Prior (second argument is Sigma_0 from Prior_Setup) lmb.D9_v2 <- lmb( weight ~ group, pfamily = dNormal_Gamma( ps$mu, Sigma_0 = ps$Sigma_0, shape = ps$shape, rate = ps$rate ) ) summary(lmb.D9_v2) vcov(lmb.D9_v2) ## Independent_Normal_Gamma_Prior (same mu, Sigma, rate as dNormal_Gamma; shape = ps$shape_ING) lmb.D9_v3 <- lmb( weight ~ group, dIndependent_Normal_Gamma( ps$mu, ps$Sigma, shape = ps$shape_ING, rate = ps$rate ) ) summary(lmb.D9_v3) ## anova anova(lmb.D9) ## lmb with dGamma prior (dispersion-only; coefficients fixed) rate_dg <- if (!is.null(ps$rate_gamma)) ps$rate_gamma else ps$rate out_lmb_dGamma <- lmb( weight ~ group, pfamily = dGamma(shape = ps$shape, rate = rate_dg, beta = ps$coefficients)) summary(out_lmb_dGamma)
Fits one lmb per observation block (SAS BY-style split on
rows), sharing the same formula on each subset. Contrast with
lmb on a cbind(...) response (several response columns) and
block_rNormalGLM (Gibbs conditional draws, matrix API).
lmbBlock( formula, block, pfamily = NULL, pfamily_list = NULL, n = 1000, data, subset, weights, na.action, method = "qr", model = TRUE, x = TRUE, y = TRUE, qr = TRUE, singular.ok = TRUE, contrasts = NULL, offset, Gridtype = 2, n_envopt = NULL, use_parallel = TRUE, use_opencl = FALSE, verbose = FALSE, ... ) ## S3 method for class 'blmb' print(x, digits = max(3, getOption("digits") - 3), ...)lmbBlock( formula, block, pfamily = NULL, pfamily_list = NULL, n = 1000, data, subset, weights, na.action, method = "qr", model = TRUE, x = TRUE, y = TRUE, qr = TRUE, singular.ok = TRUE, contrasts = NULL, offset, Gridtype = 2, n_envopt = NULL, use_parallel = TRUE, use_opencl = FALSE, verbose = FALSE, ... ) ## S3 method for class 'blmb' print(x, digits = max(3, getOption("digits") - 3), ...)
formula |
an object of class |
block |
Block partition: |
pfamily |
A single |
pfamily_list |
Optional list of |
n |
number of draws to generate. If |
data |
an optional data frame, list or environment (or object
coercible by |
subset |
an optional vector specifying a subset of observations to be used in the fitting process. |
weights |
an optional vector of weights to be used in the fitting
process. Should be |
na.action |
a function which indicates what should happen when the data contain |
method |
the method to be used in fitting the classical model during a call to |
model, x, y, qr
|
For |
singular.ok |
logical. If |
contrasts |
an optional list. See the |
offset |
this can be used to specify an a priori known component to be
included in the linear predictor during fitting. This should be |
Gridtype |
an optional argument specifying the method used to determine the number of tangent points used to construct the enveloping function. |
n_envopt |
Effective sample size passed to EnvelopeOpt for grid
construction. Defaults to match |
use_parallel |
Logical. Whether to use parallel processing during simulation. |
use_opencl |
Logical. Whether to use OpenCL acceleration during Envelope construction. |
verbose |
Logical. Whether to print progress messages. |
... |
For |
digits |
Number of significant digits to use when printing. |
A named list of class "blmb" (list of "lmb" fits).
lmbBlock(): Gaussian lmb fit per row block.
glmbayes Modeling Functions
glmbBlock()
## Row-block lmb (iris): BY Species — SAS-style separate regressions set.seed(42) data("iris", package = "datasets") ps_block <- Prior_SetupBlock( Sepal.Length ~ Sepal.Width + Petal.Length, block = "Species", data = iris, family = gaussian() ) pfamily_list <- lapply(ps_block, function(ps) { glmbayesCore::dNormal_Gamma( mu = ps$mu, Sigma_0 = ps$Sigma_0, shape = ps$shape, rate = ps$rate ) }) out_blmb <- lmbBlock( Sepal.Length ~ Sepal.Width + Petal.Length, block = "Species", pfamily_list = pfamily_list, data = iris, n = 150L, use_parallel = FALSE ) print(out_blmb) summary(out_blmb)## Row-block lmb (iris): BY Species — SAS-style separate regressions set.seed(42) data("iris", package = "datasets") ps_block <- Prior_SetupBlock( Sepal.Length ~ Sepal.Width + Petal.Length, block = "Species", data = iris, family = gaussian() ) pfamily_list <- lapply(ps_block, function(ps) { glmbayesCore::dNormal_Gamma( mu = ps$mu, Sigma_0 = ps$Sigma_0, shape = ps$shape, rate = ps$rate ) }) out_blmb <- lmbBlock( Sepal.Length ~ Sepal.Width + Petal.Length, block = "Species", pfamily_list = pfamily_list, data = iris, n = 150L, use_parallel = FALSE ) print(out_blmb) summary(out_blmb)
Bayesian linear mixed-effects model fit
lmerb( formula, data = NULL, pfamily_list, dispersion_ranef, n = 1000L, tv_tol = 0.01, m_convergence = NULL, simulate = TRUE, REML = TRUE, control = lme4::lmerControl(), start = NULL, verbose = 0L, subset, weights, na.action, offset, contrasts = NULL, devFunOnly = FALSE, fixef = NULL, seed = NULL, ... ) ## S3 method for class 'lmerb' print(x, digits = max(3L, getOption("digits") - 3L), ...)lmerb( formula, data = NULL, pfamily_list, dispersion_ranef, n = 1000L, tv_tol = 0.01, m_convergence = NULL, simulate = TRUE, REML = TRUE, control = lme4::lmerControl(), start = NULL, verbose = 0L, subset, weights, na.action, offset, contrasts = NULL, devFunOnly = FALSE, fixef = NULL, seed = NULL, ... ) ## S3 method for class 'lmerb' print(x, digits = max(3L, getOption("digits") - 3L), ...)
formula |
Mixed-model formula (single grouping factor; same constraints
as |
data |
Data frame containing all variables in |
pfamily_list |
Required named list of
|
dispersion_ranef |
Required positive scalar: the observation-level
measurement dispersion |
n |
Number of iid draws per group (default |
tv_tol |
Total variation tolerance per stored draw, in (0, 1)
(default |
m_convergence |
Optional integer override for the number of inner
Gibbs sweeps per stored draw. When |
simulate |
Logical (default |
REML |
Logical; passed to |
control |
|
start |
Optional starting values; passed to |
verbose |
Verbosity flag; passed to |
subset |
Optional subset; passed to |
weights |
Optional weights; passed to |
na.action |
Missing-data handler; passed to |
offset |
Optional offset; passed to |
contrasts |
Optional contrasts; passed to |
devFunOnly |
If |
fixef |
Optional named list of hyper-parameter vectors (Block 2 state).
When |
seed |
Optional; sets the RNG seed before sampling. |
... |
Reserved for future use. |
x |
Object of class |
digits |
Number of significant digits to use when printing. |
Entry point for lmebayes models with an lmer-like interface,
analogous to lmb and glmb for fixed-effects models.
Calls model_setup on formula and data for design
matrices (y, Z, groups, X_hyper, etc.) and embeds
the resulting lmer fit as lmer. Priors are
supplied as a named list of pfamily objects
(pfamily_list, the Block~2 hyperpriors – one per random-effect
coefficient) plus the observation-level measurement dispersion
(dispersion_ranef). Both are typically built from
Prior_Setup_lmebayes:
pfamily_list = pfamily_list(ps) and
dispersion_ranef = ps$dispersion_ranef. The Block~1 random-effect
covariance is reconstructed from the Block~2 pfamily dispersions
(Sigma_ranef = diag(tau^2_k)); lmerb does not call
Prior_Setup_lmebayes internally.
Runs a two-block Gibbs sampler for n iterations. Block 1 draws
group-level random effects given the current hyper means; Block 2
updates the hyper means (level-2 fixed effects )
given the current draw, using
multi_rNormal_reg
with the hyper design matrices from design$X_hyper.
Exact posterior and convergence characterisation.
When variance components are treated as fixed at their lmer estimates
(as done here), the joint posterior over the random-effect coefficients and
the level-2 fixed effects is exactly multivariate normal. In this
setting the convergence of the two-block Gibbs sampler is fully
characterised: Corollary 1 of Nygren (2020) shows that the total variation
(TV) distance between the -step kernel and the target density is
bounded above by a geometrically decreasing function of , with
contraction rate , the maximal eigenvalue of the
matrix
where , , and are the corresponding
blocks of the joint precision matrix. Because the bound is explicit and
computable, the required number of iterations to reach a pre-specified TV
tolerance can be derived analytically once
is known.
TV-calibrated m_convergence.
The number of inner Gibbs sweeps per stored draw (m_convergence) is
derived from tv_tol: lmerb computes the Remark 8 eigenvalue
spectrum with two_block_rate_v2 and inverts the
exact Theorem 3 bound with
two_block_l_for_tv. Because every replicate
chain is started at the exact joint posterior mean (computed by ICM via
lmerb_posterior_mean), the mean term of the
bound vanishes and only the variance-convergence sum remains. One extra
sweep is added because the bound applies to the block updated second in
each sweep (the level-2 fixed effects ); the stored
random-effect draw lags by a half-step. Each stored draw is therefore
guaranteed to be within tv_tol of the exact joint posterior in
total variation.
Object of class "lmerb": a list with the following
components (parallel to glmb and lmb):
callThe matched call.
formulaThe formula supplied.
lmerlmer fit from
model_setup (full formula), embedded as a sub-object —
analogous to glmb$glm and lmb$lm. Use
coef(fit$lmer) for per-group classical coefficients.
priorNormalized prior container: pfamily_list
(as supplied, reordered to the RE coefficient names),
dispersion_ranef, the reconstructed Sigma_ranef, and
the per-component prior_list (mu_fixef,
Sigma_fixef, dispersion_fixef) — analogous to
glmb$Prior.
model_setupThe model_setup object built
inside lmerb from formula and data.
fixef.modeNamed list of exact posterior mode (= mean,
since the joint posterior is Gaussian) vectors for the level-2 fixed
effects , computed by
lmerb_posterior_mean (ICM).
ranef.mode numeric matrix
of exact posterior mode random effects from ICM. Rows are group
levels (levels(design$groups)); columns are
design$re_coef_names.
fixef.meansNamed list of posterior mean vectors computed
as colMeans(fixef[[k]]) — the MCMC estimate of the
level-2 fixed effects. NULL when simulate = FALSE.
fixefNamed list of matrices of
Block 2 draws, one per RE component. NULL when
simulate = FALSE.
coefficientsdata.frame with n * J rows:
draw, the grouping-factor column, and one column per RE
variable. Average over draw within each group for posterior
means (see Examples). NULL when simulate = FALSE.
fixef.dispersion matrix of the
Block~2 dispersion () at each stored draw: sampled
values for dIndependent_Normal_Gamma components, constant
columns (the fixed dispersion) for dNormal components.
NULL when simulate = FALSE.
fixef.dispersion.meanNamed vector of posterior means of
(colMeans(fixef.dispersion)). NULL when
simulate = FALSE.
fixef.iters matrix of the
total number of Block~2 candidates generated per stored draw,
summed over the m_convergence inner sweeps.
dIndependent_Normal_Gamma components count envelope
accept-reject candidates until acceptance (as iters in
glmbayes samplers); dNormal components count exactly
one conjugate draw per sweep. NULL when
simulate = FALSE.
fixef.iters.meanNamed vector of average candidates per
accepted Block~2 draw
(colMeans(fixef.iters)/m_convergence; equals 1 for
dNormal components, and approximately the reciprocal
acceptance rate of the ING envelope sampler otherwise).
NULL when simulate = FALSE.
fixef.muNumeric matrix p_re x J of Block 1 prior
means at the final Gibbs state (from
build_mu_all).
convergenceList describing the sweep-count calibration:
method ("exact", or "local_gaussian_mode" for
non-Gaussian glmerb), tv_tol,
lambda_star, eigenvalues, m_min (derived
minimum sweeps), and m_convergence (sweeps actually used).
NULL when simulate = FALSE.
Nygren, K. (2020). On the total variation distance between multivariate normal densities with applications to two-block Gibbs samplers. Unpublished manuscript.
Jones, G. L. and Hobert, J. P. (2001). Honest exploration of intractable probability distributions via Markov chain Monte Carlo. Statistical Science 16, 312–334.
Prior_Setup_lmebayes, model_setup,
build_mu_all,
two_block_rNormal_reg_v2,
lmerb_posterior_mean,
block_rNormalReg,
lmb, glmb
## lmerb: school random effects on bayesrules::big_word_club ## ## Random intercept and distracted_ppvt random slope by school; the school's ## share of free/reduced-lunch students (free_reduced_lunch, constant within ## school) is a level-2 predictor of the school intercepts. ## ## Fast man-page example: prior setup, lmer reference fit, and ICM posterior ## mean only (simulate = FALSE). No Gibbs draws — suitable for R CMD check. ## ## The full sampling workflows are preserved as demos: ## demo("Ex_14_lmerb_Sleepstudy", package = "lmebayes") # lme4-style small model ## demo("Ex_12_lmerb_BigWordClub", package = "lmebayes") # full formula if (requireNamespace("bayesrules", quietly = TRUE)) { data(big_word_club, package = "bayesrules") dat <- big_word_club dat$school_id <- factor(dat$school_id) dat <- subset(dat, !is.na(score_ppvt) & !is.na(invalid_ppvt) & invalid_ppvt == 0L) dat <- dat[complete.cases(dat[, c("score_ppvt", "distracted_ppvt", "free_reduced_lunch", "school_id")]), ] form <- score_ppvt ~ free_reduced_lunch + distracted_ppvt + (1 + distracted_ppvt || school_id) ## Default hyperpriors calibrated from a reference lmer fit (weak prior). ps <- Prior_Setup_lmebayes(form, data = dat, pwt = 0.01) fit <- lmerb( form, data = dat, pfamily_list = pfamily_list(ps), dispersion_ranef = ps$dispersion_ranef, simulate = FALSE ) ## lmer MLE vs ICM posterior mean (no MCMC means when simulate = FALSE). lmebayes:::print_coef_means(fit) print(fit) summary(fit) }## lmerb: school random effects on bayesrules::big_word_club ## ## Random intercept and distracted_ppvt random slope by school; the school's ## share of free/reduced-lunch students (free_reduced_lunch, constant within ## school) is a level-2 predictor of the school intercepts. ## ## Fast man-page example: prior setup, lmer reference fit, and ICM posterior ## mean only (simulate = FALSE). No Gibbs draws — suitable for R CMD check. ## ## The full sampling workflows are preserved as demos: ## demo("Ex_14_lmerb_Sleepstudy", package = "lmebayes") # lme4-style small model ## demo("Ex_12_lmerb_BigWordClub", package = "lmebayes") # full formula if (requireNamespace("bayesrules", quietly = TRUE)) { data(big_word_club, package = "bayesrules") dat <- big_word_club dat$school_id <- factor(dat$school_id) dat <- subset(dat, !is.na(score_ppvt) & !is.na(invalid_ppvt) & invalid_ppvt == 0L) dat <- dat[complete.cases(dat[, c("score_ppvt", "distracted_ppvt", "free_reduced_lunch", "school_id")]), ] form <- score_ppvt ~ free_reduced_lunch + distracted_ppvt + (1 + distracted_ppvt || school_id) ## Default hyperpriors calibrated from a reference lmer fit (weak prior). ps <- Prior_Setup_lmebayes(form, data = dat, pwt = 0.01) fit <- lmerb( form, data = dat, pfamily_list = pfamily_list(ps), dispersion_ranef = ps$dispersion_ranef, simulate = FALSE ) ## lmer MLE vs ICM posterior mean (no MCMC means when simulate = FALSE). lmebayes:::print_coef_means(fit) print(fit) summary(fit) }
lmer/glmer gate)Wrapper around lmer or glmer for
models with exactly one grouping factor. Design matrices come from
formula (including cross-level RE moderation terms). Variance
components use vcov_formula (defaults to
lmerb_default_vcov_formula): level-2 fixed only, same
|| random structure as formula, without cross-level fixed
interactions (so RE moderation is not double-coded).
model_setup( formula, data = NULL, vcov_formula = NULL, family = gaussian(), REML = TRUE, control = NULL, start = NULL, verbose = 0L, subset, weights, na.action, offset, contrasts = NULL, devFunOnly = FALSE, fit_mer = TRUE, ... )model_setup( formula, data = NULL, vcov_formula = NULL, family = gaussian(), REML = TRUE, control = NULL, start = NULL, verbose = 0L, subset, weights, na.action, offset, contrasts = NULL, devFunOnly = FALSE, fit_mer = TRUE, ... )
formula |
Mixed-model formula for design extraction and the reference
|
data |
Optional data frame. |
vcov_formula |
Optional formula for the reference fit used to extract
|
family |
A |
REML |
Logical; passed to |
control |
|
start |
Optional starting values for the inner optimization. |
verbose |
Passed to |
subset, weights, na.action, offset, contrasts
|
Passed to
|
devFunOnly |
If |
fit_mer |
If |
... |
Passed to design extraction and, when |
Uncorrelated random effects (||).
The sampler treats Sigma_ranef as diagonal (no off-diagonal
covariance). Multi-coefficient random terms must use ||, e.g.
(1 + x || group) rather than (1 + x | group). A single
random intercept may use (1 | group); (1 || group) is not
supported by lme4.
Fixed-effect constraints.
model_setup accepts the same formula language as
lmer, subject to one structural rule: every fixed
effect that does not correspond to a random-slope term must be a
group-constant (level-2) covariate—a predictor whose value is the
same for every observation within a given group. School-level attributes
such as private_school or title1 satisfy this constraint.
Student-level covariates that vary within groups may appear as fixed
main effects only when they also appear as random slopes (they then
represent the population mean slope , e.g.,
distracted_ppvt). Cross-level interactions of the form
level2_var:random_slope (e.g.,
free_reduced_lunch:distracted_a1) are additionally permitted; they
moderate the prior mean of the corresponding random slope across groups (see
extract_re_hyper_matrices). Fixed terms that are none of
these three types—level-2 covariate, population mean slope, or cross-level
moderation interaction—are rejected with an informative error.
Two-step identifiability assessment.
After fitting lmer, model_setup performs a two-step rank
check that assesses whether the model is empirically identified at both the
within-group and across-group levels:
Level 1 (within-group): For each group , the
within-group random-effects design submatrix is
checked for full column rank (re_rank). A rank-deficient group
has too few distinct observations to estimate all random slopes
independently; its BLUPs are identified through the prior rather than
the data alone. Such groups are flagged in re_rank but are
retained in the lmer fit; Prior_Setup_lmebayes
excludes them when calibrating priors.
Level 2 (across-group): Restricting to the full-rank groups
from Step 1, each hyper-design matrix X_hyper[[k]] is checked
for full column rank (hyper_rank). Rank deficiency at this level
means the level-2 hyperparameters —the prior
means for random-effect coefficient across groups—are not
identified by the data, even as the number of full-rank groups grows.
The scalar rank_ok is TRUE only when every
X_hyper[[k]] is full-rank after Step 2. This is a necessary
condition for Prior_Setup_lmebayes to derive default priors
automatically; models with rank_ok = FALSE require user-supplied
hyperpriors.
The example uses big_word_club from the Suggested package
bayesrules (see ?bayesrules::big_word_club) and the same
formula as the full lmerb demo
(demo("Ex_12_lmerb_BigWordClub", package = "lmebayes")).
Object of class "model_setup": y, Z,
groups, X_hyper, formula, family,
vcov_formula, lmer_fit / glmer_fit (full formula),
matching lmer_vcov_fit / glmer_vcov_fit, varcorr,
vcov_re, residual_var, and re_rank (named logical
vector: TRUE if Z_j is full column rank for that group).
extract_re_hyper_matrices,
lmerb_default_vcov_formula,
extract_lmer_variance_components
## model_setup() on bayesrules::big_word_club ## ## Same model as the full lmerb demo, demo/Ex_12_lmerb_BigWordClub.R (see ## also Prior_Setup_lmebayes / lmerb development scripts in data-raw/). ## ## Level 1 (students): ## y ~ b0[j] + b_ppvt[j]*distracted_ppvt + b_a1[j]*distracted_a1 ## ## Level 2 (schools): ## b0[j] ~ private_school + title1 + free_reduced_lunch + u0[j] ## b_ppvt[j] ~ 1 + u_ppvt[j] ## b_a1[j] ~ 1 + free_reduced_lunch + u_a1[j] ## (cross-level: free_reduced_lunch:distracted_a1 in formula) ## ## Each random slope has a matching fixed main effect (required for ## Prior_Setup_lmebayes() default calibration). data(big_word_club, package = "bayesrules") dat <- big_word_club dat$school_id <- factor(dat$school_id) dat <- subset( dat, !is.na(score_ppvt) & !is.na(invalid_ppvt) & invalid_ppvt == 0L & complete.cases(dat[, c( "score_ppvt", "distracted_a1", "distracted_ppvt", "private_school", "title1", "free_reduced_lunch", "school_id" )]) ) form_lmer <- score_ppvt ~ private_school + title1 + free_reduced_lunch + distracted_a1 + distracted_ppvt + free_reduced_lunch:distracted_a1 + (1 + distracted_ppvt + distracted_a1 || school_id) ctrl_bobyqa <- lme4::lmerControl(optimizer = "bobyqa", optCtrl = list(maxfun = 2e5)) ## --------------------------------------------------------------------------- ## 1. lmer fit: raw output ## --------------------------------------------------------------------------- cat("--- lmer fit ---\n") fit <- lme4::lmer(form_lmer, data = dat, control = ctrl_bobyqa) print(summary(fit)) cat("\n--- fixef(fit): population-level (gamma) estimates ---\n") print(lme4::fixef(fit)) cat("\n--- coef(fit): per-group coefficients (fixef + ranef) ---\n") print(coef(fit)) ## --------------------------------------------------------------------------- ## 2. model_setup: structured view of the same model ## --------------------------------------------------------------------------- design <- model_setup(form_lmer, data = dat, control = ctrl_bobyqa) print(design) ## --------------------------------------------------------------------------- ## 3. Random effects b[j]: first 10 schools ## --------------------------------------------------------------------------- cat("--- Random effects b[j]: first 10", design$group_name, "---\n") re_df <- as.data.frame(lme4::ranef(design$lmer_fit)[[design$group_name]]) print(utils::head(re_df, 10)) ## --------------------------------------------------------------------------- ## 4. Gamma estimates organised to match the Random Effects Model above ## ## Mapping (intercept RE): X_hyper columns map directly to fixef() names. ## Mapping (slope RE, hyper ~ 1): (Intercept) column -> fixef[slope_name]. ## --------------------------------------------------------------------------- cat("\n--- Random effects model (gamma estimates) ---\n") fe <- lme4::fixef(design$lmer_fit) coef_df <- coef(design$lmer_fit)[[design$group_name]] coef_means <- colMeans(coef_df) coef_vars <- apply(coef_df, 2L, var) coef_sds <- sqrt(coef_vars) w <- max(nchar(design$re_coef_names)) for (nm in design$re_coef_names) { Xj <- design$X_hyper[[nm]] other <- setdiff(colnames(Xj), "(Intercept)") hyper_rhs <- if (length(other) == 0L) "1" else paste(c("1", other), collapse = " + ") gamma <- setNames( vapply(colnames(Xj), function(col) { if (nm == "(Intercept)") { if (col %in% names(fe)) unname(fe[col]) else 0 } else if (col == "(Intercept)") { if (nm %in% names(fe)) unname(fe[nm]) else unname(coef_means[nm]) } else { cand <- c(paste0(col, ":", nm), paste0(nm, ":", col)) hit <- cand[cand %in% names(fe)] if (length(hit)) unname(fe[hit[1L]]) else 0 } }, numeric(1L)), colnames(Xj) ) cat(sprintf(" %-*s ~ %s\n", w, nm, hyper_rhs)) print(gamma) cat("\n") } ## --------------------------------------------------------------------------- ## 5. Empirical SD/variance of per-school coefficients vs lmer VarCorr ## --------------------------------------------------------------------------- cat("--- Between-school SD of random coefficients vs lmer VarCorr ---\n") vc <- as.data.frame(lme4::VarCorr(design$lmer_fit)) cat(sprintf(" %-16s empirical_sd=%7.4f empirical_var=%8.4f lmer_sd=%7.4f lmer_var=%8.4f\n", "(Intercept)", coef_sds["(Intercept)"], coef_vars["(Intercept)"], vc$sdcor[vc$var1 == "(Intercept)" & is.na(vc$var2)][1L], vc$vcov[vc$var1 == "(Intercept)" & is.na(vc$var2)][1L])) for (nm in setdiff(design$re_coef_names, "(Intercept)")) { if (!nm %in% colnames(coef_df)) next lmer_row <- vc[vc$var1 == nm & is.na(vc$var2), ] cat(sprintf(" %-16s empirical_sd=%7.4f empirical_var=%8.4f lmer_sd=%7.4f lmer_var=%8.4f\n", nm, coef_sds[nm], coef_vars[nm], if (nrow(lmer_row)) lmer_row$sdcor[1L] else NA_real_, if (nrow(lmer_row)) lmer_row$vcov[1L] else NA_real_)) } ## --------------------------------------------------------------------------- ## 6. lmer refitted on full-rank schools only (same subset as Prior_Setup) ## --------------------------------------------------------------------------- cat("\n--- lmer refit: full-rank schools only ---\n") full_rank_schools <- names(design$re_rank)[design$re_rank] cat(sprintf(" Using %d of %d schools (dropping rank-deficient: %s)\n\n", length(full_rank_schools), nlevels(design$groups), paste(names(design$re_rank)[!design$re_rank], collapse = ", "))) dat_fr <- subset(dat, school_id %in% full_rank_schools) dat_fr$school_id <- droplevels(dat_fr$school_id) fit_fr <- lme4::lmer(form_lmer, data = dat_fr, control = ctrl_bobyqa) print(summary(fit_fr)) cat("\n--- VarCorr comparison: all schools vs full-rank schools only ---\n") vc_fr <- as.data.frame(lme4::VarCorr(fit_fr)) cat(sprintf(" %-16s all_schools_sd=%7.4f full_rank_sd=%7.4f\n", "(Intercept)", vc$sdcor[vc$var1 == "(Intercept)" & is.na(vc$var2)][1L], vc_fr$sdcor[vc_fr$var1 == "(Intercept)" & is.na(vc_fr$var2)][1L])) for (nm in setdiff(design$re_coef_names, "(Intercept)")) { row_all <- vc[vc$var1 == nm & is.na(vc$var2), ] row_fr <- vc_fr[vc_fr$var1 == nm & is.na(vc_fr$var2), ] cat(sprintf(" %-16s all_schools_sd=%7.4f full_rank_sd=%7.4f\n", nm, if (nrow(row_all)) row_all$sdcor[1L] else NA_real_, if (nrow(row_fr)) row_fr$sdcor[1L] else NA_real_)) } ## =========================================================================== ## 7. Optional stress test (NOT the lmerb example model): esl_observed RE ## =========================================================================== cat("\n\n=== Section 7 (optional): esl_observed added as random slope ===\n\n") dat_esl <- subset( dat, complete.cases(dat[, c("esl_observed")]) ) form_esl <- score_ppvt ~ private_school + title1 + free_reduced_lunch + distracted_a1 + distracted_ppvt + free_reduced_lunch:distracted_a1 + esl_observed + (1 + distracted_ppvt + distracted_a1 + esl_observed || school_id) design_esl <- model_setup(form_esl, data = dat_esl, control = ctrl_bobyqa) print(design_esl)## model_setup() on bayesrules::big_word_club ## ## Same model as the full lmerb demo, demo/Ex_12_lmerb_BigWordClub.R (see ## also Prior_Setup_lmebayes / lmerb development scripts in data-raw/). ## ## Level 1 (students): ## y ~ b0[j] + b_ppvt[j]*distracted_ppvt + b_a1[j]*distracted_a1 ## ## Level 2 (schools): ## b0[j] ~ private_school + title1 + free_reduced_lunch + u0[j] ## b_ppvt[j] ~ 1 + u_ppvt[j] ## b_a1[j] ~ 1 + free_reduced_lunch + u_a1[j] ## (cross-level: free_reduced_lunch:distracted_a1 in formula) ## ## Each random slope has a matching fixed main effect (required for ## Prior_Setup_lmebayes() default calibration). data(big_word_club, package = "bayesrules") dat <- big_word_club dat$school_id <- factor(dat$school_id) dat <- subset( dat, !is.na(score_ppvt) & !is.na(invalid_ppvt) & invalid_ppvt == 0L & complete.cases(dat[, c( "score_ppvt", "distracted_a1", "distracted_ppvt", "private_school", "title1", "free_reduced_lunch", "school_id" )]) ) form_lmer <- score_ppvt ~ private_school + title1 + free_reduced_lunch + distracted_a1 + distracted_ppvt + free_reduced_lunch:distracted_a1 + (1 + distracted_ppvt + distracted_a1 || school_id) ctrl_bobyqa <- lme4::lmerControl(optimizer = "bobyqa", optCtrl = list(maxfun = 2e5)) ## --------------------------------------------------------------------------- ## 1. lmer fit: raw output ## --------------------------------------------------------------------------- cat("--- lmer fit ---\n") fit <- lme4::lmer(form_lmer, data = dat, control = ctrl_bobyqa) print(summary(fit)) cat("\n--- fixef(fit): population-level (gamma) estimates ---\n") print(lme4::fixef(fit)) cat("\n--- coef(fit): per-group coefficients (fixef + ranef) ---\n") print(coef(fit)) ## --------------------------------------------------------------------------- ## 2. model_setup: structured view of the same model ## --------------------------------------------------------------------------- design <- model_setup(form_lmer, data = dat, control = ctrl_bobyqa) print(design) ## --------------------------------------------------------------------------- ## 3. Random effects b[j]: first 10 schools ## --------------------------------------------------------------------------- cat("--- Random effects b[j]: first 10", design$group_name, "---\n") re_df <- as.data.frame(lme4::ranef(design$lmer_fit)[[design$group_name]]) print(utils::head(re_df, 10)) ## --------------------------------------------------------------------------- ## 4. Gamma estimates organised to match the Random Effects Model above ## ## Mapping (intercept RE): X_hyper columns map directly to fixef() names. ## Mapping (slope RE, hyper ~ 1): (Intercept) column -> fixef[slope_name]. ## --------------------------------------------------------------------------- cat("\n--- Random effects model (gamma estimates) ---\n") fe <- lme4::fixef(design$lmer_fit) coef_df <- coef(design$lmer_fit)[[design$group_name]] coef_means <- colMeans(coef_df) coef_vars <- apply(coef_df, 2L, var) coef_sds <- sqrt(coef_vars) w <- max(nchar(design$re_coef_names)) for (nm in design$re_coef_names) { Xj <- design$X_hyper[[nm]] other <- setdiff(colnames(Xj), "(Intercept)") hyper_rhs <- if (length(other) == 0L) "1" else paste(c("1", other), collapse = " + ") gamma <- setNames( vapply(colnames(Xj), function(col) { if (nm == "(Intercept)") { if (col %in% names(fe)) unname(fe[col]) else 0 } else if (col == "(Intercept)") { if (nm %in% names(fe)) unname(fe[nm]) else unname(coef_means[nm]) } else { cand <- c(paste0(col, ":", nm), paste0(nm, ":", col)) hit <- cand[cand %in% names(fe)] if (length(hit)) unname(fe[hit[1L]]) else 0 } }, numeric(1L)), colnames(Xj) ) cat(sprintf(" %-*s ~ %s\n", w, nm, hyper_rhs)) print(gamma) cat("\n") } ## --------------------------------------------------------------------------- ## 5. Empirical SD/variance of per-school coefficients vs lmer VarCorr ## --------------------------------------------------------------------------- cat("--- Between-school SD of random coefficients vs lmer VarCorr ---\n") vc <- as.data.frame(lme4::VarCorr(design$lmer_fit)) cat(sprintf(" %-16s empirical_sd=%7.4f empirical_var=%8.4f lmer_sd=%7.4f lmer_var=%8.4f\n", "(Intercept)", coef_sds["(Intercept)"], coef_vars["(Intercept)"], vc$sdcor[vc$var1 == "(Intercept)" & is.na(vc$var2)][1L], vc$vcov[vc$var1 == "(Intercept)" & is.na(vc$var2)][1L])) for (nm in setdiff(design$re_coef_names, "(Intercept)")) { if (!nm %in% colnames(coef_df)) next lmer_row <- vc[vc$var1 == nm & is.na(vc$var2), ] cat(sprintf(" %-16s empirical_sd=%7.4f empirical_var=%8.4f lmer_sd=%7.4f lmer_var=%8.4f\n", nm, coef_sds[nm], coef_vars[nm], if (nrow(lmer_row)) lmer_row$sdcor[1L] else NA_real_, if (nrow(lmer_row)) lmer_row$vcov[1L] else NA_real_)) } ## --------------------------------------------------------------------------- ## 6. lmer refitted on full-rank schools only (same subset as Prior_Setup) ## --------------------------------------------------------------------------- cat("\n--- lmer refit: full-rank schools only ---\n") full_rank_schools <- names(design$re_rank)[design$re_rank] cat(sprintf(" Using %d of %d schools (dropping rank-deficient: %s)\n\n", length(full_rank_schools), nlevels(design$groups), paste(names(design$re_rank)[!design$re_rank], collapse = ", "))) dat_fr <- subset(dat, school_id %in% full_rank_schools) dat_fr$school_id <- droplevels(dat_fr$school_id) fit_fr <- lme4::lmer(form_lmer, data = dat_fr, control = ctrl_bobyqa) print(summary(fit_fr)) cat("\n--- VarCorr comparison: all schools vs full-rank schools only ---\n") vc_fr <- as.data.frame(lme4::VarCorr(fit_fr)) cat(sprintf(" %-16s all_schools_sd=%7.4f full_rank_sd=%7.4f\n", "(Intercept)", vc$sdcor[vc$var1 == "(Intercept)" & is.na(vc$var2)][1L], vc_fr$sdcor[vc_fr$var1 == "(Intercept)" & is.na(vc_fr$var2)][1L])) for (nm in setdiff(design$re_coef_names, "(Intercept)")) { row_all <- vc[vc$var1 == nm & is.na(vc$var2), ] row_fr <- vc_fr[vc_fr$var1 == nm & is.na(vc_fr$var2), ] cat(sprintf(" %-16s all_schools_sd=%7.4f full_rank_sd=%7.4f\n", nm, if (nrow(row_all)) row_all$sdcor[1L] else NA_real_, if (nrow(row_fr)) row_fr$sdcor[1L] else NA_real_)) } ## =========================================================================== ## 7. Optional stress test (NOT the lmerb example model): esl_observed RE ## =========================================================================== cat("\n\n=== Section 7 (optional): esl_observed added as random slope ===\n\n") dat_esl <- subset( dat, complete.cases(dat[, c("esl_observed")]) ) form_esl <- score_ppvt ~ private_school + title1 + free_reduced_lunch + distracted_a1 + distracted_ppvt + free_reduced_lunch:distracted_a1 + esl_observed + (1 + distracted_ppvt + distracted_a1 + esl_observed || school_id) design_esl <- model_setup(form_esl, data = dat_esl, control = ctrl_bobyqa) print(design_esl)
Prior family objects provide a convenient way to specify the details of the priors
used by matrix-input samplers such as rglmb and rlmb. See the documentation for
rglmb and rlmb for the details of how such model fitting
takes place.
Under a Beta(shape1, shape2) prior on the binomial probability
and a Binomial(, ) likelihood with identity link (
directly), the posterior is:
dNormal(mu, Sigma, dispersion = NULL) dNormal_Gamma(mu, Sigma_0, shape, rate) dIndependent_Normal_Gamma( mu, Sigma, shape, rate, max_disp_perc = 0.99, disp_lower = NULL, disp_upper = NULL ) dGamma( shape, rate, beta, Inv_Dispersion = TRUE, lik_shape = 1, max_disp_perc = 0.99, disp_lower = NULL, disp_upper = NULL )dNormal(mu, Sigma, dispersion = NULL) dNormal_Gamma(mu, Sigma_0, shape, rate) dIndependent_Normal_Gamma( mu, Sigma, shape, rate, max_disp_perc = 0.99, disp_lower = NULL, disp_upper = NULL ) dGamma( shape, rate, beta, Inv_Dispersion = TRUE, lik_shape = 1, max_disp_perc = 0.99, disp_lower = NULL, disp_upper = NULL )
mu |
a prior mean vector for the the modeling coefficients used in several pfamilies |
Sigma |
a prior variance-covariance matrix for |
dispersion |
the dispersion to be assumed when it is not given a prior. Should be provided
when the Normal prior is for the |
Sigma_0 |
prior variance-covariance on the precision-weighted coefficient scale for
|
shape |
The prior shape parameter for the gamma piece (inverse dispersion / precision).
When taking defaults from |
rate |
The prior rate parameter paired with |
max_disp_perc |
Specifies the percentile used to truncate the posterior dispersion
distribution when constructing the envelope for accept-reject sampling. This determines
the lower and upper bounds for the dispersion ( |
disp_lower |
lower bound truncation for dispersion |
disp_upper |
upper bound truncation for dispersion |
beta |
Initial coefficient matrix (1 |
Inv_Dispersion |
Logical (default
|
lik_shape |
Known shape parameter |
pfamily is a generic with methods for fitted objects such as rglmb and
rlmb. The dNormal() prior is supported for all response families.
The gaussian() family additionally supports dNormal_Gamma(),
dIndependent_Normal_Gamma(), and dGamma() (precision prior).
Intercept-only models with an identity link support two closed-form conjugate priors:
dBeta() for binomial(link = "identity") and
dGamma(Inv_Dispersion = FALSE) for poisson(link = "identity") and
Gamma(link = "identity").
A pfamily object represents a structured prior specification for use in Bayesian generalized linear modeling.
Each constructor function (e.g., dNormal(), dGamma(), dNormal_Gamma(), dBeta()) returns an object of
class "pfamily" containing the prior parameters, supported likelihood families, compatible link functions,
and a simulation function for posterior sampling.
These priors are designed to integrate seamlessly with modeling functions such as rglmb() and rlmb() in the
glmbayes package, which consume the pfamily object to define the prior distribution over model parameters.
The pfamily() generic retrieves the embedded prior from a fitted model object, while print.pfamily() displays its structure.
prior_list and simfun. The named list prior_list holds the hyperparameters for the chosen
prior family. When a model function draws from the posterior, it passes prior_list into the element
simfun (e.g., rNormal_reg, rGamma_reg) so the low-level sampler receives
one consistent list structure regardless of which constructor built the pfamily.
Prior_Setup and default hyperparameters. Prior_Setup() fits an auxiliary GLM and returns
default mu, Sigma / Sigma_0, dispersion, Gamma shape and rate, and
related fields aligned with the data and prior-weight (pwt) choices. Those values can be supplied as
arguments to the pfamily constructors when you want package-default priors on the same scale as the model
matrix. Recommended use of shape and rate is not identical across constructors: for
dIndependent_Normal_Gamma(), pass shape = ps$shape_ING from Prior_Setup (not the
scalar ps$shape used by dNormal_Gamma()). For dGamma() with fixed coefficients
(beta), pass rate = ps$rate_gamma when that field is present (otherwise ps$rate); see
Prior_Setup and compute_gaussian_prior.
dNormal(): Specifies a multivariate normal prior over regression coefficients. It is conjugate for
Gaussian likelihoods with an identity link function, and serves as the primary implemented prior for all
other supported likelihood families in the current framework. This structure facilitates efficient posterior
sampling and analytical tractability. The returned prior_list includes ddef: TRUE when
dispersion was omitted or NULL (so the default 1 was used), FALSE when
dispersion was supplied explicitly (including 1).
For models with log-concave likelihood functions-such as Poisson, Binomial, and Gamma families-
posterior sampling under a dNormal prior is performed using a (Nygren and Nygren 2006)
likelihood subgradient approach. This method constructs tight enveloping functions around the posterior
using subgradients of the log-likelihood, enabling efficient accept-reject sampling even in high dimensions.
When the posterior distribution is approximately normal (typically the case for large sample sizes), the
area under the enveloping function is bounded above by a constant factor-approximately
in the univariate case, and in -dimensional models. These bounds ensure that
the rejection rate remains manageable and that the sampler remains computationally efficient.
The concept of conjugate priors was first formalized by (Raiffa and Schlaifer 1961), and further developed for regression models using g-prior structures by (Zellner 1986).
dGamma(): A Gamma prior with two distinct roles controlled by Inv_Dispersion:
Inv_Dispersion = TRUE (default): prior on the inverse dispersion (precision
or shape ). Used for dispersion estimation in Gaussian and
Gamma(log) models, typically in a Gibbs step with beta held fixed
(Gelman et al. 2013; Dobson 1990; McCullagh and Nelder 1989).
With Gaussian Prior_Setup output, prefer rate_gamma for rate
(see Details above).
Inv_Dispersion = FALSE: conjugate Gamma prior on the rate parameter
directly. Supports intercept-only models with an identity link:
Poisson (Gamma–Poisson conjugacy) and Gamma (Gamma–Gamma conjugacy).
Posterior draws are closed-form IID samples via rGamma_Conjugate_reg.
The lik_shape argument specifies the known Gamma likelihood shape (default 1,
i.e.\ exponential). Prior_Setup returns calibrated conj_poisson
hyperparameters for this path.
dBeta(): A Beta prior on the binomial probability for intercept-only
binomial(link = "identity") models. The posterior is a closed-form Beta draw
(Beta–Binomial conjugacy) produced by rBeta_reg. Arguments shape1
and shape2 are the prior pseudo-success and pseudo-failure counts.
Prior_Setup returns calibrated conj_beta hyperparameters for this path.
dNormal_Gamma(): Combines a multivariate normal prior on coefficients with a gamma prior on precision,
forming a conjugate structure for Gaussian models with unknown variance. The second argument is Sigma_0
(precision-weighted scale); it is aliased internally to Sigma in prior_list.
This formulation parallels classical Normal-Gamma models and is compatible with hierarchical extensions
(Gelman et al. 2013; Raiffa and Schlaifer 1961).
dIndependent_Normal_Gamma(): Similar to dNormal_Gamma(), but assumes independence between the
coefficient and precision priors. This structure is useful for models where prior independence is desired
or analytically convenient. With Prior_Setup on a Gaussian model, pass shape_ING as
the shape argument (see Details above).
Each pfamily object includes:
pfamily, prior_list, okfamilies, plinks, and simfun (see Value).
mu / Sigma: the surrogate Normal mean is shape1/(shape1+shape2) and
the surrogate variance is the Beta variance
shape1*shape2/((shape1+shape2)^2*(shape1+shape2+1)).
An object of class "pfamily" (with a concise print method). A list with elements:
pfamily |
Character string: the constructor name ( |
prior_list |
Named list of prior hyperparameters. It is passed into
|
okfamilies |
Character vector of implemented |
plinks |
Function of one |
simfun |
Function used to generate posterior draws (e.g., |
Dobson A~J (1990).
An Introduction to Generalized Linear Models.
Chapman and Hall, London.
Gelman A, Carlin JB, Stern HS, Dunson DB, Vehtari A, Rubin DB (2013).
Bayesian Data Analysis, 3rd edition.
CRC Press.
McCullagh P, Nelder J~A (1989).
Generalized Linear Models.
Chapman and Hall, London.
Nygren K~N, Nygren L~M (2006).
“Likelihood Subgradient Densities.”
Journal of the American Statistical Association, 101(475), 1144–1156.
doi:10.1198/016214506000000357.
Raiffa H, Schlaifer R (1961).
Applied Statistical Decision Theory.
Clinton Press, Inc., Boston.
Zellner A (1986).
“On Assessing Prior Distributions and Bayesian Regression Analysis with g‐Prior Distributions.”
In Goel P~K, Zellner A (eds.), Bayesian Inference and Decision Techniques: Essays in Honor of Bruno de Finetti, volume 6 of Studies in Bayesian Econometrics and Statistics, 233–243.
Elsevier.
rglmb, rlmb for modeling functions that consume pfamily objects.
rNormal_reg, rNormalGamma_reg, rGamma_reg, rGamma_Conjugate_reg, rindepNormalGamma_reg for lower-level sampling functions used by pfamily constructors.
Prior_Setup, Prior_Check for initializing and validating prior specifications.
EnvelopeBuild for envelope construction methods used in likelihood subgradient sampling (Nygren and Nygren 2006).
See also (Hastie and Pregibon 1992) for the original S modeling framework that inspired the design of pfamily.
Converts the per-component Block-2 hyperprior parameters stored in a
Prior_Setup_lmebayes object into a named list of
pfamily objects, one per random-effect
coefficient (e.g. "(Intercept)", slope names).
## S3 method for class 'lmebayes_prior_setup' pfamily_list(object, ptypes = "dNormal", ...)## S3 method for class 'lmebayes_prior_setup' pfamily_list(object, ptypes = "dNormal", ...)
object |
An object of class |
ptypes |
Character: either a single string applied to every
random-effect component, or a character vector / list with one
string per component. Allowed values are |
... |
Currently ignored. |
For each random-effect coefficient , the prior parameters come
from object$prior_list[[k]]:
"dNormal": dNormal(mu = mu_fixef, Sigma =
Sigma_fixef, dispersion = dispersion_fixef). The Block-2
dispersion (the random-effect variance ) is treated
as known.
"dIndependent_Normal_Gamma": the same mu and
Sigma, plus a Gamma prior on the Block-2 precision
calibrated with the same convention as
Prior_Setup. The per-component
effective prior sample size is taken from
object$n_prior_dispersion[[k]] (set by
Prior_Setup_lmebayes via pwt_dispersion /
n_prior_dispersion, derived from pwt by default).
Then
where is the number of Block-2 coefficients for
component (the shape_ING convention with the
glmbayesCore default rate ). Because
, the implied inverse-Gamma prior
on the dispersion has mean exactly for every
and , while small pwt_dispersion keeps it
deliberately diffuse.
The dispersion prior must not outweigh the data: \eqn{n_0 \le J}
(equivalently \code{pwt_dispersion} \eqn{\le 0.5}) is required,
mirroring the sampler-side guard in
\code{\link[glmbayesCore]{two_block_rNormal_reg_v2}} (the ING
dispersion envelope caps its log-tilt at the data contribution
\eqn{J/2}; a prior-dominated calibration would invalidate it).
\code{disp_lower} and \code{disp_upper} default to the 0.01 and
0.99 quantiles of the \emph{limiting posterior} for \eqn{\tau^2_k}
-- the weak-prior (\eqn{n_0 \to 0}) limit of the Block-2 posterior
Gamma for the precision (glmbayesCore Chapter A12, Theorem 2),
\eqn{\Gamma(a_\infty, b_\infty)} with
\deqn{a_\infty = (J+1)/2, \qquad b_\infty = \tau^2_k\,(J-1)/2,}
inverted to a \eqn{\tau^2} interval:
\deqn{disp\_lower = 1 / q_{\Gamma}(0.99;\; a_\infty, b_\infty),
\qquad
disp\_upper = 1 / q_{\Gamma}(0.01;\; a_\infty, b_\infty).}
Quantiles of the limiting posterior -- rather than of the prior --
make the window independent of \eqn{n_0}: prior quantiles stretch
without bound as the dispersion prior weakens (collapsing the
envelope acceptance rate), whereas this window covers at least
~98\% of the exact posterior for every \eqn{n_0} (the finite-
\eqn{n_0} posterior is strictly more concentrated than the limit)
and keeps sampling cost stable. See
\code{inst/ING_TRUNCATION_WINDOW.md} for the derivation. The
values are computed once by \code{\link{Prior_Setup_lmebayes}}
(stored in its \code{ing_prior} field and shown by its print
method); this function reads them from the object. During
sampling each \eqn{\tau^2_k} draw is hard-truncated to this window
(renormalized inverse-CDF), and because both bounds are supplied
the window is \emph{fixed} across all inner Gibbs sweeps, rather
than re-derived per sweep from a surrogate posterior.
\code{\link{lmerb}} and \code{\link{glmerb}} use \code{disp_lower}
as the conservative \eqn{\tau^2_k} plug-in for their eigenvalue /
TV convergence calibration, so the resulting bound holds over the
chain's entire (truncated) dispersion support.
A named list of "pfamily" objects, with names equal to
names(object$prior_list) (the random-effect coefficient
names).
Prior_Setup_lmebayes,
dNormal,
dIndependent_Normal_Gamma
if (requireNamespace("bayesrules", quietly = TRUE)) { data(big_word_club, package = "bayesrules") dat <- big_word_club dat$school_id <- factor(dat$school_id) dat <- subset(dat, !is.na(score_ppvt)) ps <- Prior_Setup_lmebayes( score_ppvt ~ private_school + (1 | school_id), data = dat ) ## All components as dNormal (known Block-2 dispersion) pf1 <- pfamily_list(ps) print(pf1[["(Intercept)"]]) ## All components with a Gamma prior on the Block-2 precision pf2 <- pfamily_list(ps, ptypes = "dIndependent_Normal_Gamma") }if (requireNamespace("bayesrules", quietly = TRUE)) { data(big_word_club, package = "bayesrules") dat <- big_word_club dat$school_id <- factor(dat$school_id) dat <- subset(dat, !is.na(score_ppvt)) ps <- Prior_Setup_lmebayes( score_ppvt ~ private_school + (1 | school_id), data = dat ) ## All components as dNormal (known Block-2 dispersion) pf1 <- pfamily_list(ps) print(pf1[["(Intercept)"]]) ## All components with a Gamma prior on the Block-2 precision pf2 <- pfamily_list(ps, ptypes = "dIndependent_Normal_Gamma") }
Helper function to facilitate the Setup of Prior Distributions for glm models.
Prior_Setup( formula, family = gaussian(), data = NULL, weights = NULL, subset = NULL, na.action = na.fail, offset = NULL, contrasts = NULL, pwt = NULL, pwt_default_low = 0.01, pwt_default_high = 0.05, n_prior = NULL, sd = NULL, dispersion = NULL, intercept_source = c("null_model", "full_model"), effects_source = c("null_effects", "full_model"), mu = NULL, k = 1, ... )Prior_Setup( formula, family = gaussian(), data = NULL, weights = NULL, subset = NULL, na.action = na.fail, offset = NULL, contrasts = NULL, pwt = NULL, pwt_default_low = 0.01, pwt_default_high = 0.05, n_prior = NULL, sd = NULL, dispersion = NULL, intercept_source = c("null_model", "full_model"), effects_source = c("null_effects", "full_model"), mu = NULL, k = 1, ... )
formula |
an object of class |
family |
a description of the error distribution and link function to be used in the model. |
data |
an optional data frame, list or environment (or object
coercible by |
weights |
an optional vector of ‘prior weights’ to be used
in the fitting process. Should be |
subset |
an optional vector specifying a subset of observations to be used in the fitting process. (See additional details about how this argument interacts with data-dependent bases in the ‘Details’ below.) |
na.action |
how |
offset |
this can be used to specify an a priori known
component to be included in the linear predictor during fitting.
This should be |
contrasts |
an optional list. See the |
pwt |
Weight on the prior relative to the likelihood function at the maximum likelihood
estimate. If supplied, this value is used directly (scalar or one value per coefficient).
If |
pwt_default_low |
Default prior weight used when |
pwt_default_high |
Default prior weight used when |
n_prior |
Optional scalar effective prior sample size (on the |
sd |
Optional vector argument with the prior standard deviations for the coefficients |
dispersion |
Optional scalar dispersion override (default |
intercept_source |
Specifies the method through which the prior mean for the intercept term is set. Options are based on the null intercept only model (null_model) or full_models. The default is the null model which is safer if variables are not centered. |
effects_source |
Specifies the method through which the prior means for the effects terms are set. Options are null_effects (prior means set to zero) or full_model (effect means set to match maximum likelihood estimates). |
mu |
Optional vector argument with the prior means for the coefficients |
k |
Scalar (default |
... |
For For |
Inputs to the function
The inputs to Prior_Setup() fall into three conceptual categories:
1. Model specification
formula: structure of the GLM (response and predictors).
family: error distribution and link.
data, weights, subset, na.action,
offset, contrasts, control, ...: as in
glm.
2. Prior variance–covariance specification
pwt: prior weight relative to the likelihood. If scalar, used to
construct a Zellner-type g-prior. If vector, applied elementwise.
n_prior: optional scalar effective prior sample size. Replaces
scalar pwt only when pwt is scalar and sd is not
used; otherwise supplies precision-prior / calibration only.
sd: optional vector of prior standard deviations. If provided,
used to compute pwt from the diagonal of vcov(glm_full).
pwt_default_low, pwt_default_high: defaults for pwt
when not supplied.
3. Prior mean specification
intercept_source: method for setting the prior mean of the intercept
("null_model" or "full_model").
effects_source: method for setting the prior mean of the effects
("null_effects" or "full_model").
mu: optional user-specified prior mean vector; overrides other
centering logic if provided.
Prior covariance and Zellner scaling
Let be the covariance matrix of the
full-model GLM coefficients. For non-Gaussian families, the prior covariance
is:
where denotes elementwise multiplication.
Intercept-only Poisson(link = "identity") conjugate prior on the rate
When the design is a single column (intercept only), family = poisson(),
link = "identity", scalar pwt, and offsets are zero, the effective
conjugate prior observation count already satisfies
(otherwise conj_poisson remains NULL with a warning). Writing the
weighted mean , the output list
component conj_poisson stores
and , so the prior mean for the rate matches .
Omitting optional mu resets the surrogate Normal summaries mu and the
sole diagonal element of Sigma to these Gamma moments (Sigma_{11} =
).
For Gaussian families, Prior_Setup() also constructs the dispersion-free
covariance
which under scalar pwt and the default calibration reduces to
Gaussian Normal–Gamma calibration and
For family = gaussian(), the function performs the Normal–Gamma
calibration described in (Nygren 2025). Let:
,
,
the weighted least-squares estimator,
the dispersion-free prior covariance.
The marginal quadratic term is
where is the weighted residual sum of squares at
. Under the default scalar-pwt Zellner mapping
,
this simplifies to
which makes the limiting behavior as transparent.
The calibrated dispersion is
and the Normal–Gamma hyperparameters are
The independent Normal–Gamma shape is
Posterior summaries for the conjugate Normal–Gamma prior
Under the conjugate Normal–Gamma prior (used by dNormal_Gamma()),
the posterior has:
Posterior mean
Posterior expectation of
Posterior covariance
Weak-prior limits (Theorems 2 and 3)
As (equivalently ),
, and the conjugate Normal–Gamma
posterior converges to the classical weighted least-squares limit:
For the independent Normal–Gamma prior used by
dIndependent_Normal_Gamma(), neither the posterior mean nor the
posterior covariance is available in closed form; the posterior must be
obtained by numerical integration or sampling (e.g.,
rindepNormalGamma_reg()). Theorem 3 in
(Nygren 2025) shows that the ING posterior has
the same weak-prior limit as the conjugate Normal–Gamma posterior:
A list of class "PriorSetup" with components:
mu |
Prior mean vector (length equal to the number of coefficients). |
Sigma |
Coefficient-scale prior variance–covariance matrix. |
Sigma_0 |
For |
dispersion |
Calibrated dispersion (Gaussian models only), equal to
|
shape |
Derived prior Gamma shape parameter for the Normal–Gamma prior
on precision (Gaussian only), |
shape_ING |
For |
rate |
Derived prior Gamma rate parameter (Gaussian only), using the
calibrated |
rate_gamma |
For |
coefficients |
Named numeric vector of returned coefficient values.
For |
model |
The model frame used to construct the design matrix (if
|
x |
The model matrix used (if |
y |
The response vector used (if |
call |
The matched call to |
PriorSettings |
A list containing prior configuration details, including
|
conj_poisson |
|
Nygren K (2025). “Chapter A12: Technical Derivations for Priors Returned by Prior_ Setup.” Vignette in the glmbayes R package. R vignette name: Chapter-A12.
pfamily for prior-family objects and the constructors
dNormal, dNormal_Gamma, dGamma,
and dIndependent_Normal_Gamma.
rglmb, rlmb for matrix-input fits with a
pfamily built from Prior_Setup() output; rglmb,
rlmb for matrix-based sampling that consumes the same prior
structure; simfuncs for functions that take a prior_list
assembled from those components (including
rindepNormalGamma_reg for
dIndependent_Normal_Gamma()).
multi_prior_setup for a matrix/cbind response with Gaussian;
use with rlmb
Prior_Setup per column.
(Zellner 1986); (Raiffa and Schlaifer 1961); (Gelman et al. 2013); (McCullagh and Nelder 1989); (Nygren 2025); (Nygren 2025).
Other prior:
Prior_Check(),
multi_prior_setup()
## Not run: ## Full runnable examples are maintained in \pkg{glmbayesCore}: example(Prior_Setup, package = "glmbayesCore", ask = FALSE, echo = TRUE) ## End(Not run)## Not run: ## Full runnable examples are maintained in \pkg{glmbayesCore}: example(Prior_Setup, package = "glmbayesCore", ask = FALSE, echo = TRUE) ## End(Not run)
Calibrates priors for the level-2 fixed effects (fixef) of a
hierarchical mixed model using the reference lmer/glmer fits
on all groups (from model_setup). Per-group design
rank (re_rank) is a diagnostic check only and does not subset the
data. Random-effect variances are treated as fixed at their mixed-model
estimates. The returned object provides all inputs needed for the
two-block Gibbs sampler:
Prior_Setup_lmebayes( formula, data, family = gaussian(), pwt = 0.01, pwt_dispersion = NULL, n_prior_dispersion = NULL, intercept_source = c("null_model", "full_model"), effects_source = c("null_effects", "full_model") ) ## S3 method for class 'lmebayes_prior_setup' print(x, digits = 4L, ...)Prior_Setup_lmebayes( formula, data, family = gaussian(), pwt = 0.01, pwt_dispersion = NULL, n_prior_dispersion = NULL, intercept_source = c("null_model", "full_model"), effects_source = c("null_effects", "full_model") ) ## S3 method for class 'lmebayes_prior_setup' print(x, digits = 4L, ...)
formula |
Mixed-model formula passed to |
data |
Data frame containing all variables in |
family |
Model |
pwt |
Prior weight(s) in |
pwt_dispersion |
Optional relative prior weight(s) in
|
n_prior_dispersion |
Optional absolute effective prior sample
size(s) (in group units) for the Block~2 dispersion prior. A positive
scalar, or a list / numeric vector with one value per random-effect
component (named or positional). See |
intercept_source |
Character string controlling the prior mean for
intercept terms. One of |
effects_source |
Character string controlling the prior mean for
non-intercept fixed-effect terms. One of |
x |
Object of class |
digits |
Number of decimal places for numeric output. Default 4. |
... |
Ignored. |
Block 1 (per-group, independent):
when family = gaussian(). For non-Gaussian families there is no
observation-level dispersion; Block~1 uses dNormal with
ddef = TRUE (see dNormal).
Block 2 (per-RE coefficient , independent):
Why default calibration depends on classical estimates.
Prior_Setup_lmebayes anchors each Block~2 mean at the classical
mixed-model estimate and scales covariances from vcov(fit_ref) by
. This requires:
Every X_hyper[[k]] column maps to a fixef(fit_ref) term.
Each RE variance from fit_ref is strictly positive.
Object of class "lmebayes_prior_setup" with fields:
formulaModel formula.
familyFamily object.
pwtPrior weight(s) used: the scalar as supplied, or the canonical named list of per-predictor weight vectors when a list was supplied.
pwt_dispersionNamed per-component vector of relative
dispersion prior weights (always present; consistent with
n_prior_dispersion via ).
n_prior_dispersionNamed per-component vector of
effective prior sample sizes for the Block~2 dispersion prior
(always present; used by
pfamily_list to
calibrate dIndependent_Normal_Gamma components).
designFull model_setup object (all groups).
fit_refReference lmer/glmer fit on all
groups (the full-formula fit from model_setup).
dispersion_ranefScalar for Gaussian models
only; NULL otherwise.
Sigma_ranefDiagonal RE covariance matrix (Block~1).
prior_listNamed Block~2 prior list per RE coefficient.
ing_priorNamed per-component list of the prospective
dIndependent_Normal_Gamma calibration: Gamma precision-prior
shape and rate
(the glmbayesCore default
calibration with n_prior_dispersion; since
rate , the implied
inverse-Gamma prior on has mean exactly
), and the default truncation
window disp_lower / disp_upper: the 0.01 / 0.99
quantiles of the limiting posterior
– the weak-prior
() limit of the Block~2 posterior Gamma for the
precision (glmbayesCore Chapter A12, Theorem 2; inverted to a
interval). This window is identical for all
, covers ~98\
prior strength, and keeps the envelope sampler's cost stable as
priors weaken; see inst/ING_TRUNCATION_WINDOW.md. Used by
pfamily_list when
ptypes = "dIndependent_Normal_Gamma"; ignored for
dNormal priors.
x invisibly.
model_setup, Prior_Setup,
build_mu_all
lmb / glmbBlock
Runs Prior_Setup on each block subset of the data.
Prior_SetupBlock( formula, block, family = gaussian(), data = NULL, weights = NULL, subset = NULL, na.action = na.fail, offset = NULL, contrasts = NULL, pwt = NULL, pwt_default_low = 0.01, pwt_default_high = 0.05, n_prior = NULL, sd = NULL, dispersion = NULL, intercept_source = c("null_model", "full_model"), effects_source = c("null_effects", "full_model"), mu = NULL, k = 1, ... )Prior_SetupBlock( formula, block, family = gaussian(), data = NULL, weights = NULL, subset = NULL, na.action = na.fail, offset = NULL, contrasts = NULL, pwt = NULL, pwt_default_low = 0.01, pwt_default_high = 0.05, n_prior = NULL, sd = NULL, dispersion = NULL, intercept_source = c("null_model", "full_model"), effects_source = c("null_effects", "full_model"), mu = NULL, k = 1, ... )
formula |
A |
block |
Block partition: |
family |
a description of the error distribution and link function to be used in the model. |
data |
an optional data frame, list or environment (or object
coercible by |
weights |
an optional vector of ‘prior weights’ to be used
in the fitting process. Should be |
subset |
an optional vector specifying a subset of observations to be used in the fitting process. (See additional details about how this argument interacts with data-dependent bases in the ‘Details’ below.) |
na.action |
how |
offset |
this can be used to specify an a priori known
component to be included in the linear predictor during fitting.
This should be |
contrasts |
an optional list. See the |
pwt |
Weight on the prior relative to the likelihood function at the maximum likelihood
estimate. If supplied, this value is used directly (scalar or one value per coefficient).
If |
pwt_default_low |
Default prior weight used when |
pwt_default_high |
Default prior weight used when |
n_prior |
Optional scalar effective prior sample size (on the |
sd |
Optional vector argument with the prior standard deviations for the coefficients |
dispersion |
Optional scalar dispersion override (default |
intercept_source |
Specifies the method through which the prior mean for the intercept term is set. Options are based on the null intercept only model (null_model) or full_models. The default is the null model which is safer if variables are not centered. |
effects_source |
Specifies the method through which the prior means for the effects terms are set. Options are null_effects (prior means set to zero) or full_model (effect means set to match maximum likelihood estimates). |
mu |
Optional vector argument with the prior means for the coefficients |
k |
Scalar (default |
... |
For For |
A named list of class "block_PriorSetup". Each element is a
Prior_Setup result for one block.
lmbBlock, multi_prior_setup,
Prior_Setup_lmebayes, normalize_block
Bayesian generalized linear mixed-effects model sampler
rglmerb( n, design, prior, family = poisson(), dispersion_ranef = NULL, fixef_start = NULL, m_convergence = NULL, n_pilot = NULL, gap_tol = 0.0196, m_convergence_pilot = NULL, tv_tol = 0.01, mode_gap_max = 1, collect_block1 = TRUE, seed = NULL, verbose = TRUE, progbar = FALSE )rglmerb( n, design, prior, family = poisson(), dispersion_ranef = NULL, fixef_start = NULL, m_convergence = NULL, n_pilot = NULL, gap_tol = 0.0196, m_convergence_pilot = NULL, tv_tol = 0.01, mode_gap_max = 1, collect_block1 = TRUE, seed = NULL, verbose = TRUE, progbar = FALSE )
n |
Integer. Number of independent chains in the main stage. |
design |
A |
prior |
A |
family |
A |
dispersion_ranef |
Observation-level measurement dispersion |
fixef_start |
Optional named list of Block~2 starting vectors. When
|
m_convergence |
Optional integer inner Gibbs sweeps per main draw. |
n_pilot |
Optional integer pilot chains (non-Gaussian only);
|
gap_tol |
Mode–mean gap tolerance for deriving |
m_convergence_pilot |
Optional pilot inner sweeps (non-Gaussian only). |
tv_tol |
Total variation tolerance for convergence calibration. |
mode_gap_max |
Pilot sweep calibration when |
collect_block1 |
Collect Block~1 |
seed |
Optional RNG seed (Gaussian path only). |
verbose |
Print stage headers and diagnostics. |
progbar |
Progress bars when |
Matrix-level sampler for lmebayes model_setup objects and prior
containers. Routes by response family:
family = gaussian() delegates to
rLMMNormal_reg or
rLMMindepNormalGamma_reg when dispersion_ranef is
a dGamma() pfamily.
Non-Gaussian families delegate to rGLMM
(sweep-outer engine with optional pilot/main staging).
See glmerb for the formula-level API.
Object of class c("rglmerb", "list") with Block~2 fields in
the fixef.* namespace, plus ranef.mode, Prior,
design, and family. Non-Gaussian fits may include
n_pilot, pilot, and pilot_chisq; Gaussian fits set
n_pilot = 0L and omit pilot output.
glmerb,
rLMMNormal_reg,
rLMMindepNormalGamma_reg,
rGLMM
Bayesian linear mixed-effects model sampler (two-block Gibbs engine)
rlmerb( n, design, prior, dispersion_ranef, fixef_start = NULL, m_convergence = NULL, tv_tol = 0.01, seed = NULL, progbar = TRUE, verbose = TRUE, print_icm_table = TRUE )rlmerb( n, design, prior, dispersion_ranef, fixef_start = NULL, m_convergence = NULL, tv_tol = 0.01, seed = NULL, progbar = TRUE, verbose = TRUE, print_icm_table = TRUE )
n |
Integer. Number of stored draws (each draw is one full pass through
|
design |
A |
prior |
A |
dispersion_ranef |
Required observation-level dispersion: a positive
scalar |
fixef_start |
Optional named list of starting hyper-parameter vectors
(one per RE component). When |
m_convergence |
Optional integer. Number of inner Gibbs sweeps per
stored draw. When |
tv_tol |
Single numeric in |
seed |
Optional integer RNG seed. Default |
progbar |
Logical. Show a text progress bar during sampling.
Default |
verbose |
Logical. Print the lmer-vs-ICM table and the convergence
calibration line. Default |
print_icm_table |
Logical. When |
Full sampling engine for Gaussian linear mixed models, parallel to
rlmb in glmbayes and rglmerb
/ glmerb in lmebayes. Takes structured design
and prior objects, computes the ICM posterior mean internally, and
delegates replicate-chain sampling to
rLMMNormal_reg or
rLMMindepNormalGamma_reg when dispersion_ranef is a
dGamma() pfamily.
rlmerb is called internally by lmerb after
model_setup and prior construction are complete. It can also
be called directly in simulation or Gibbs-sampling workflows where formula
parsing and model-fit overhead are unnecessary.
An object of class c("rlmerb", "list") with Block~2 fields in
the fixef.* namespace (Core LMM engines):
fixef, fixef.mode, fixef.init, fixef.means,
fixef.dispersion, fixef.dispersion.mean, fixef.iters,
fixef.iters.mean, fixef.mu; Block~1 draws in
coefficients; ranef.mode; m_convergence;
convergence; Prior; design.
lmerb,
rLMMNormal_reg,
rLMMindepNormalGamma_reg, glmerb,
rglmerb, rlmb
Summary method for row-block glmb fits (class "bglmb").
summary.bglmb applies summary.glmb to each block;
print.summary.bglmb follows summary.mlmb /
summary.blmb with per-block sections.
## S3 method for class 'bglmb' summary(object, ...) ## S3 method for class 'summary.bglmb' print(x, digits = max(3, getOption("digits") - 3), ...)## S3 method for class 'bglmb' summary(object, ...) ## S3 method for class 'summary.bglmb' print(x, digits = max(3, getOption("digits") - 3), ...)
object |
An object of class |
x |
An object of class |
digits |
Number of significant digits for printing. |
... |
Passed to |
summary.bglmb returns a named list of "summary.glmb"
objects with class "summary.bglmb".
glmbBlock, lmbBlock,
summary.mlmb, summary.blmb,
summary.glmb
Summary method for row-block lmb fits (class "blmb").
## S3 method for class 'blmb' summary(object, ...) ## S3 method for class 'summary.blmb' print(x, digits = max(3, getOption("digits") - 3), ...)## S3 method for class 'blmb' summary(object, ...) ## S3 method for class 'summary.blmb' print(x, digits = max(3, getOption("digits") - 3), ...)
object |
An object of class |
x |
An object of class |
digits |
Number of significant digits for printing. |
... |
Passed to |
Methods for lmerb fits. summary.lmerb builds
Block~2 (level-2 fixed effect) tables per random-effects component,
following the layout of summary.glmb and the
multi-response structure of summary.mlmb.
## S3 method for class 'lmerb' summary(object, groups = NULL, digits = max(3L, getOption("digits") - 3L), ...) ## S3 method for class 'glmerb' summary(object, groups = NULL, digits = max(3L, getOption("digits") - 3L), ...) ## S3 method for class 'summary.lmerb' print(x, digits = max(3L, getOption("digits") - 3L), ...)## S3 method for class 'lmerb' summary(object, groups = NULL, digits = max(3L, getOption("digits") - 3L), ...) ## S3 method for class 'glmerb' summary(object, groups = NULL, digits = max(3L, getOption("digits") - 3L), ...) ## S3 method for class 'summary.lmerb' print(x, digits = max(3L, getOption("digits") - 3L), ...)
object |
An object of class |
groups |
Optional character vector of grouping levels for which to
include a per-group Block~1 (random effects) detail table. When
|
digits |
Number of significant digits for printing. |
x |
An object of class |
... |
Ignored. |
summary.lmerb returns an object of class
"summary.lmerb", a list with components call,
formula, n, simulated, varcor,
fixef_overview, fixef (per-RE-component tables),
ranef_overview, any_non_normal, tau2 (per-component
Block~2 dispersion table: prior type, plug-in value, posterior
mean / SD / quantiles from fixef.dispersion for sampled ING
components, and Cand/draw, the average number of Block~2
candidates per accepted draw from fixef.iters.mean – 1 for
dNormal, roughly the reciprocal acceptance rate of the
envelope sampler for ING), and optionally ranef_groups.
lmerb, glmerb, print.lmerb,
summary.glmb, summary.mlmb