| Title: | Bayesian Multilevel Quantile Regression |
|---|---|
| Description: | Fits Bayesian mixed-effects (multilevel) quantile regression models using the asymmetric Laplace working likelihood and Stan. Supports an 'lme4'-style formula interface with nested and crossed random effects, fitting one or several quantiles, post-hoc non-crossing rearrangement of fitted quantiles, and the Yang, Wang and He (2016) posterior-variance correction for valid frequentist inference from the (misspecified) asymmetric Laplace posterior. |
| Authors: | Kailas Venkitasubramanian [aut, cre, cph] |
| Maintainer: | Kailas Venkitasubramanian <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0 |
| Built: | 2026-07-10 21:52:00 UTC |
| Source: | https://github.com/cran/bqmm |
A lightweight family object describing the asymmetric Laplace distribution
(ALD) working likelihood used by bqmm(). It mirrors the role of a
stats::family object but is intentionally minimal in this release.
ald(link = "identity")ald(link = "identity")
link |
Name of the link for the location (quantile) parameter.
Only |
An object of class "bqmm_family".
ald()ald()
Convert a bqmm fit to a posterior draws object
## S3 method for class 'bqmm' as_draws(x, ...)## S3 method for class 'bqmm' as_draws(x, ...)
x |
A |
... |
Unused. |
A draws_array (from the posterior package) with tidy variable
names: b_<name> for fixed effects, sd_<component> for random-effect
SDs, and sigma.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) as_draws(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) as_draws(fit)
Coerce a bqmm fit to a matrix of posterior draws
## S3 method for class 'bqmm' as.matrix(x, ...)## S3 method for class 'bqmm' as.matrix(x, ...)
x |
A |
... |
Unused. |
A matrix of posterior draws (draws in rows, parameters in columns), using the raw Stan parameter names.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) dim(as.matrix(fit))fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) dim(as.matrix(fit))
Fits a Bayesian mixed-effects quantile regression model using the asymmetric
Laplace working likelihood and Stan. The interface follows lme4: random
effects are written inline in the formula, e.g. y ~ x + (1 + x | group),
and nested or crossed grouping factors are both supported.
bqmm( formula, data, tau = 0.5, family = ald(), prior = NULL, cov = c("diagonal", "unstructured"), adjust = TRUE, prior_only = FALSE, chains = 4, iter = 2000, warmup = floor(iter/2), cores = getOption("mc.cores", 1L), seed = NULL, control = list(adapt_delta = 0.95), ... )bqmm( formula, data, tau = 0.5, family = ald(), prior = NULL, cov = c("diagonal", "unstructured"), adjust = TRUE, prior_only = FALSE, chains = 4, iter = 2000, warmup = floor(iter/2), cores = getOption("mc.cores", 1L), seed = NULL, control = list(adapt_delta = 0.95), ... )
formula |
An lme4-style model formula. |
data |
A data frame containing the variables in |
tau |
Quantile level(s) in (0, 1). Scalar or vector. |
family |
A |
prior |
A |
cov |
Random-effect covariance structure. |
adjust |
Logical; compute the Yang-Wang-He (2016) variance correction so
that |
prior_only |
Logical; sample from the prior predictive distribution. |
chains, iter, warmup, cores, seed
|
Passed to |
control |
A list of sampler control parameters (e.g. |
... |
Additional arguments forwarded to |
One or several quantiles may be requested through tau. A scalar returns a
single bqmm fit; a vector fits each quantile independently and returns a
bqmm_multi container.
A bqmm object (single tau) or a bqmm_multi object (vector
tau).
# A minimal fit; raise chains/iter for real analyses. fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) summary(fit)# A minimal fit; raise chains/iter for real analyses. fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) summary(fit)
Builds the list of prior hyperparameters passed to Stan. Defaults are weakly
informative and scaled to the data (see bqmm_default_priors()); any element
supplied here overrides the default.
bqmm_prior( beta_mean = 0, beta_sd = NULL, sigma_scale = NULL, re_scale = NULL, lkj = 2 )bqmm_prior( beta_mean = 0, beta_sd = NULL, sigma_scale = NULL, re_scale = NULL, lkj = 2 )
beta_mean |
Numeric scalar or vector: prior mean(s) for the fixed-effect
coefficients. Recycled to the number of columns of the design matrix.
Default |
beta_sd |
Positive scalar or vector: prior SD(s) for the fixed-effect
coefficients. |
sigma_scale |
Positive scalar: half-normal scale for the ALD scale
|
re_scale |
Positive scalar: half-normal scale for the random-effect
standard deviations. |
lkj |
Positive scalar: LKJ shape parameter for the random-effect
correlation matrix (used only when |
An object of class "bqmm_prior".
bqmm_prior(beta_sd = 5)bqmm_prior(beta_sd = 5)
Alias for fixef(); returns the posterior-median fixed effects.
## S3 method for class 'bqmm' coef(object, ...)## S3 method for class 'bqmm' coef(object, ...)
object |
A |
... |
Unused. |
A named numeric vector of posterior-median fixed-effect coefficients.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) coef(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) coef(fit)
Coefficient-versus-tau matrix for a bqmm_multi fit
## S3 method for class 'bqmm_multi' coef(object, ...)## S3 method for class 'bqmm_multi' coef(object, ...)
object |
A |
... |
Unused. |
A tau-by-coefficient matrix of posterior-median fixed effects, with one row per quantile.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = c(0.25, 0.75), chains = 1, iter = 250, refresh = 0, seed = 1) coef(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = c(0.25, 0.75), chains = 1, iter = 250, refresh = 0, seed = 1) coef(fit)
Wald-type intervals built from the posterior-median estimates and the (optionally misspecification-corrected) fixed-effect covariance.
## S3 method for class 'bqmm' confint( object, parm, level = 0.95, adjusted = TRUE, method = c("ywh", "ij"), cluster = TRUE, ... )## S3 method for class 'bqmm' confint( object, parm, level = 0.95, adjusted = TRUE, method = c("ywh", "ij"), cluster = TRUE, ... )
object |
A |
parm |
Optional subset of coefficients (names or indices) to return. |
level |
Interval coverage (default |
adjusted |
Logical; if |
method |
Correction to use when |
cluster |
Logical; use the cluster-robust form (default |
... |
Unused. |
A matrix with one row per coefficient and lower/upper interval columns.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) confint(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) confint(fit)
Linear predictor (conditional tau-quantile) at the posterior median
## S3 method for class 'bqmm' fitted(object, ...)## S3 method for class 'bqmm' fitted(object, ...)
object |
A |
... |
Unused. |
Numeric vector of fitted conditional quantiles.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) head(fitted(fit))fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) head(fitted(fit))
Posterior-median fixed effects
## S3 method for class 'bqmm' fixef(object, ...)## S3 method for class 'bqmm' fixef(object, ...)
object |
A |
... |
Unused. |
A named numeric vector of posterior-median fixed-effect coefficients.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) fixef(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) fixef(fit)
Pointwise log-likelihood draws
## S3 method for class 'bqmm' log_lik(object, ...)## S3 method for class 'bqmm' log_lik(object, ...)
object |
A |
... |
Unused. |
An S x N matrix of pointwise log-likelihood values, suitable for use
with the loo package.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) dim(log_lik(fit))fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) dim(log_lik(fit))
Number of observations used in the fit
## S3 method for class 'bqmm' nobs(object, ...)## S3 method for class 'bqmm' nobs(object, ...)
object |
A |
... |
Unused. |
An integer, the number of observations.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) nobs(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) nobs(fit)
Default plot shows fixed-effect posterior intervals. With bayesplot
installed, richer MCMC plots are available via as_draws().
## S3 method for class 'bqmm' plot(x, ...)## S3 method for class 'bqmm' plot(x, ...)
x |
A |
... |
Unused. |
Invisibly, x.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) plot(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) plot(fit)
Plot coefficient-versus-tau paths for a bqmm_multi fit
## S3 method for class 'bqmm_multi' plot(x, ...)## S3 method for class 'bqmm_multi' plot(x, ...)
x |
A |
... |
Unused. |
Invisibly, x.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = c(0.25, 0.75), chains = 1, iter = 250, refresh = 0, seed = 1) plot(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = c(0.25, 0.75), chains = 1, iter = 250, refresh = 0, seed = 1) plot(fit)
Draws of the expected response (conditional tau-quantile)
## S3 method for class 'bqmm' posterior_epred(object, ...)## S3 method for class 'bqmm' posterior_epred(object, ...)
object |
A |
... |
Unused. |
An S x N matrix of posterior draws of the linear predictor, where S is the number of posterior draws and N the number of observations.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) dim(posterior_epred(fit))fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) dim(posterior_epred(fit))
Draws from the posterior predictive distribution
## S3 method for class 'bqmm' posterior_predict(object, ...)## S3 method for class 'bqmm' posterior_predict(object, ...)
object |
A |
... |
Unused. |
An S x N matrix of posterior predictive draws of the response, where S is the number of posterior draws and N the number of observations.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) dim(posterior_predict(fit))fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) dim(posterior_predict(fit))
Predictions from a bqmm fit
## S3 method for class 'bqmm' predict( object, newdata = NULL, re.form = NULL, noncrossing = c("none", "rearrange"), ... )## S3 method for class 'bqmm' predict( object, newdata = NULL, re.form = NULL, noncrossing = c("none", "rearrange"), ... )
object |
A |
newdata |
Optional data frame; if omitted, training data are used. |
re.form |
|
noncrossing |
One of |
... |
Unused. |
Numeric vector of predicted conditional quantiles.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) head(predict(fit, re.form = NA))fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) head(predict(fit, re.form = NA))
Posterior-median random effects
## S3 method for class 'bqmm' ranef(object, ...)## S3 method for class 'bqmm' ranef(object, ...)
object |
A |
... |
Unused. |
A numeric vector of posterior-median random effects aligned with the
columns of the random-effects design matrix Z, or NULL if the model has
no random effects.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) ranef(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) ranef(fit)
Post-hoc monotonisation of estimated quantile curves (Chernozhukov, Fernandez-Val and Galichon, 2010): at any covariate point, sorting the fitted values across quantile levels into increasing order yields a valid, non-crossing set of quantiles and never increases estimation error. This is the v0.1 non-crossing strategy; joint constrained estimation is deferred.
rearrange_quantiles(preds)rearrange_quantiles(preds)
preds |
A numeric matrix of fitted quantiles with one column per
quantile level, ordered by increasing |
A matrix of the same shape with each row sorted increasingly.
m <- rbind(c(1, 0.5, 2), c(0, 1, 0.8)) # some crossings rearrange_quantiles(m)m <- rbind(c(1, 0.5, 2), c(0, 1, 0.8)) # some crossings rearrange_quantiles(m)
Residuals from a bqmm fit
## S3 method for class 'bqmm' residuals(object, ...)## S3 method for class 'bqmm' residuals(object, ...)
object |
A |
... |
Unused. |
Numeric vector of response-minus-fitted residuals.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) head(residuals(fit))fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) head(residuals(fit))
Produces a fixed-effect coefficient table (estimate, standard error and interval) together with random-effect standard deviations.
## S3 method for class 'bqmm' summary( object, level = 0.95, adjusted = TRUE, method = c("ywh", "ij"), cluster = TRUE, ... )## S3 method for class 'bqmm' summary( object, level = 0.95, adjusted = TRUE, method = c("ywh", "ij"), cluster = TRUE, ... )
object |
A |
level |
Interval coverage (default |
adjusted |
Logical; if |
method |
Correction to use when |
cluster |
Logical; use the cluster-robust form (default |
... |
Unused. |
An object of class summary.bqmm.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) summary(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) summary(fit)
Summarize a bqmm_multi fit
## S3 method for class 'bqmm_multi' summary(object, ...)## S3 method for class 'bqmm_multi' summary(object, ...)
object |
A |
... |
Passed to the per-quantile |
A list of summary.bqmm objects, one per quantile.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = c(0.25, 0.75), chains = 1, iter = 250, refresh = 0, seed = 1) summary(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = c(0.25, 0.75), chains = 1, iter = 250, refresh = 0, seed = 1) summary(fit)
Random-effect standard deviations and correlations
## S3 method for class 'bqmm' VarCorr(x, sigma = 1, ...)## S3 method for class 'bqmm' VarCorr(x, sigma = 1, ...)
x |
A |
sigma |
Ignored; present for compatibility with the generic. |
... |
Unused. |
A named numeric vector of posterior-median random-effect standard
deviations (with a posterior-median correlation matrix attached as the
"correlation" attribute for unstructured models), or NULL if the model
has no random effects.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) VarCorr(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) VarCorr(fit)
Variance-covariance of the fixed effects
## S3 method for class 'bqmm' vcov(object, adjusted = TRUE, method = c("ywh", "ij"), cluster = TRUE, ...)## S3 method for class 'bqmm' vcov(object, adjusted = TRUE, method = c("ywh", "ij"), cluster = TRUE, ...)
object |
A |
adjusted |
Logical; if |
method |
Correction to use when |
cluster |
Logical; use the cluster-robust form (default |
... |
Unused. |
A K x K covariance matrix for the fixed effects.
fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) vcov(fit)fit <- bqmm(distance ~ age + (1 | Subject), data = nlme::Orthodont, tau = 0.5, chains = 1, iter = 300, refresh = 0, seed = 1) vcov(fit)