Bayesian Analysis of Graphical Models
Overview
Bayesian estimation and edge selection for graphical models of mixed binary, ordinal, and continuous variables. The variable types determine the model: an ordinal Markov random field for discrete data, a Gaussian graphical model for continuous data, or a mixed Markov random field combining both. Edge inclusion is determined through spike-and-slab priors, yielding posterior inclusion probabilities for each edge. Supports multi-group comparison via 'bgmCompare()', simulation, prediction, and missing data imputation.
This release rebuilds most of the package on top of 0.1.6.3. bgm() now fits
Gaussian graphical models and mixed discrete-continuous networks alongside
ordinal ones; priors are supplied as objects instead of loose scalars;
inclusion inference is Rao-Blackwellized throughout; bgmCompare() has been
reworked; and a set of checking tools (verdicts(), calibration_check(),
prior_sensitivity_check(), network and edge plots) is new. Several defaults
changed, some arguments were removed, and pairwise parameters are reported on
a different scale, so a script written against 0.1.6.3 can run and give
different numbers. Those changes are listed first.
Throughout this file and in the package's output, "log" means the natural
logarithm.
Breaking changes
Show all changes in 0.2.0.0Hide the rest of the changes in 0.2.0.0
**Pairwise parameters are reported on the association scale.**
bgm()stores and reports pairwise interaction parameters on the association scale: the coefficientomegathat enters every conditional as2 * omega * x. In 0.1.6.3 the same coupling was stored assigma = 2 * omega. Reported pairwise effects —coef(),summary(),extract_pairwise_interactions(), and the raw posterior samples — are therefore about half their 0.1.6.3 values for the same data and model. Main effects, indicators, and inclusion probabilities are unaffected in scale. Code that reads raw pairwise samples, or that compares numbers against a 0.1.6.3 run, needs the factor of two applied; there is no automatic conversion.bgmCompare()moves to the association scale withbgm(), in the same release and by the same factor: the two entry points were mutually consistent in 0.1.6.3 and remain so. Pairwise effects reported bycoef(),summary(),extract_pairwise_interactions(),extract_group_params(), and the raw posterior samples are therefore about half their 0.1.6.3 values, exactly as forbgm(). **A storedbgmCompare()fit from an earlier version should be refit rather than rescaled**, because the prior acted on the old, doubled coordinate: the samedifference_scaleorinteraction_priornumber is now a tighter prior than it was, and difference inclusion Bayes factors move accordingly. The calibration of thedifference_scaledefault under the association-scale parameterization is still under study, so difference verdicts near a decision threshold should be read as scale-contingent.simulate_mrf()reads itspairwiseargument on the association scale too: the discrete Gibbs conditional now accumulates2 * (score - baseline) * pairwisewhere 0.1.6.3 accumulated(score - baseline) * pairwise. **Apairwisematrix that a 0.1.6.3 script passed in now means twice the coupling it used to**, so simulated data are more strongly dependent than before at the same input. Halve a hand-specifiedpairwisematrix to reproduce 0.1.6.3 output; a matrix taken from a 0.2.0.0bgm()fit needs no adjustment, because the fit is on the same scale as the simulator. The continuous (variable_type = "continuous") branch takes a precision matrix and is unaffected.
**Changed defaults.**
- The default interaction prior is
normal_prior(scale = 1)inbgm(), where 0.1.6.3 used a Cauchy atpairwise_scale = 2.5;sample_ggm_prior()uses the same default, so the GGM prior chain matchesbgm().bgmCompare()takes the same default for its baseline pairwise interactions, so a compare fit and separatebgm()fits at stated defaults now price a baseline interaction alike. Passinteraction_prior = cauchy_prior(scale = 2.5)tobgm()for the 0.1.6.3 prior, remembering that the scale now acts on the association coordinate. Under the joint precision-graph specification the normalizer correction table is keyed on the interaction prior, so the first fit at the new default cell (with a Beta-Bernoulli or Stochastic-Block edge prior) builds and caches a fresh table once. bgmCompare()now defaults tointeraction_prior = normal_prior(scale = 1)for the baseline pairwise interactions and todifference_family = "Normal"for the group differences, both of which were Cauchy in 0.1.6.3 and through 0.2.0.0's development; the baseline default now matchesbgm(), so the two entry points no longer ship different priors for an identically named argument. Results under the defaults change: a fit at the new defaults is a different model from a fit at the old ones, and difference verdicts on categories one group never observed move the most, because a Normal slab bounds an unidentified threshold difference far more tightly than a Cauchy one.cauchy_prior(scale = 1)anddifference_family = "Cauchy"remain fully available and reproduce the previous behaviour.iterandwarmupdefault to2e3inbgm()andbgmCompare(), up from1e3. A default call therefore runs about twice as long and returns twice as many draws as it did in 0.1.6.3. Setiterandwarmupexplicitly to recover the old budget.- The NUTS
target_acceptdefault is0.80in bothbgm()(was0.60) andbgmCompare()(was0.65). Higher target acceptance means smaller steps: expect more leapfrog steps and a longer run per iteration, in exchange for fewer divergences. The adaptive-Metropolis default is unchanged at0.44. Passtarget_acceptto restore the old value. - On continuous and mixed models the prior on the precision diagonal defaults to
exponential_prior(eta = 1), whereetais the rate in the frame in which the pairwise slab has unit scale; the raw rate is derived at fit time aseta / sfor interaction-prior scales. At the default unit slab scale this is the same distribution asgamma_prior(shape = 1, rate = 1), but with a non-unit slab scale the diagonal rate now co-scales. One consequence: a scale-free interaction prior (beta_prime_prior()) on a continuous model requires the diagonal prior to be given withraterather thaneta.
**Removed and reshaped arguments.**
update_method = "hamiltonian-mc"has been removed; useupdate_method = "nuts". NUTS adapts trajectory length dynamically and is more reliable, especially with edge selection on GGM models. Thehmc_num_leapfrogsargument has been removed with it. A call passing either now fails. On continuous data the new conjugateupdate_method = "gibbs"(see New features) is a second option that needs no step-size tuning at all.- The
standardizeargument ofbgm()andbgmCompare()no longer does anything: pairwise interactions are on the association scale and share one prior scale, so the per-pair adjustment by the product of the two variables' maximum scores has been dropped. The argument stays as a deprecated formal so the failure is informative rather than an unused-argument error.standardize = FALSE, the old default, warns and proceeds, because it is what the sampler already does;standardize = TRUEerrors and points to setting the scale directly throughinteraction_prior(anddifference_scaleforbgmCompare()). There is no per-pair equivalent, and none is planned: standardization belongs in the model rather than in an argument, and a forthcoming g-prior formulation of the interaction prior addresses it there. The per-pair maximum-score adjustment is retired in favour of that direction. - Priors are now objects. The scalar arguments
pairwise_scale,main_alpha,main_beta,inclusion_probability,beta_bernoulli_alpha,beta_bernoulli_beta,beta_bernoulli_alpha_between,beta_bernoulli_beta_between,dirichlet_alpha, andlambdaare deprecated formals: passing one warns and is translated into the corresponding prior object, so old calls keep working for now.edge_priortakes a prior object (bernoulli_prior(),beta_bernoulli_prior(),sbm_prior()); the old character values are still accepted through a deprecation branch. The replacements areinteraction_prior,threshold_prior,means_prior,precision_scale_prior, andedge_prior. Note thatpairwise_scale = stranslates tocauchy_prior(scale = s), preserving the 0.1.6.3 family, so a deprecated call and a call at the new default are not the same model. extract_category_thresholds()is deprecated in favour ofextract_main_effects(), which covers category thresholds, continuous means, and precision diagonal entries in one call.
**Changed output and semantics.**
extract_ess()reports the Rao-Blackwellized effective sample size for the edge (or difference) indicators — then_effcolumn of the fit summary's inclusion table — where 0.1.6.3 returned the indicator chain's transition-based ESS. A 0.1.6.3-era call therefore gets different numbers with no warning. The extractor family is now coherent: the Rao-Blackwellized inclusion probability (extract_posterior_inclusion_probabilities()), its R-hat (extract_rhat()), and its ESS all describe the same estimate. Fits made with bgms < 0.2.0.0 carry no Rao-Blackwellized draws, so a default call on such a fit falls back to the transition ESS without warning, while an explicitestimator = "rb"errors.- The Rao-Blackwellized estimate is the canonical inclusion probability throughout a fit:
extract_posterior_inclusion_probabilities()defaults toestimator = "rb"(with"raw"still available) andfit$posterior_mean_indicatorreports it. Numbers quoted from a 0.1.6.3 fit will not reproduce exactly; the two estimate the same quantity, the Rao-Blackwellized one with lower variance. - The fit summary's inclusion table has different columns. It now reports the Rao-Blackwellized inclusion probability with a continuous Monte Carlo standard error (
mcse), effective sample size (n_eff), and split-R-hat (Rhat), beside the per-direction transition counts (n0->1,n1->0). The transition-basedn_eff_mixtcolumn is gone (see Deprecated). The three Rao-Blackwellized columns areNAwhere the Rao-Blackwellized draws are constant to double precision, which places the inclusion probability at its numerical bound, and are computed everywhere else. - On a
bgmCompare()fit the Rao-Blackwellized inclusion probabilities areNAfor indicators the sampler never updated — the main-effect differences, unlessmain_difference_selection = TRUE. **A previously all-numeric matrix can now containNA**, which breaks downstream code that assumes otherwise. TheNAis honest, and the contrast withbgm()is the point: an always-included edge indicator inbgm()is still *proposed* at every iteration, so the Rao-Blackwellized accumulators see its conditional inclusion odds and report a finite Bayes factor. An unselected main-difference indicator is never proposed at all, so there is no Rao-Blackwellized quantity to report — the entry isNAexactly when the indicator was never visited, not because a number was lost. Useestimator = "raw"for the old all-numeric behaviour, or filter onis.na(). - R-hat is the classic split-R-hat (Gelman et al. 2013 / Stan;
Rhat = sqrt(var_plus / W)withvar_plus = (n-1)/n * W + B/n). 0.1.6.3 applied the Brooks-Gelman degrees-of-freedom adjustment used bycoda::gelman.diag, which collapsed to a data-independentsqrt(5/3) ~ 1.29on nearly-saturated binary edge (or difference) indicators — the typical shape of a decisive edge, where one split sub-chain carries a brief excursion and the rest are constant — so the most decisive edges were flagged as unconverged. Reported R-hat changes slightly for all parameters (the adjustment factor was near 1 for healthy chains) and substantially for near-saturated indicators, which now report values near 1, orNAwhen every chain is identical. Chains stuck constant at different values report+Infinstead ofNA. See the diagnostics vignette for how to read indicator R-hat alongside the transition counts and the inclusion probability. - Fitted objects from
bgm()andbgmCompare()are S7 class objects (new dependency:S7). All existing$,[[, andnames()access patterns continue to work. When an incompatibleeasybgmversion is loaded, bgms returns plain S3 lists for backwards compatibility; this shim will be removed in a future release. The compatibility mode is chosen when the fit object is constructed, so loadeasybgmbefore fitting when the fit is meant for use with an oldereasybgm. summary()on abgmsfit returns an additionalquadraticelement (the precision diagonal, reported on the residual-variance scale for continuous and mixed fits) and carries amain_labelattribute.
New features
**New model classes.**
- Gaussian graphical models:
bgm(x, variable_type = "continuous")fits a GGM with Bayesian edge selection. Sampling uses NUTS on a free-element Cholesky (theta-space) parameterization of the precision matrix, which keeps the precision matrix positive-definite by construction; adaptive-metropolis is also available. - A conjugate GGM Gibbs sampler:
update_method = "gibbs"fits a GGM with a row-by-row update of the precision matrix, with or without edge selection. It needs no step-size or proposal tuning and supports a Normal or Cauchy prior on the edges. Continuous data only. - With
update_method = "gibbs"and edge selection, the first 15% of warmup runs the full model so the precision matrix settles, and edge selection is active for the remaining 85%. Both windows scale with the warmup budget. - Mixed MRF models:
bgm()accepts a per-variablevariable_typevector that mixes"ordinal","blume-capel", and"continuous"types, to estimate networks with both discrete and continuous variables.simulate.bgms()andpredict.bgms()support mixed models. - Missing-data imputation now covers the new model classes:
na_action = "impute"integrates over missing values during MCMC sampling for continuous and mixed models as well as ordinal ones.
**Prior specification.**
- Priors are constructed by dedicated functions and passed as objects:
normal_prior(),cauchy_prior(), andbeta_prime_prior()for parameter priors;gamma_prior()andexponential_prior()for the precision diagonal;bernoulli_prior(),beta_bernoulli_prior(), andsbm_prior()for the edge prior. Each has aprint()method. The correspondingbgm()formals areinteraction_prior(pairwise slab),threshold_prior(category thresholds, defaultbeta_prime_prior(0.5, 0.5)— the 0.1.6.3main_alpha/main_betapair),means_prior(continuous means, defaultnormal_prior(scale = 1)),precision_scale_prior(precision diagonal), andedge_prior. gamma_prior()andexponential_prior()accept the rate aseta, the rate on the precision diagonal in the frame where the pairwise slab prior has unit scale. The raw rate is derived at fit time aseta / sfor interaction-prior scales, so the prior geometry is held fixed when the slab scale changes; at fixedeta, graph and partial-correlation inference is invariant to the slab scale. Applies to GGM and mixed MRF models.bgm(delta =)sets the exponent of the determinant tilt on the continuous precision block. It defaults toNULL, resolved at fit time to0.5 * log(p)over the continuous variables.bgmCompare(difference_family =)chooses the family of the prior on the group differences,"Normal"(the default) or"Cauchy"(0.1.6.3's fixed behaviour). It governs the pairwise-interaction differences and the main-effect threshold differences alike, and underdifference_selection = TRUEit is the slab of the spike-and-slab.
**Inclusion inference.**
- Rao-Blackwellized inclusion probabilities and Bayes factors, through
extract_posterior_inclusion_probabilities(estimator = "rb")andextract_inclusion_bf(). For each indicator update the sampler records the one-step drawJ = gamma + (1 - 2 gamma) alpha(pre-move stategamma, birth/death acceptance probabilityalpha), stored per chain and per edge infit$raw_samples$rb_inclusionalongside the raw indicator draws. AveragingJis a lower-variance estimator of the inclusion probability than the raw indic
The NEWS section is longer than shown here.
From NEWS.md in the release
Install
Health
- OK13 OK2026-09-08
- ERROR12 OK, 1 ERROR2026-09-07
- OK13 OK2026-08-05
- NOTE12 OK, 1 NOTE2026-08-01
- OK13 OK2026-06-09
Show 5 earlier changesHide 5 earlier changes
- ERROR12 OK, 1 ERROR2026-06-08
- OK13 OK2026-05-02
- NOTE12 OK, 2 NOTE2026-04-22
- ERROR11 OK, 2 NOTE, 1 ERROR2026-04-18
- NOTE12 OK, 2 NOTE2026-03-10
Documentation
- Help pages
- 69 (9 internal)includes a package overview page
- Examples that run
- 27%11 run in a plain check · 26 only when donttest examples are enabled (R CMD check --as-cran) · 1 never run · 3 hold no code
- Exported functions with examples
- 67%
- Documented parameters
- 96%
- Return-value docs
- 95%
- Help pages citing references
- 10% with a bibliography file
Downloads
Repository
- PRs merged (all time)
- 90%
- Median days to close, 50 most recently updated closed issues
- 43
- Median days to close, 50 most recently updated closed PRs
- 0
Stars over time
Forks over time
Issues over time
PRs over time
Commits over time
Commit identities over time
14 development-tooling and community-health practices detected across 7 families in the upstream repository
Checks run against github.com/bayesian-graphical-modelling-lab/bgms on 2026-10-18.
The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel
GitHub Pages site last deployed 2026-08-05
Show all practicesHide 3 practices
This repository shows signs of AI coding tools.
- GitHub Copilotfirst seen 2026-03-04Seen in the repository: .github/copilot-instructions.md
- Claude Codefirst seen 2026-04-27Named in .Rbuildignore: .claudeNamed in .gitignore: .claude
Dependencies
Installing bgms adds 12 packages (9 with compiled code, 21 MB of source tarballs). Heaviest: BH 14 MB, Rcpp 1.8 MB, rbibutils 1.1 MB.
Code & Tests
Datasets
People & History
Pick two releases to compare their code metrics.
- 0.2.0.0Latest2026-08-04 · current release · diff ↗ ·
added 23 exports
bernoulli_prior, beta_bernoulli_prior, beta_prime_prior, calibration_check, cauchy_prior, exponential_prior, extract_centrality, extract_inclusion_bf, extract_log_odds, extract_main_effects, extract_partial_correlations, extract_precision, extract_prior_inclusion_probabilities, gamma_prior, normal_prior, plot_edge_posterior, prior_sensitivity_check, sample_ggm_prior, sample_graph_prior, sample_sbm_prior, sbm_prior, summarize_zratio_gauge, verdicts - RR 4.6.0 released · 2026-04-24
- 0.1.6.3
- 0.1.6.22026-01-20 · diff ↗
- 0.1.6.1
- 0.1.6.02025-09-27 · diff ↗ ·
removed 2 exports
extract_main_difference.bgmCompare, extract_pairwise_difference.bgmCompareadded 1 export
extract_group_params - RR 4.5.0 released · 2025-04-11
- 0.1.4.22024-12-05 · diff ↗
- 0.1.4.12024-11-12 · diff ↗
- 0.1.42024-10-21 · diff ↗ ·
removed 1 export
extract_edge_priorsadded 7 exports
bgmCompare, extract_category_thresholds, extract_indicator_priors, extract_indicators, extract_main_difference.bgmCompare, extract_pairwise_difference.bgmCompare, extract_pairwise_interactions - 0.1.3.12024-05-15 · diff ↗ ·
added 5 exports
extract_arguments, extract_edge_indicators, extract_edge_priors, extract_pairwise_thresholds, extract_posterior_inclusion_probabilities - RR 4.4.0 released · 2024-04-24
- 0.1.3
- 0.1.22023-10-13 · diff ↗
- 0.1.12023-09-01 · diff ↗
- 0.1.02023-04-21
Show 2 earlier eventsHide 2 earlier events
- RR 4.3.0 released · 2023-04-21
- RR 4.2.0 released · 2022-04-22
Package metadata
- First published
- 2023-04-21
- Total releases
- 13 / 3 yrs
- License
- GPL (>= 2) OSI
- Copyright
- Includes datasets 'ADHD' and 'Boredom', which are licensed under CC-BY 4. See individual data documentation for license and citation.
- Minimum R
- ≥ 3.5
- Bundled data
- 7.3 KB / 3 files
- Download size
- 1.7 MB
Cite
Cite this package
Run in R for the authors' entry:
citation("bgms")The package provides a citation file, so citation() returns the authors' own entry.
It points to 10.1017/psy.2024.4, 10.1017/psy.2025.10060, 10.1037/met0000847.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-21, which the citation names so these numbers can be found later. More on citing and the projects behind them.