| Type: | Package |
| Title: | Infinitesimal Jackknife Standard Errors for 'brms' Models |
| Version: | 0.3.4 |
| Description: | Computes infinitesimal jackknife standard errors and covariance matrices for posterior expectations from 'brms' models or matched posterior draws and pointwise log likelihoods. Supports independent and clustered sampling units, transformed quantities, blockwise likelihood evaluation, and chain stability diagnostics. References: Ji et al. (2026) <doi:10.3102/10769986251379738>; Giordano and Broderick (2024) <doi:10.48550/arXiv.2305.06466>. |
| License: | MIT + file LICENSE |
| Depends: | R (≥ 3.5.0) |
| Imports: | posterior (≥ 1.4.0), stats |
| Suggests: | brms (≥ 2.20.0), testthat (≥ 3.0.0), knitr, rmarkdown, ggplot2 (≥ 3.4.0) |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| Encoding: | UTF-8 |
| RoxygenNote: | 8.0.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-10-22 04:35:44 UTC; jifeng3 |
| Author: | Feng Ji |
| Maintainer: | Feng Ji <f.ji@utoronto.ca> |
| Repository: | CRAN |
| Date/Publication: | 2026-10-22 13:30:32 UTC |
IJ inference for posterior expectations
Description
Compute infinitesimal jackknife sampling uncertainty from matched posterior draws and observation-level log likelihoods, with optional cluster aggregation.
Start with your available inputs
| A fitted brms model | ijse returns structured inference. |
| Draws and log likelihoods | ijse_draws is backend independent. |
| Existing vector-only code | IJ_se preserves the original API. |
| A computed result | summary.ijse documents standard methods.
|
The matrix/callback interface requires no brms or Stan installation. The brms interface requires brms; installed synthetic examples can be used without compiling Stan or fitting a new model.
What the uncertainty means
The target is a posterior expectation, including a function evaluated jointly
on every draw. Posterior draw covariance and IJ sampling covariance are
different quantities. vcov(result) returns IJ covariance;
vcov(result, type = "posterior") returns posterior covariance.
confint(result) uses a normal reference and IJ SEs. IJ changes uncertainty,
not estimator bias, and cluster IDs must reflect meaningful independent units.
Executable tutorials and calibration study
-
vignette("ijse", package = "IJSE"): complete first calculation, covariance, transformations and callbacks without Stan. -
vignette("ijse-brms", package = "IJSE"): actual median-regression examples, explicit sampling IDs, joint contrasts and draw selection. -
vignette("ijse-diagnostics", package = "IJSE"): chain metadata, influence derivatives and reproduced input errors. -
vignette("ijse-study", package = "IJSE"): 40,000 exact-posterior datasets, 320 independent draw ensembles and 400 actual brms fits, with Monte Carlo uncertainty and explicit calibration limitations.
The three tutorial scripts are installed under system.file("tutorials",
package = "IJSE"). The study vignette reads compact results; package checks
do not rerun the MCMC study. Use citation("IJSE") for software and
published-method citations.
Author(s)
Maintainer: Feng Ji f.ji@utoronto.ca (ORCID)
Authors:
Feng Ji f.ji@utoronto.ca (ORCID)
JoonHo Lee jlee296@ua.edu
Sophia Rabe-Hesketh sophiarh@berkeley.edu
See Also
ijse, ijse_draws,
summary.ijse
Infinitesimal jackknife inference for brms models
Description
Extract matched draws and likelihood contributions from a brmsfit
object and compute IJ inference with ijse_draws.
Usage
ijse(
fit,
cluster_var = NULL,
variables = NULL,
transform = NULL,
draw_ids = NULL,
block_size = NULL,
save_influence = FALSE,
diagnostics = c("all", "posterior", "none")
)
IJ_se(fit, cluster_var = NULL)
Arguments
fit |
A fitted |
cluster_var |
Optional cluster IDs in the order of the likelihood columns
returned by |
variables |
Optional exact parameter names. Defaults to parameters starting
with |
transform |
Optional function applied to the selected draws; see
|
draw_ids |
Optional strictly increasing indices of post-warmup draws,
ordered by iteration within chain, then chain. The same indices are passed
to likelihood extraction. Each retained chain requires at least two draws
when |
block_size |
|
save_influence |
Whether to retain empirical influence values. |
diagnostics |
One of |
Details
MCMC chain diagnostics are retained for the selected or transformed quantities. The likelihood uses the brms default of conditioning on fitted group effects. This extraction choice does not establish IJ validity for arbitrary hierarchical models. For clustered working-independence models, supply cluster IDs explicitly; they are never inferred from a model formula.
Streaming respects observation permutations in brms prediction metadata.
The tested brms release does not support pointwise evaluation for regression
ARMA models; use ordinary extraction for those models. Covariance ARMA models
are rejected because brms returns conditional LOO densities instead of joint
likelihood factors. Supply one joint likelihood per independent series to
ijse_draws(). Discrete truncated models also require explicit matrix
input because the backend lower-bound normalization is not validated.
Multivariate streaming is rejected
because response-specific orderings may differ; the default dense path uses
brms's combined likelihood.
Measurement-error predictors require saved latent draws, for example
brms::save_pars(latent = TRUE) when fitting. Otherwise brms may
resample prediction latents, which do not match the fitted posterior draws.
Even with saved latents, the native likelihood conditions on them; it is not
an observed-data likelihood integrating measurement error. Missing-response
models may return non-finite likelihoods, which are rejected. Use explicitly
derived observed-data likelihoods with ijse_draws() when appropriate.
Value
ijse() returns the structured ijse object documented
under ijse_draws. IJ_se() returns
the named numeric vector of standard errors, as in previous releases.
Choosing an interface
Use ijse() to retain estimates, both covariance types, intervals,
diagnostics and optional influence. IJ_se() returns only IJ SEs with
the same pooled formula. Ordinary extraction is the default. A positive
block_size requests brms pointwise likelihood evaluation; backend
prediction/preparation objects may still be large. This differs from
ijse_draws(), whose positive block size controls a supplied callback.
Parameter extraction and likelihood extraction share draw_ids.
Do not manually reorder parameter rows or pass cluster IDs for the original
unfiltered dataset. Keep fitting-row keys with the actual model data and
check clustered, n_obs, n_units, and unit_ids.
Correct lengths alone cannot identify mismatched scientific units.
See Also
Examples
# Uses an installed synthetic fit: no Stan compilation or new fitting.
if (requireNamespace("brms", quietly = TRUE)) {
examples <- readRDS(system.file("extdata", "tutorial",
"median-examples.rds", package = "IJSE"))
fit <- examples$clustered$fit
ids <- examples$clustered$cluster
result <- ijse(fit, cluster_var = ids, save_influence = TRUE)
stopifnot(result$clustered, result$n_units == 30L)
summary(result)
vcov(result)
vcov(result, type = "posterior")
confint(result, parm = "b_x", level = 0.90)
head(result$unit_ids)
stopifnot(isTRUE(all.equal(IJ_se(fit, ids), result$se)))
streamed <- ijse(fit, cluster_var = ids, block_size = 40,
diagnostics = "none")
stopifnot(isTRUE(all.equal(vcov(streamed), vcov(result))))
prediction <- ijse(fit, cluster_var = ids,
variables = c("b_Intercept", "b_x"),
transform = function(d) {
cbind(median_at_x1 = d[, "b_Intercept"] + d[, "b_x"])
}, diagnostics = "posterior")
coef(prediction)
}
# For fitting instructions, run vignette("ijse-brms", package = "IJSE").
Infinitesimal jackknife inference from posterior draws
Description
Compute sampling covariance of posterior expectations from matched posterior draws and pointwise log likelihoods, with optional cluster aggregation.
Usage
ijse_draws(
draws,
log_lik,
cluster_var = NULL,
variables = NULL,
transform = NULL,
n_obs = NULL,
block_size = 1000L,
save_influence = FALSE,
chain_id = NULL,
diagnostics = c("all", "posterior", "none")
)
Arguments
draws |
A numeric matrix or data frame (draws by parameters), or a posterior draws object. Rows must correspond exactly to likelihood rows. |
log_lik |
A finite numeric matrix (draws by observations), or a function accepting observation indices and returning such a matrix for those columns. A callback must preserve the requested column order and draw row order. |
cluster_var |
Optional atomic vector of cluster IDs, in likelihood-column order. Missing IDs, including used explicit NA factor levels, are rejected. At least two clusters are required. |
variables |
Optional character vector of exact parameter names to select
before applying |
transform |
Optional function of the selected plain numeric draw matrix. Return a numeric vector, matrix, or data frame with one row per input draw. Named columns are recommended. Each returned column defines a posterior expectation of interest. Names on a returned vector are draw-row labels, not a quantity name; they are preserved and checked against available input labels. Use a one-column matrix or data frame to name a single transformed quantity. |
n_obs |
Number of likelihood columns. Required for a likelihood callback. |
block_size |
Maximum number of likelihood columns requested per callback block. Already materialized matrices use the compiled dense covariance path. |
save_influence |
Whether to retain the empirical influence matrix
(parameters by resampling units). Default |
chain_id |
Optional atomic vector identifying the chain of each draw. Within each chain, rows must be in iteration order. Inferred for posterior draws objects unless supplied explicitly. Each chain must have two draws when computing chain-specific IJ SEs. Missing chain IDs, including used explicit NA factor levels, are rejected. |
diagnostics |
One of |
Details
Inputs have S posterior-draw rows, P selected or
transformed quantities, and N observation-level likelihood columns.
Supply log likelihoods excluding the prior, rather than a log posterior or
a single joint-likelihood column. At least two draws and two sampling units
are required. variables is applied before transform.
For quantity vector g(\theta), write
C_i = \operatorname{Cov}_{\theta\mid y}(g(\theta),\ell_i(\theta)).
Its estimate uses sample covariance over draws with denominator S-1.
For independent observations, K=N and each unit contribution is
C_u=C_i. For clusters, K=J and
C_u=\sum_{i\in u}C_i. The returned sampling covariance is
\widehat V_{\mathrm{IJ}}=
\frac{K}{K-1}\sum_{u=1}^K
(\widehat C_u-\overline C)(\widehat C_u-\overline C)^{\mathsf T}.
Here \overline C is the average unit contribution. This is the
finite-sample convention used by Ji et al. (2026).
The target is E\{g(\theta)\mid y\}, which can differ from
g\{E(\theta\mid y)\}. Transforms use jointly sampled quantities.
Fixed-reference predictors are supported; extra sampling variation from
estimating the reference distribution is not included. IJ covariance is
sampling covariance of posterior expectations, not posterior draw covariance.
It does not remove estimator bias. Validity depends on sampling units,
likelihood factorization, and model regularity. Cluster aggregation alone
does not validate arbitrary latent-effects models, few clusters, time series,
informative cluster sampling, or multiway dependence.
Value
An ijse list containing:
estimateNamed vector of
Pposterior draw means.posterior_sd,posterior_vcovNamed posterior sample SDs and a
P\times Pposterior sample covariance matrix.se,vcovNamed IJ SEs and a
P\times PIJ sampling covariance matrix. Both covariance matrices have quantity dimnames.n_draws,n_obs,n_unitsCounts
S,N, andK. Without clustering,n_units == n_obs.clusteredWhether cluster IDs were supplied. Unique per-row IDs still set this flag to
TRUE, with observation-equivalent covariance.unit_idsExact original cluster IDs, named by unique display labels, in first-appearance order;
NULLfor independent observations.influenceNULLunless requested; otherwise aP\times Kmatrix equal toK\widehat C_u, with quantity rows and unit-label columns. Seesummary.ijsefor interpretation.diagnosticsList with
mode,chain_ids,chain_se(chains by quantities),chain_relative_range,rhat,ess_bulk, andess_tail. Uncomputed entries areNULL. Posterior metrics and relative ranges are named by quantity.callThe matched function call.
Alignment and labels
Explicit row labels are checked when available on both sides. Names of a
vector returned by transform are treated as draw-row labels. Automatic
data-frame row numbers are positional. With unlabeled or incorrectly
relabeled inputs, equal dimensions cannot establish correct row alignment.
Labeled callback blocks must also agree with one another, including when
the original draws are unlabeled. The first labeled block establishes that
cross-block reference; unlabeled rows still require the caller's care.
A callback must preserve observation-column order; it cannot be inferred.
Cluster and chain IDs are matched in order of first appearance. Their display
labels use make.unique(as.character(ids)); distinct numeric IDs can
otherwise print alike. Exact original cluster IDs are in unit_ids,
named by those labels. Exact chain IDs are in diagnostics$chain_ids
when diagnostics are enabled. Do not parse display labels to reconstruct IDs.
Diagnostics and memory
"all" computes chain-specific IJ SEs when each chain has at least
two draws. R-hat and bulk/tail ESS require equally long chains with at least
four draws each. The metrics describe selected or transformed quantities,
not the precision of all quantity-likelihood covariances. Missing calculations
are NULL; computed metrics can be NA, for example for constants.
The chain relative range is (max(SE)-min(SE))/pooled_SE; it is a
stability check, not a calibrated IJ Monte Carlo SE or a universal pass rule.
For actual MCMC fits, also inspect sampler and nuisance-parameter diagnostics.
block_size limits callback requests, not storage of a matrix already
supplied. Dense matrices use stats::cov(). Saved influence uses
P\times K storage; it is off by default. Clustered computations retain
aggregated quantity-by-cluster contributions even when influence is not saved.
Finite inputs can overflow covariance calculations; rescale when requested.
References
Ji, F., Lee, J., and Rabe-Hesketh, S. (2026). Valid Standard Errors for Bayesian Quantile Regression With Clustered and Independent Data. Journal of Educational and Behavioral Statistics, 51(5). doi:10.3102/10769986251379738. Giordano, R. and Broderick, T. (2024). The Bayesian Infinitesimal Jackknife for Variance. doi:10.48550/arXiv.2305.06466.
See Also
ijse, summary.ijse,
IJSE-package. Run vignette("ijse", package = "IJSE")
for a complete executable introduction.
Examples
set.seed(12)
y <- c(-1, 0, 0.5, 1, 2)
v <- 1 / (length(y) + 1 / 4)
mu <- rnorm(2000, v * sum(y), sqrt(v))
draws <- cbind(mu = mu)
ll <- vapply(y, function(yi) dnorm(yi, mu, log = TRUE),
numeric(length(mu)))
result <- ijse_draws(draws, ll)
summary(result)
vcov(result)
confint(result)
ijse_draws(draws, ll,
transform = function(x) cbind(mu_squared = x[, 1]^2))
# A callback avoids storing the whole likelihood matrix.
ijse_draws(draws, function(i) ll[, i, drop = FALSE],
n_obs = length(y), block_size = 2)
Summarize IJ inference
Description
Standard methods for posterior expectations and their IJ sampling covariance. Normal intervals are centered on posterior expectations and use IJ SEs; they are not posterior credible intervals or a small-cluster correction.
Usage
## S3 method for class 'ijse'
coef(object, ...)
## S3 method for class 'ijse'
vcov(object, ..., type = c("ij", "posterior"))
## S3 method for class 'ijse'
influence(model, ...)
## S3 method for class 'ijse'
confint(object, parm, level = 0.95, ...)
## S3 method for class 'ijse'
summary(object, level = 0.95, ...)
## S3 method for class 'ijse'
print(x, digits = max(3L, getOption("digits") - 3L), ...)
## S3 method for class 'summary.ijse'
print(x, digits = max(3L, getOption("digits") - 3L), ...)
Arguments
object, x, model |
An |
... |
Reserved for future arguments; must be empty. |
type |
For |
parm |
Parameter names or integer indices; defaults to all quantities. |
level |
Confidence level strictly between zero and one. |
digits |
Number of significant digits used for printing. |
Details
confint() uses the posterior expectation plus or minus
a standard-normal critical value times the IJ SE. It is symmetric and
uses a normal reference, even for clustered results. It is not an equal-tailed
posterior credible interval, an IJ Monte Carlo interval, or a t correction.
The upper-tail calculation avoids rounding a valid probability to one when
level is very close to one. Below level = 1e-8, the central
inverse-probability expansion \sqrt{\pi/2}\,level avoids losing a tiny
positive level; its omitted relative correction is below double precision.
Floating-point precision can limit display
of extreme confidence levels and very narrow interval endpoints.
SE_ratio in the summary is IJ_SE / Posterior_SD; it is
NA when the posterior SD is zero. A larger ratio alone does not prove
calibrated inference. The two vcov() choices estimate distinct objects.
Posterior covariance is unavailable in objects saved before version 0.3.0;
recompute those objects to request it.
Saved influence() values are K\widehat C_u, not zero-centered
influence values. Divide by n_units to obtain case-weight derivative
estimates. For a small likelihood-weight change \Delta w_u,
\Delta E(g\mid y)\approx\widehat C_u\Delta w_u; downweighting reverses
the derivative's sign. Deleting a whole unit is a finite perturbation and
need not equal this local approximation. The rows need not have mean zero.
Sampling covariance centers across units, so
cov(t(influence(result))) / result$n_units reproduces vcov(result).
Use result$unit_ids for exact cluster IDs; columns use unique display
labels. Independent observations use their likelihood-column indices.
In a finite-draw importance-reweighting check, normalized empirical weights
differentiate with denominator S, whereas IJSE uses sample covariance
with denominator S-1. Multiply that numerical derivative by
S/(S-1) when checking equality. This is a testing identity, not an extra
correction to apply to the reported IJ SE.
Value
coef() returns a named vector of posterior expectations.
vcov() returns the P\times P IJ sampling covariance by default,
or posterior draw covariance for type = "posterior".
confint() returns a quantities-by-two matrix, in the requested
parm order, with percentage-labeled columns. When the percentage
labels would coincide at display precision, columns are named lower
and upper.
influence() returns the saved quantities-by-units matrix or errors
when influence was not retained.
summary() returns a summary.ijse list: coefficients
(Estimate, Posterior_SD, IJ_SE, SE_ratio, lower and upper limits), counts,
clustered, unit_ids, level, diagnostics and call.
Print methods invisibly return their input.
See Also
Examples
set.seed(1)
y <- c(-1, 0, 0.5, 1, 2)
v <- 1 / (length(y) + 1 / 4)
d <- cbind(theta = rnorm(1000, v * sum(y), sqrt(v)))
ll <- vapply(y, function(yi) dnorm(yi, d[, 1], log = TRUE),
numeric(nrow(d)))
result <- ijse_draws(d, ll, save_influence = TRUE)
coef(result)
vcov(result)
confint(result, level = 0.90)
summary(result)
vcov(result, type = "posterior")
influence(result) / result$n_units
stopifnot(isTRUE(all.equal(
cov(t(influence(result))) / result$n_units, vcov(result))))