| Type: | Package |
| Title: | Gaussian Graphical Models with Latent Clustering Structure |
| Version: | 0.3.0 |
| Description: | Implements the Normal-Block model, a Gaussian graphical model with a latent clustering structure for the multivariate analysis of continuous data. The model clusters variables and, building on the graphical lasso, infers a network of statistical dependencies between clusters rather than between individual variables, for known or unknown clusterings, with an optional zero-inflation extension for data with an excess of exact zeros. A complementary family clusters variables by their regression response to covariates rather than by their covariance, sharing one profile per cluster. See Tous & Chiquet (2026) <doi:10.1016/j.csda.2026.108347> for the model itself and its variational expectation-maximization estimation procedure. |
| License: | GPL (≥ 3) |
| URL: | https://github.com/jchiquet/normalblockr, https://jchiquet.github.io/normalblockr/ |
| BugReports: | https://github.com/jchiquet/normalblockr/issues |
| Encoding: | UTF-8 |
| LazyData: | true |
| Depends: | R (≥ 4.1.0) |
| Imports: | Matrix, dplyr, tidyr, tibble, purrr, R6, ggplot2, igraph, sbm, corrplot, scales, MASS, stats, Rcpp |
| LinkingTo: | Rcpp, RcppArmadillo |
| Suggests: | testthat (≥ 3.0.0), aricode, covr, Metrics, rmarkdown, pheatmap, paletteer, ggthemes, knitr |
| Config/testthat/edition: | 3 |
| VignetteBuilder: | knitr |
| Config/roxygen2/version: | 8.1.0 |
| NeedsCompilation: | yes |
| Packaged: | 2026-09-11 17:43:32 UTC; jchiquet |
| Author: | Jeanne Tous [aut],
Nestor Ngalala Manguitini [ctb],
Julien Chiquet |
| Maintainer: | Julien Chiquet <julien.chiquet@inrae.fr> |
| Repository: | CRAN |
| Date/Publication: | 2026-09-11 18:10:02 UTC |
normalblockr: Gaussian Graphical Models with Latent Clustering Structure
Description
Implements the Normal-Block model, a Gaussian graphical model with a latent clustering structure for the multivariate analysis of continuous data. The model clusters variables and, building on the graphical lasso, infers a network of statistical dependencies between clusters rather than between individual variables, for known or unknown clusterings, with an optional zero-inflation extension for data with an excess of exact zeros. A complementary family clusters variables by their regression response to covariates rather than by their covariance, sharing one profile per cluster. See Tous & Chiquet (2026) doi:10.1016/j.csda.2026.108347 for the model itself and its variational expectation-maximization estimation procedure.
Author(s)
Maintainer: Julien Chiquet julien.chiquet@inrae.fr (ORCID)
Authors:
Julien Chiquet julien.chiquet@inrae.fr (ORCID)
Jeanne Tous jeanne.tous@inrae.fr
Other contributors:
Nestor Ngalala Manguitini [contributor]
See Also
Useful links:
Report bugs at https://github.com/jchiquet/normalblockr/issues
Bayesian Information Criterion for a Normal-Block Model
Description
Extracts the (variational) BIC of a fitted normal-block model, computed as 'deviance + log(n) * nb_param' (lower is better).
Usage
## S3 method for class 'NormalBlockBase'
BIC(object, ...)
Arguments
object |
An object of class NormalBlockBase. |
... |
not used, only here for S3 compatibility |
Value
A scalar: the (variational) BIC.
Examples
ex_data <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex_data$Y, ex_data$X)
model <- normal_block(data, blocks = 3, control = NB_control(verbose = FALSE))
BIC(model)
Bayesian Information Criterion for a Collection of Normal-Block Models
Description
Returns the (variational) BIC of every model in a collection of normal-block models.
Usage
## S3 method for class 'NormalBlockCollection'
BIC(object, ...)
Arguments
object |
An object inheriting from NormalBlockCollection. |
... |
not used, only here for S3 compatibility |
Value
A numeric vector of BIC values, one per model in the collection.
Examples
ex_data <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex_data$Y, ex_data$X)
models <- normal_block(data, blocks = 2:5, control = NB_control(verbose = FALSE))
BIC(models)
NB_control
Description
Control the model settings and various optimization parameters
Usage
NB_control(
niter = 500,
threshold = 1e-04,
fixed_point_niter = 5,
sparsity_weights = NULL,
sparsity_penalties = NULL,
n_sparsity_penalties = 30,
min_ratio = 0.01,
fixed_tau = FALSE,
clustering_init = NULL,
verbose = TRUE,
heuristic = FALSE,
noise_covariance = NULL,
refine = FALSE
)
Arguments
niter |
number of iterations in model optimization |
threshold |
loglikelihood / elbo threshold under which optimization stops |
fixed_point_niter |
number of sweeps of the tau update for Normal-Block-Mean with unknown clusters. Each sweep visits the rows of tau sequentially and maximizes the ELBO exactly in each, so it can never decrease the ELBO. |
sparsity_weights |
weights with which the penalty should be applied in case sparsity is required, non-0 values on the diagonal mean diagonal shall be penalized too (default is non-penalized diagonal and 1s off-diagonal) |
sparsity_penalties |
list of penalties the user wants to test, other parameters are only used if penalties is not specified |
n_sparsity_penalties |
number of penalties to test. |
min_ratio |
ratio for sparsity between max penalty (0 edge penalty) and min penalty to test |
fixed_tau |
whether tau should be fixed at clustering_init during optimization useful for calls to fixed_q models in stability_selection |
clustering_init |
how to obtain the initial clustering of the q unknown blocks: a heuristic name ("ward2", "kmeans", "sbm" or "spectral"), an actual clustering (a vector of labels or a p x q indicator matrix, or a list of either per q for a collection), or "best_of_inits" to try several heuristics per model and keep the best-ELBO fit (see [NormalBlockVarBase]'s 'best_of_inits()'; not supported with 'sparsity = TRUE'). Default 'NULL', resolved per model family at fit time: "ward2" for variance-block models, "kmeans" for mean-block models ("ward2" was benchmarked substantially worse there – see [NormalBlockMeanBase]). See 'inst/methods_initialization_and_refine.md' for the heuristics' rationale, why no single one dominates, and how this interacts with 'refine' (below). |
verbose |
telling if information should be printed during optimization |
heuristic |
whether to use the heuristic approach (moment-based, no (V)EM recursion) instead of the full (V)EM. Default is FALSE. In heuristic mode, no likelihood/ELBO is computed, so 'entropy', 'loglik', 'BIC', 'ICL' and 'EBIC' are all 'NA' on the resulting model. |
noise_covariance |
shape of the residual covariance. Variance-block models accept "diagonal" (variable-specific) or "spherical" (common); mean-block models, whose Sigma is the full p x p residual covariance, also accept "full". Default 'NULL', resolved per model family at fit time to "diagonal" – except for a mean-block model with 'sparsity > 0', which implies "full" since a penalty on a diagonal precision matrix would have nothing to act on (explicitly asking for both is an error). The mean-block "diagonal"/"spherical" variants need no matrix inversion, hence no 'n > p' requirement, and they select the number of clusters markedly better than a full Sigma once p approaches n: the p(p+1)/2 covariance parameters otherwise drown the mean structure BIC/ICL are weighing. Use "full" when the residual associations are themselves of interest. |
refine |
for [NormalBlockVarCollectionClusters] only: whether 'optimize()' should automatically call 'refine()' afterwards. Default 'FALSE' since it adds real cost; call 'collection$refine()' directly at any point afterwards for the same effect without setting this. |
Value
A named list of parameters to pass to [normal_block()]'s 'control' argument.
Root Base Class for Normal-Block Models
Description
R6 abstract class shared by the variance-block ([NormalBlockVarBase]) and mean-block ([NormalBlockMeanBase]) model families.
Public fields
dataobject of NormalBlockData class, with responses and design matrix
Active bindings
inference_methodinference procedure used (heuristic or integrated with EM)
nnumber of samples
pnumber of responses per sample
dnumber of variables (dimensions in X)
qnumber of blocks
n_edgesnumber of edges of the network (non null coefficient of the sparse precision matrix Omega)
objectiveevolution of the objective function during (V)EM algorithm
loglik(or its variational lower bound)
deviance(or its variational lower bound)
BIC(or its variational lower bound)
entropyEntropy of the conditional distribution when applicable
ICLvariational lower bound of the ICL
EBICvariational lower bound of the EBIC
criteriaa vector with loglik, BIC and number of parameters
sparsity(overall sparsity parameter)
sparsity_term(sparsity_term term in log-likelihood due to sparsity)
membershipscluster memberships
clusteringgiven as the list of elements contained in each cluster
cluster_sizesgiven as a vector of cluster sizes
elements_per_clustergiven as the list of elements contained in each cluster
Methods
Public methods
NormalBlockBase$new()
Create a new ['NormalBlockBase'] object.
Usage
NormalBlockBase$new(data, q, sparsity = 0, control, zero_inflation = FALSE)
Arguments
dataobject of NormalBlockData class, with responses and design matrix
qnumber of block/cluster
sparsitysparsity penalty on the network density
controlstructured list of more specific parameters, to generate with NB_control
zero_inflationwhether the concrete subclass models zero-inflation; set by the ZI subclasses themselves, not meant to be set by the end user. When 'FALSE', the (costly) zero-inflation probability fit ('kappa'/'B0') is skipped entirely, since it would otherwise never be used downstream.
Returns
A new ['NormalBlockBase'] object
NormalBlockBase$update()
Update a ['NormalBlockBase'] object
All possible parameters of the child classes
Usage
NormalBlockBase$update( B = NA, dm1 = NA, C = NA, Omega = NA, gamma = NA, mu = NA, kappa = NA, alpha = NA, M = NA, S = NA, Psi = NA, Phi = NA, Lambda = NA, ll_list = NA, warm_started = NA, clustering_init = NA )
Arguments
Bregression matrix [all]
dm1diagonal vector of inverse variance matrix (variables level) [NBVar]
Cthe matrix of groups memberships (posterior probabilities) [all]
Omegainverse variance matrix (cluster-level for Normal Block models, variable-level for Normal Mean Block models) [all]
gammavariance of posterior distribution of W [NBVar - known]
mumean for posterior distribution of W [NBVar - known]
kappavector of zero-inflation probabilities [ZINBVar, ZINBMean]
alphavector of groups probabilities [NBVar]
Mvariational mean for posterior distribution of W [NBVar - unknown]
Svariational diagonal of variances for posterior distribution of W [NBVar - unknown]
Psivariational expectation of C'Omega C, intermediary term in calculations [NBMean - unknown]
Phivariational correction term used in the Psi/ELBO computations [NBMean - unknown]
Lambdavariational correction term used in the Sigma-hat update [NBMean - unknown]
ll_listlist of log-lik (elbo) values
warm_startedwhether 'optim_initialize()' should treat the model as already initialized (reuse B/Omega/dm1/C/alpha/M/S as they stand) rather than recomputing a fresh heuristic initialization. Set by [warm_start_from()] and by [split()]/[merge()].
clustering_initinitial clustering
Returns
Update the current ['normal'] object
NormalBlockBase$optimize()
calls optimization (EM or heuristic) and updates relevant fields
Usage
NormalBlockBase$optimize( control = list(niter = 500, threshold = 1e-04, fixed_point_niter = 5), warn = TRUE )
Arguments
controla list for controlling the optimization process
warnwhether to warn when the (V)EM stops at the 'niter' cap without reaching 'threshold' (see 'private$warn_if_not_converged()'). Set to 'FALSE' for deliberately-truncated trial fits (cheap candidate scoring in 'candidates_split()'/'candidates_merge()', the sparsity-path warm-start probe in [NormalBlockCollectionSparsity]) where stopping at the cap is expected and not a sign of trouble.
Returns
optimizes the model and updates its parameters
NormalBlockBase$best_of_inits()
Try several clustering-initialization heuristics and keep the best-ELBO converged fit (see 'NB_control(clustering_init = )' and 'inst/methods_initialization_and_refine.md' for the rationale). Every candidate is first screened with a short 'trial_niter' run (same idea as 'candidates_split()'/'candidates_merge()'), and only the 'max_training' best-screened ones are fully retrained with 'control'.
Usage
NormalBlockBase$best_of_inits( inits = private$default_inits, trial_niter = 10, max_training = 2, control = list(niter = 500, threshold = 1e-04, fixed_point_niter = 5) )
Arguments
initsvector of clustering-heuristic names to try; defaults to the model family's own preferred order ('private$default_inits')
trial_niternumber of (V)EM iterations used to cheaply screen every candidate in 'inits' before fully retraining the best few
max_traininghow many of the screened candidates (best 'loglik' after 'trial_niter' iterations) get fully retrained with 'control'
control'optimize()' control list ('niter'/'threshold') used for the final full retraining of the 'max_training' best candidates
Returns
a new, already-optimized model. Does not mutate the current object; reassign the result ('model <- model$best_of_inits()').
NormalBlockBase$candidates_split()
generate and select a set of candidate models by splitting the clusters of the current model
Usage
NormalBlockBase$candidates_split(trial_niter = 5)
Arguments
trial_niternumber of (V)EM iterations used to cheaply score each candidate before the caller fully re-optimizes the best few – kept short on purpose.
NormalBlockBase$candidates_merge()
generate and select a set of candidate models by merging the clusters of the current model
Usage
NormalBlockBase$candidates_merge(max_candidates = 30, trial_niter = 2)
Arguments
max_candidatesmerge candidates are, unlike split's, quadratic in q ('choose(q, q-2)' pairs): beyond 'max_candidates' pairs, only the most promising ones are actually built and trial-optimized, ranked by the family's own 'private$merge_score()'. Set to 'Inf' to always try every pair.
trial_nitersee [candidates_split()]
NormalBlockBase$predict()
Predicts observations Y for new covariates X, in Y's original units (like '$fitted', so that predicting on the training X reproduces it).
Usage
NormalBlockBase$predict(new_X)
Arguments
new_Xnew set of covariates.
Returns
A n*p prediction matrix for new observations
NormalBlockBase$latent_network()
Extract interaction network in the latent space, as a matrix rather than a plot – see '$plot_network()' to plot it instead.
Usage
NormalBlockBase$latent_network(type = c("partial_cor", "support", "precision"))
Arguments
typeedge value in the network. Can be "support" (binary edges), "precision" (coefficient of the precision matrix) or "partial_cor" (partial correlation between species)
Returns
a square matrix of size 'self$q'
NormalBlockBase$plot_loglik()
plots the evolution of the objective (log-likelihood or ELBO) across the (V)EM iterations of the last call to 'optimize()'.
Usage
NormalBlockBase$plot_loglik(show_increment = TRUE)
Arguments
show_incrementwhether to add a second panel with the (log10) absolute increment between iterations and the convergence 'threshold' (distinguishes true convergence from a flat-looking objective trace).
Returns
a ['ggplot2::ggplot'] graph
NormalBlockBase$plot_network()
plot the latent network. To extract the network as a matrix instead of plotting it, use '$latent_network()'.
Usage
NormalBlockBase$plot_network(
type = c("partial_cor", "support"),
output = c("igraph", "corrplot"),
edge.color = c("#F8766D", "#00BFC4"),
remove.isolated = FALSE,
node.labels = NULL,
layout = igraph::layout_in_circle,
plot = TRUE
)
Arguments
typeedge value in the network. Either "precision" (coefficient of the precision matrix) or "partial_cor" (partial correlation between species).
outputOutput type. Either 'igraph' (for the network) or 'corrplot' (for the adjacency matrix)
edge.colorLength 2 color vector. Color for positive/negative edges. Default is 'c("#F8766D", "#00BFC4")'. Only relevant for igraph output.
remove.isolatedif 'TRUE', isolated node are remove before plotting. Only relevant for igraph output.
node.labelsvector of character. The labels of the nodes. The default will use the column names ot the response matrix.
layoutan optional igraph layout. Only relevant for igraph output.
plotlogical. Should the final network be displayed or only sent back to the user. Default is 'TRUE'.
NormalBlockBase$plot()
plots the evolution of the objective during model optimization (see 'plot_loglik()')
Usage
NormalBlockBase$plot()
NormalBlockBase$print()
User friendly print method
Usage
NormalBlockBase$print(model = paste("A", self$who_am_I, ".\n"))
Arguments
modelFirst line of the print output
NormalBlockBase$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockBase$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
# An internal abstract base class, never instantiated directly -- see
# normal_block() for how concrete models are created and fitted.
Base Class for a Collection of Normal-Block Models
Description
Shared scaffolding for the collections explored by [get_model()]/ [normal_block()]: a sweep over sparsity penalties (['NormalBlockVarCollectionSparsity']), over the number of clusters (['NormalBlockVarCollectionClusters']), or over both (['NormalBlockVarCollectionClustersSparsity']). Concrete subclasses set 'private$progress_field'/'private$progress_label' in their 'initialize()' and provide their own 'get_best_model()', delegating the (row of 'self$criteria' minimizing a criterion) lookup to 'private$best_id()'.
Public fields
modelslist of models (or sub-collections) explored by the collection
controlstore the list of user-defined model settings and optimization parameters
Active bindings
criteriaa data frame with the values of some criteria for the collection of models
logliknot defined for a collection: accessing it raises an informative error. Use ‘logLik()' for every model’s log-likelihood, or '$get_best_model()$loglik' for a single one.
Methods
Public methods
NormalBlockCollection$optimize()
optimizes every model (or sub-collection) in the collection
Usage
NormalBlockCollection$optimize( control = list(niter = 500, threshold = 1e-04, verbose = TRUE) )
Arguments
controloptimization parameters (niter and threshold). When 'control$clustering_init' is '"best_of_inits"', each leaf model is fit via its own 'best_of_inits()' instead of a plain 'optimize()'.
NormalBlockCollection$print()
User-friendly print method: model type and the range of q/sparsity explored. See 'summary()' for the full criteria table.
Usage
NormalBlockCollection$print()
NormalBlockCollection$summary()
Summarize the collection: model type, full criteria table, and the range of q/sparsity explored.
Usage
NormalBlockCollection$summary()
Returns
An object of class 'summary.NormalBlockCollection', printed with a dedicated [print.summary.NormalBlockCollection()] method.
NormalBlockCollection$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockCollection$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
# An internal abstract base class, never instantiated directly -- see
# normal_block() for how collections (NormalBlockVarCollectionClusters,
# NormalBlockVarCollectionSparsity, NormalBlockVarCollectionClustersSparsity)
# are actually created and fitted.
Base Class for a Collection of Models over a Range of Cluster Counts
Description
Shared scaffolding for [NormalBlockVarCollectionClusters] and [NormalBlockMeanCollectionClusters]: everything that does not depend on the model family (model lookup, model selection, the criteria plot and the split/merge 'refine()' search). Concrete subclasses only build 'self$models' in their 'initialize()' and name themselves through 'who_am_I'.
Super class
NormalBlockCollection -> NormalBlockCollectionClusters
Active bindings
q_listnumber of blocks
Methods
Public methods
Inherited methods
NormalBlockCollectionClusters$get_model()
returns the unknown-clusters model corresponding to given q
Usage
NormalBlockCollectionClusters$get_model(q)
Arguments
qnumber of blocks asked by user
Returns
A unknown-clusters object with given value q
NormalBlockCollectionClusters$get_best_model()
Extract best model in the collection
Usage
NormalBlockCollectionClusters$get_best_model(
crit = c("ICL", "BIC", "EBIC", "deviance")
)
Arguments
crita character for the criterion used to performed the selection. Either "ICL" or "BIC". "ICL" is the default criterion
Returns
a ['unknown-clusters'] object
NormalBlockCollectionClusters$plot()
Display various outputs (goodness-of-fit criteria, robustness, diagnostic) associated with a collection of network fits (a ['Networkfamily'])
Usage
NormalBlockCollectionClusters$plot(
criteria = c("deviance", "ICL", "BIC", "EBIC")
)
Arguments
criteriavector of characters. The criteria to plot in 'c("deviance", "BIC", "ICL")'. Defaults to all of them.
Returns
a ['ggplot2::ggplot'] graph
NormalBlockCollectionClusters$optimize()
optimizes every model in the collection, then – if 'control$refine' is 'TRUE' (see [NB_control()], default 'FALSE') – calls [refine()] automatically.
Usage
NormalBlockCollectionClusters$optimize( control = list(niter = 500, threshold = 1e-04, verbose = TRUE) )
Arguments
controloptimization parameters (niter, threshold, verbose)
NormalBlockCollectionClusters$refine()
Tries to improve every model in the collection with a short split-and-reoptimize trial seeded from its smaller-q neighbor ('"split"'), a short merge-and-reoptimize trial seeded from its larger-q neighbor ('"merge"'), or both (the default); a candidate replaces the original only if it strictly lowers the deviance, so this can only improve (or leave unchanged) each model it touches. Only contiguous q pairs ('q' and 'q -/+ 1', both present in the collection) are refined. See 'inst/methods_initialization_and_refine.md' for the rationale and empirical evidence.
Usage
NormalBlockCollectionClusters$refine(
trial_niter = 2,
max_candidates = 30,
directions = c("split", "merge"),
verbose = self$control$verbose
)
Arguments
trial_niternumber of EM iterations used for the cheap trial candidates (passed to 'candidates_split()'/'candidates_merge()') before fully re-optimizing only the best one.
max_candidatespassed to 'candidates_merge()' (ignored for '"split"', which is never combinatorial in q) – see its documentation.
directionswhich neighbor(s) to seed refinement candidates from: '"split"' (smaller-q neighbor), '"merge"' (larger-q neighbor), or both (the default).
verbosewhether to print, for each q attempted, whether the candidate from that neighbor improved on it. Defaults to 'control$verbose' (the value set at construction, see [NB_control()]).
Returns
invisibly returns 'self'; improved models replace the originals in '$models' in place.
NormalBlockCollectionClusters$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockCollectionClusters$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
# An internal abstract base class, never instantiated directly -- see
# normal_block() for how collections are created and fitted.
Base Class for a Collection over Cluster Counts and Sparsity Levels
Description
Shared scaffolding for [NormalBlockVarCollectionClustersSparsity] and [NormalBlockMeanCollectionClustersSparsity]: a collection of sparsity sub-collections, one per q. Everything family-agnostic (two-key model lookup, model selection over both axes, the criteria heatmap) lives here; subclasses only build 'self$models' and name themselves.
Super class
NormalBlockCollection -> NormalBlockCollectionClustersSparsity
Active bindings
q_listnumber of blocks
sparsitylist of penalties used for each q
Methods
Public methods
Inherited methods
NormalBlockCollectionClustersSparsity$get_model()
returns a collection of models corresponding to given q or one single model if penalty is also given
Usage
NormalBlockCollectionClustersSparsity$get_model(q, sparsity = NA)
Arguments
qnumber of blocks asked by user.
sparsitysparsity penalty asked by user
Returns
either a sparsity sub-collection or a single model object
NormalBlockCollectionClustersSparsity$get_best_model()
Extract best model in the collection
Usage
NormalBlockCollectionClustersSparsity$get_best_model(
crit = c("ICL", "BIC", "EBIC")
)
Arguments
crita character for the criterion used to performed the selection. Either "BIC", "EBIC" or "ICL". "ICL" is the default criterion
Returns
a single fitted model object
NormalBlockCollectionClustersSparsity$plot()
Display various outputs (goodness-of-fit criteria, robustness, diagnostic) associated with a collection of network fits
Usage
NormalBlockCollectionClustersSparsity$plot(
criterion = c("deviance", "ICL", "BIC", "EBIC"),
n_intervals = NULL
)
Arguments
criterionThe criteria to plot in 'c("deviance", BIC", "EBIC", "ICL")'. Defaults deviance.
n_intervalsnumber of intervals into which the penalties range should be split
Returns
a ['ggplot2::ggplot'] heatmap
NormalBlockCollectionClustersSparsity$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockCollectionClustersSparsity$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
# An internal abstract base class, never instantiated directly -- see
# normal_block() for how collections are created and fitted.
Base Class for a Collection of Models over a Sparsity Path
Description
Shared scaffolding for [NormalBlockVarCollectionSparsity] and [NormalBlockMeanCollectionSparsity]: the warm-started path traversal, the penalty lookup and the criteria plot. Concrete subclasses derive the penalty grid in their 'initialize()' and provide their own 'get_best_model()' (only the variance-block family offers StARS).
Super class
NormalBlockCollection -> NormalBlockCollectionSparsity
Public fields
dataobject of NormalBlockData class, with responses and design matrix
Active bindings
qnumber of blocks
blocksgroup matrix or number of blocks
sparsitylist of sparsity penalties
Methods
Public methods
Inherited methods
NormalBlockCollectionSparsity$optimize()
optimizes every model in the sparsity path, warm-starting each one (after the first) from the previous, adjacent penalty's converged parameters (see the family's base class's 'warm_start_from()') instead of re-deriving everything from the heuristic clustering, the way the generic [NormalBlockCollection] 'optimize()' would. 'blocks' (hence q) is fixed across the whole path, only the sparsity penalty changes, so the warm start is always between models of matching shape.
Usage
NormalBlockCollectionSparsity$optimize( control = list(niter = 500, threshold = 1e-04, verbose = TRUE) )
Arguments
controloptimization parameters (niter and threshold)
NormalBlockCollectionSparsity$get_model()
returns the NormalBlockVarKnownClusters model corresponding to given penalty
Usage
NormalBlockCollectionSparsity$get_model(sparsity)
Arguments
sparsitysparsity penalty asked by user
Returns
A NormalBlockVarKnownClusters (sparse) object with given value penalty
NormalBlockCollectionSparsity$plot()
Display various outputs (goodness-of-fit criteria, robustness, diagnostic) associated with a collection of network fits (a collection)
Usage
NormalBlockCollectionSparsity$plot(
criteria = c("deviance", "BIC", "EBIC", "ICL"),
log.x = TRUE
)
Arguments
criteriavector of characters. The criteria to plot in 'c("deviance", BIC", "EBIC", "ICL")'. Defaults to all of them.
log.xlogical: should the x-axis be represented in log-scale? Default is 'TRUE'.
Returns
a ['ggplot2::ggplot'] graph
NormalBlockCollectionSparsity$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockCollectionSparsity$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
# An internal abstract base class, never instantiated directly -- see
# normal_block() for how collections are created and fitted.
Data Container for Normal-Block Models
Description
R6 class holding the responses and design matrix used to fit a normal-block model.
Public fields
Ythe matrix of responses (rescaled column-wise if 'scale = TRUE')
Y_scalethe per-column standard deviation Y was divided by (all 1's if 'scale = FALSE')
Xthe matrix of covariates
X0the matrix of zero-inflation covariates, if applicable
formuladescribes the relationship between Y and X, and X0 if applicable, useful if not all of X's or X0's covariates should be used, should be formatted ~ X1 + X2... | Z1 + Z2... with the Normal formula before the | and the ZI formula after the |
nsample size
dnumber of covariates
d0number of zero-inflation covariates, if applicable
pnumber of variables
XtXuseful for inference in some cases
XtXm1inverse of XtX, useful for inference
XtYuseful for inference
npYtotal number of non zeros in Y
nYtotal number of non zeros for each column/variable in Y
zeroswhere are the zero in Y
zeros_barwhere are the non-zeros in Y
Methods
Public methods
NormalBlockData$new()
Create a new ['NormalBlockData'] object.
Usage
NormalBlockData$new( Y, X, X0 = NULL, formula = NULL, scale = TRUE, zeros = NULL )
Arguments
Ythe matrix of responses (called Y in the model).
Xdesign matrix (called X in the model).
X0zero-inflation design matrix, if applicable.
formuladescribes the relationship between Y and X, useful if not all of X's covariates should be used.
scalewhether to rescale each column of Y by its own standard deviation (no centering). Default TRUE, see the class-level documentation for the rationale and its limits.
zerosan optional 0/1 matrix of structural zeros, overriding the default 'Y == 0'.
NormalBlockData$ols_fit()
Ordinary-least-squares fit of Y on X, with its residuals and their covariance. Computed once and memoized.
Usage
NormalBlockData$ols_fit()
Returns
a list with 'B' (d x p), 'R' (n x p residuals) and 'Sigma' (p x p residual covariance)
NormalBlockData$zi_ols_fit()
Masked counterpart of 'ols_fit()': a per-variable weighted least-squares fit of B under the zero-inflation mask, with its inverse residual variances and residuals (see 'zi_weighted_fit()'). Computed once and memoized.
Usage
NormalBlockData$zi_ols_fit()
Returns
a list with 'B' (d x p), 'dm1' (p) and 'R' (n x p masked residuals)
NormalBlockData$zi_fit()
Zero-inflation component: 'p' independent logistic regressions of each variable's zero pattern on 'X0', and the fixed contribution they make to the log-likelihood. The (V)EM never revisits these, so they are a property of the data rather than of a model.
Usage
NormalBlockData$zi_fit()
Returns
a list with 'B0' (d0 x p), 'kappa' (n x p zero-inflation probabilities) and 'ZI_cond_mean' (a scalar)
NormalBlockData$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockData$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex$Y, ex$X)
c(n = data$n, p = data$p, d = data$d)
Base Class for Mean-Block Models
Description
R6 abstract class for the Normal-Block models where the clustering structures the mean (mu_i = C B' X_i).
Super class
NormalBlockBase -> NormalBlockMeanBase
Active bindings
model_para list with the matrices of the model parameters: B (covariates), dm1 (species variance), Omega (groups precision matrix)). On the internal fitting scale (‘self$data$Y', possibly column-rescaled by 'NormalBlockData(scale = TRUE)'): use '$B_original'/'$dm1_original' for the same quantities converted back to Y’s original units.
nb_paramnumber of parameters in the model
sparsity_weights(weights associated to each pair of groups)
Methods
Public methods
Inherited methods
NormalBlockMeanBase$new()
Create a new ['NormalBlockMeanBase'] object.
Usage
NormalBlockMeanBase$new( data, q, sparsity = 0, control = NB_control(), zero_inflation = FALSE )
Arguments
dataobject of NormalBlockData class, with responses and design matrix
qnumber of block/cluster
sparsitysparsity penalty on the network density
controlstructured list of more specific parameters, to generate with NB_Mean_control
zero_inflationwhether the concrete subclass models zero-inflation; set by the ZI subclasses themselves, not meant to be set by the end user.
Returns
A new ['NormalBlockMeanBase'] object
NormalBlockMeanBase$predict()
Predicts observations Y for new covariates X, in Y's original units. The mean-block mean is mu_i = C B' X_i, so the cluster-level predictor has to be mapped back to the variables through C.
Usage
NormalBlockMeanBase$predict(new_X)
Arguments
new_Xnew set of covariates.
Returns
A n*p prediction matrix for new observations
NormalBlockMeanBase$warm_start_from()
Seed this model's starting parameters from another, already-optimized model with the same q, instead of the heuristic clustering-derived values set at construction time. Used by [split()]/[merge()].
Usage
NormalBlockMeanBase$warm_start_from(other)
Arguments
othera [NormalBlockMeanBase] object, already optimized
Returns
Update the current object in place with ‘other'’s parameters
NormalBlockMeanBase$split()
Create a clone of the current ['NormalBlockMeanBase'] object after splitting cluster 'index'. Unlike the variance-block family, Omega and the sparsity weights are p x p here and do not depend on q, so they carry over unchanged; only C (tau) and B (one column per cluster) are affected. Variables are split by their current noise variance (1 / diag(Omega)) around its within-cluster median, the same criterion [NormalBlockVarBase]'s 'split()' uses via 'dm1', since 'diag(Omega)' plays the same per-variable-precision role here.
Usage
NormalBlockMeanBase$split(index, in_place = FALSE)
Arguments
indexindex (integer) of the cluster to split
in_placeshould the split be applied to the object itself, or should a copy be sent? Default FALSE (send a copy)
Returns
A new ['NormalBlockMeanBase'] object
NormalBlockMeanBase$merge()
Create a clone of the current ['NormalBlockMeanBase'] object after merging clusters 'indices'
Usage
NormalBlockMeanBase$merge(indices, in_place = FALSE)
Arguments
indicesindices (couple of integer) of the clusters to merge
in_placeshould the merge be applied to the object itself, or should a copy be sent? Default FALSE (send a copy)
Returns
A new ['NormalBlockMeanBase'] object
NormalBlockMeanBase$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockMeanBase$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
# An internal abstract base class, never instantiated directly -- use
# NormalBlockMeanKnownClusters / NormalBlockMeanUnknownClusters.
Collection of Mean-Block Models over a Range of Cluster Counts
Description
R6 class for a collection of mean-block models ([NormalBlockMeanBase]) with different numbers of clusters (q). Inherits its scaffolding ('print()'/'summary()'/'plot()'/'optimize()', the 'criteria' table) from [NormalBlockCollection]. Unlike [NormalBlockVarCollectionClusters], there is no SBM-path shortcut here: the shared clustering-heuristic registry's cov()/correlation-based methods are ill-suited to the mean-block family (see [NormalBlockMeanBase]'s own default), so each q is fit independently.
Super classes
NormalBlockCollection -> NormalBlockCollectionClusters -> NormalBlockMeanCollectionClusters
Active bindings
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockMeanCollectionClusters$new()
Create a new ['NormalBlockMeanCollectionClusters'] object.
Usage
NormalBlockMeanCollectionClusters$new( mydata, q_list, zero_inflation = FALSE, sparsity = 0, control = NB_control() )
Arguments
mydataobject of NormalBlockData class, with responses and design matrix
q_listlist of q values (number of groups) in the collection
zero_inflationwhether Y carries structural zeros; every model in the collection is then zero-inflated (Sigma diagonal or spherical only, see [NormalBlockMeanBase])
sparsitysparsity penalty on the network density
controlstructured list of more specific parameters, to generate with NB_control
Returns
A new ['NormalBlockMeanCollectionClusters'] object
NormalBlockMeanCollectionClusters$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockMeanCollectionClusters$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_mean_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex$Y, ex$X)
models <- normal_block(data, blocks = 2:5, model = "mean")
models$plot(c("BIC", "ICL"))
models$get_best_model()
Collection of Mean-Block Models over Cluster Counts and Sparsity Levels
Description
R6 class for a collection of mean-block models ([NormalBlockMeanBase]) over both a range of cluster counts (q) and a sparsity path, i.e. one [NormalBlockMeanCollectionSparsity] per q. Mirrors [NormalBlockVarCollectionClustersSparsity], minus its SBM-path shortcut for the initial clustering (ill-suited to this family, see [NormalBlockMeanCollectionClusters]).
Super classes
NormalBlockCollection -> NormalBlockCollectionClustersSparsity -> NormalBlockMeanCollectionClustersSparsity
Active bindings
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockMeanCollectionClustersSparsity$new()
Create a new ['NormalBlockMeanCollectionClustersSparsity'] object.
Usage
NormalBlockMeanCollectionClustersSparsity$new( mydata, q_list, control = NB_control() )
Arguments
mydataobject of NormalBlockData class, with responses and design matrix
q_listlist of q values (number of groups) in the collection
controlstructured list of parameters to handle sparsity control
Returns
A new ['NormalBlockMeanCollectionClustersSparsity'] object
NormalBlockMeanCollectionClustersSparsity$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockMeanCollectionClustersSparsity$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_mean_data(n = 60, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex$Y, ex$X)
models <- normal_block(data, blocks = 2:4, sparsity = TRUE, model = "mean",
control = NB_control(n_sparsity_penalties = 4))
models$plot("BIC")
models$get_best_model("BIC")
Collection of Mean-Block Models over a Sparsity Path
Description
R6 class for a collection of mean-block models ([NormalBlockMeanBase]) with a fixed clustering (or a fixed number of blocks) and different sparsity levels applied to the p x p precision matrix of the variables. Mirrors [NormalBlockVarCollectionSparsity], minus the StARS/stability selection path, which relies on 'fixed_tau', not supported by the mean-block VEM.
Super classes
NormalBlockCollection -> NormalBlockCollectionSparsity -> NormalBlockMeanCollectionSparsity
Active bindings
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockMeanCollectionSparsity$new()
Create a new ['NormalBlockMeanCollectionSparsity'] object.
Usage
NormalBlockMeanCollectionSparsity$new(mydata, blocks, control = NB_control())
Arguments
mydataobject of NormalBlockData class, with responses and design matrix
blockseither a clustering matrix (known, fixed clustering) or a single integer (number of blocks to infer)
controlstructured list of parameters to handle sparsity control
Returns
A new ['NormalBlockMeanCollectionSparsity'] object
NormalBlockMeanCollectionSparsity$get_best_model()
Extract best model in the collection
Usage
NormalBlockMeanCollectionSparsity$get_best_model(
crit = c("BIC", "EBIC", "ICL")
)
Arguments
crita character for the criterion used to perform the selection, either "BIC", "EBIC" or "ICL". Default is BIC
Returns
a ['NormalBlockMeanBase'] object
NormalBlockMeanCollectionSparsity$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockMeanCollectionSparsity$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_mean_data(n = 60, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex$Y, ex$X)
models <- normal_block(data, blocks = 3, sparsity = TRUE, model = "mean",
control = NB_control(n_sparsity_penalties = 5))
models$plot(c("BIC", "EBIC"))
Mean-Block Model with Known Clustering
Description
R6 class for a Normal-Block-Mean model with a known clustering.
Super classes
NormalBlockBase -> NormalBlockMeanBase -> NormalBlockMeanKnownClusters
Active bindings
fittedY values predicted by the model, in Y's original units
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockBase$best_of_inits()NormalBlockBase$candidates_merge()NormalBlockBase$candidates_split()NormalBlockBase$latent_network()NormalBlockBase$optimize()NormalBlockBase$plot()NormalBlockBase$plot_loglik()NormalBlockBase$plot_network()NormalBlockBase$print()NormalBlockBase$update()NormalBlockMeanBase$merge()NormalBlockMeanBase$predict()NormalBlockMeanBase$split()NormalBlockMeanBase$warm_start_from()
NormalBlockMeanKnownClusters$new()
Create a new ['NormalBlockMeanKnownClusters'] object.
Usage
NormalBlockMeanKnownClusters$new(data, C, sparsity = 0, control = NB_control())
Arguments
dataobject of NormalBlockData class, with responses and design matrix
Cclustering matrix C_jk = 1 if species j belongs to cluster k
sparsityto apply on variance matrix when calling GLASSO
controlstructured list of more specific parameters, to generate with NB_control
Returns
A new ['NormalBlockMeanKnownClusters'] object
NormalBlockMeanKnownClusters$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockMeanKnownClusters$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_mean_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex$Y, ex$X)
model <- normal_block(data, blocks = ex$parameters$C, model = "mean")
model$plot()
Mean-Block Model with Unknown Clustering
Description
R6 class for a Normal-Block-Mean model with a fixed number of clusters (but unknown clustering), inferred by variational EM.
Super classes
NormalBlockBase -> NormalBlockMeanBase -> NormalBlockMeanUnknownClusters
Active bindings
fittedY values predicted by the model, in Y's original units
var_para list with the variational parameter: tau (posterior group probabilities)
nb_paramnumber of parameters in the model
entropyEntropy of the conditional distribution The only latent variable is the clustering, so the entropy of the variational distribution reduces to -sum(tau * log(tau)).
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockBase$best_of_inits()NormalBlockBase$candidates_merge()NormalBlockBase$candidates_split()NormalBlockBase$latent_network()NormalBlockBase$optimize()NormalBlockBase$plot()NormalBlockBase$plot_loglik()NormalBlockBase$plot_network()NormalBlockBase$print()NormalBlockBase$update()NormalBlockMeanBase$merge()NormalBlockMeanBase$predict()NormalBlockMeanBase$split()NormalBlockMeanBase$warm_start_from()
NormalBlockMeanUnknownClusters$new()
Create a new ['NormalBlockMeanUnknownClusters'] object.
Usage
NormalBlockMeanUnknownClusters$new( data, q, sparsity = 0, control = NB_control() )
Arguments
dataobject of NormalBlockData class, with responses and design matrix
qnumber of clusters
sparsityto apply on variance matrix when calling GLASSO
controlstructured list of more specific parameters, to generate with NB_control
Returns
A new ['NormalBlockMeanUnknownClusters'] object
NormalBlockMeanUnknownClusters$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockMeanUnknownClusters$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_mean_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex$Y, ex$X)
model <- normal_block(data, blocks = 3, model = "mean")
model$clustering
Base Class for Variance-Block Models
Description
R6 abstract class for the sparse Normal-Block models, where the clustering structures the latent covariance.
Super class
NormalBlockBase -> NormalBlockVarBase
Active bindings
B_originalregression coefficients (d x p), converted back to Y's original units (undoing ‘NormalBlockData(scale = TRUE)'’s column-wise rescaling, if any). Use 'model_par$B' instead for the coefficients on the internal fitting scale.
d0number of zi variables (dimensions in X0)
model_para list with the matrices of the model parameters: B (covariates), dm1 (species variance), Omega (groups precision matrix)). On the internal fitting scale (‘self$data$Y', possibly column-rescaled by 'NormalBlockData(scale = TRUE)') – use '$B_original'/'$dm1_original' for the same quantities converted back to Y’s original units.
nb_paramnumber of parameters in the model
sparsity_weights(weights associated to each pair of groups)
dm1_originalinverse residual variance per variable (1 / Var(Y_j)), converted back to Y's original units. Use 'model_par$dm1' instead for the internal fitting scale. With 'noise_covariance = "spherical"', 'model_par$dm1' is a single value repeated p times; once converted back per-variable, the p values returned here generally differ from one another whenever Y's columns were rescaled by different factors.
Methods
Public methods
Inherited methods
NormalBlockBase$best_of_inits()NormalBlockBase$candidates_merge()NormalBlockBase$candidates_split()NormalBlockBase$latent_network()NormalBlockBase$optimize()NormalBlockBase$plot()NormalBlockBase$plot_loglik()NormalBlockBase$plot_network()NormalBlockBase$predict()NormalBlockBase$print()NormalBlockBase$update()
NormalBlockVarBase$new()
Create a new ['NormalBlockVarBase'] object.
Usage
NormalBlockVarBase$new( data, q, sparsity = 0, control = NB_control(), zero_inflation = FALSE )
Arguments
dataobject of NormalBlockData class, with responses and design matrix
qnumber of block/cluster
sparsitysparsity penalty on the network density
controlstructured list of more specific parameters, to generate with NB_control
zero_inflationwhether the concrete subclass models zero-inflation; set by the ZI subclasses themselves, not meant to be set by the end user. When 'FALSE', the (costly) zero-inflation probability fit ('kappa'/'B0') is skipped entirely, since it would otherwise never be used downstream.
Returns
A new ['NormalBlockVarBase'] object
NormalBlockVarBase$warm_start_from()
Seed this model's starting parameters from another, already-optimized model with the same q, instead of a fresh heuristic clustering. Used by [NormalBlockVarCollectionSparsity] to warm-start each penalty in a sparsity path from the previous one's solution.
Usage
NormalBlockVarBase$warm_start_from(other)
Arguments
othera [NormalBlockVarBase] object, already optimized
Returns
Update the current object in place with ‘other'’s parameters
NormalBlockVarBase$split()
Create a clone of the current ['NormalBlockVarBase'] object after splitting cluster 'cl' We split the cluster according to the species variances
Usage
NormalBlockVarBase$split(index, in_place = FALSE)
Arguments
indexindex (integer) of the cluster to split
in_placeshould the split applied to the object itself, or should a copy be sent? default FALSE (send a copy)
Returns
A new ['NormalBlockVarBase'] object
NormalBlockVarBase$merge()
Create a clone of the current ['NormalBlockVarBase'] object after merging clusters 'cl1' and 'cl2'
Usage
NormalBlockVarBase$merge(indices, in_place = FALSE)
Arguments
indicesindices (couple of integer) of the clusters to merge
in_placeshould the split applied to the object itself, or should a copy be sent? default FALSE (send a copy)
Returns
A new ['NormalBlockVarBase'] object
NormalBlockVarBase$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockVarBase$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
# An internal abstract base class, never instantiated directly. See
# normal_block() for how concrete models (NormalBlockVarKnownClusters,
# NormalBlockVarUnknownClusters, and their zero-inflated variants) are
# actually created and fitted.
Collection of Normal-Block Models over a Range of Cluster Counts
Description
R6 class for a collection of normal-block models with different number of clusters (q) and a fixed sparsity level.
Super classes
NormalBlockCollection -> NormalBlockCollectionClusters -> NormalBlockVarCollectionClusters
Active bindings
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockVarCollectionClusters$new()
Create a new ['NormalBlockVarCollectionClusters'] object.
Usage
NormalBlockVarCollectionClusters$new( mydata, q_list, zero_inflation = FALSE, sparsity = 0, control = NB_control() )
Arguments
mydataobject of NormalBlockData class, with responses and design matrix
q_listlist of q values (number of groups) in the collection
zero_inflationwhether the models in the collection should be zero-inflated or not
sparsitysparsity penalty on the network density
controlstructured list of more specific parameters, to generate with NB_control
Returns
A new ['NormalBlockVarCollectionClusters'] object
NormalBlockVarCollectionClusters$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockVarCollectionClusters$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex$Y, ex$X)
models <- normal_block(data, blocks = 2:4, control = NB_control(verbose = FALSE))
models$get_best_model("ICL")$q
Collection of Normal-Block Models over Cluster Counts and Sparsity Levels
Description
R6 class for a collection of normal-block models with different number of clusters (q) and different sparsity levels.
Super classes
NormalBlockCollection -> NormalBlockCollectionClustersSparsity -> NormalBlockVarCollectionClustersSparsity
Active bindings
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockVarCollectionClustersSparsity$new()
Create a new ['NormalBlockVarCollectionClustersSparsity'] object.
Usage
NormalBlockVarCollectionClustersSparsity$new( mydata, q_list, zero_inflation = FALSE, control = NB_control() )
Arguments
mydataobject of NormalBlockData class, with responses and design matrix
q_listlist of q values (number of groups) in the collection
zero_inflationboolean to specify whether data is zero-inflated
controlstructured list of parameters to handle sparsity control
Returns
A new ['NormalBlockVarCollectionClustersSparsity'] object
NormalBlockVarCollectionClustersSparsity$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockVarCollectionClustersSparsity$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex$Y, ex$X)
models <- normal_block(data, blocks = 2:3, sparsity = TRUE,
control = NB_control(verbose = FALSE, n_sparsity_penalties = 3))
models$get_best_model("BIC")$q
Collection of Normal-Block Models over a Sparsity Path
Description
R6 class for a collection of normal-block models with a fixed clustering (blocks) and different sparsity levels.
Super classes
NormalBlockCollection -> NormalBlockCollectionSparsity -> NormalBlockVarCollectionSparsity
Active bindings
sparsity_detailslist of information about model's penalties
criteriaa data frame with the values of some criteria ((approximated) log-likelihood, BIC) for the collection of models
stability_pathmeasure of edges stability based on StARS method
stabilitymean edge stability along the sparsity penalties path
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockVarCollectionSparsity$new()
Create a new ['NormalBlockVarCollectionSparsity'] object.
Usage
NormalBlockVarCollectionSparsity$new( mydata, blocks, zero_inflation = FALSE, control = NB_control() )
Arguments
mydataobject of NormalBlockData class, with responses and design matrix
blockseither a clustering matrix (known, fixed clustering) or a single integer (number of blocks to infer)
zero_inflationboolean to specify whether data is zero-inflated
controlstructured list of parameters to handle sparsity control
Returns
A new ['NormalBlockVarCollectionSparsity'] object
NormalBlockVarCollectionSparsity$get_best_model()
Extract best model in the collection
Usage
NormalBlockVarCollectionSparsity$get_best_model(
crit = c("BIC", "EBIC", "ICL", "StARS"),
stability = 0.9
)
Arguments
crita character for the criterion used to performed the selection.
stabilityif criterion = "StARS" gives level of stability required. Either "BIC", "EBIC", "ICL" or "StARS". Default is BIC
Returns
a ['NormalBlockVarUnknownClusters'] object
NormalBlockVarCollectionSparsity$stability_selection()
Compute the stability path by stability selection
Usage
NormalBlockVarCollectionSparsity$stability_selection( subsamples = NULL, n_subsamples = 10 )
Arguments
subsamplesa list of vectors describing the subsamples. The number of vectors (or list length) determines the number of subsamples used in the stability selection. Automatically set to 20 subsamples with size '10*sqrt(n)' if 'n >= 144' and '0.8*n' otherwise following Liu et al. (2010) recommendations.
n_subsamplesnumber of subsamples to create if the subsamples are not given
NormalBlockVarCollectionSparsity$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockVarCollectionSparsity$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex$Y, ex$X)
models <- normal_block(data, blocks = ex$parameters$C, sparsity = TRUE,
control = NB_control(verbose = FALSE, n_sparsity_penalties = 5))
models$get_best_model("BIC")$sparsity
Normal-Block Model with Known Clustering
Description
R6 class for a normal-block model with known clustering.
Super classes
NormalBlockBase -> NormalBlockVarBase -> NormalBlockVarKnownClusters
Active bindings
posterior_para list with the parameters of posterior distribution W | Y
entropyEntropy of the conditional distribution
fittedY values predicted by the model, in Y's original units
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockBase$best_of_inits()NormalBlockBase$candidates_merge()NormalBlockBase$candidates_split()NormalBlockBase$latent_network()NormalBlockBase$optimize()NormalBlockBase$plot()NormalBlockBase$plot_loglik()NormalBlockBase$plot_network()NormalBlockBase$predict()NormalBlockBase$print()NormalBlockBase$update()NormalBlockVarBase$merge()NormalBlockVarBase$split()NormalBlockVarBase$warm_start_from()
NormalBlockVarKnownClusters$new()
Create a new ['NormalBlockVarKnownClusters'] object.
Usage
NormalBlockVarKnownClusters$new(data, C, sparsity = 0, control = NB_control())
Arguments
dataobject of NormalBlockVarData class, with responses and design matrix
Cclustering matrix C_jk = 1 if species j belongs to cluster k
sparsityto apply on variance matrix when calling GLASSO
controlstructured list of more specific parameters, to generate with NB_control
Returns
A new ['NormalBlockVarKnownClusters'] object
NormalBlockVarKnownClusters$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockVarKnownClusters$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex$Y, ex$X)
model <- normal_block(data, blocks = ex$parameters$C, control = NB_control(verbose = FALSE))
model$clustering
Normal-Block Model with Unknown Clustering
Description
R6 class for a normal-block model with a fixed number of clusters (but unknown clustering).
Super classes
NormalBlockBase -> NormalBlockVarBase -> NormalBlockVarUnknownClusters
Public fields
fixed_tauwhether tau should be fixed at clustering_init during optimization, useful for stability selection
Active bindings
model_para list with the matrices of the model parameters: B (covariates), dm1 (species variance), Omega (groups precision matrix))
nb_paramnumber of parameters in the model
var_para list with the matrices of the variational parameters: M (means), S (variances), tau (posterior group probabilities)
entropyEntropy of the conditional distribution
fittedY values predicted by the model, in Y's original units
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockBase$best_of_inits()NormalBlockBase$candidates_merge()NormalBlockBase$candidates_split()NormalBlockBase$latent_network()NormalBlockBase$optimize()NormalBlockBase$plot()NormalBlockBase$plot_loglik()NormalBlockBase$plot_network()NormalBlockBase$predict()NormalBlockBase$print()NormalBlockBase$update()NormalBlockVarBase$merge()NormalBlockVarBase$split()NormalBlockVarBase$warm_start_from()
NormalBlockVarUnknownClusters$new()
Create a new ['NormalBlockVarUnknownClusters'] object.
Usage
NormalBlockVarUnknownClusters$new( data, q, sparsity = 0, control = NB_control() )
Arguments
datacontains the matrix of responses (Y) and the design matrix (X).
qrequired number of groups
sparsitysparsity penalty to add on blocks precision matrix for sparsity
controlstructured list for specific parameters
Returns
A new ['NormalBlockVarUnknownClusters'] object
NormalBlockVarUnknownClusters$clone()
The objects of this class are cloneable with this method.
Usage
NormalBlockVarUnknownClusters$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex$Y, ex$X)
model <- normal_block(data, blocks = 3, control = NB_control(verbose = FALSE))
model$clustering
Zero-Inflated Mean-Block Model with Known Clustering
Description
R6 class for a zero-inflated Normal-Block-Mean model with a known clustering. Sigma is diagonal or spherical here. See [NormalBlockMeanBase] for why a full one is out of reach under a mask.
Super classes
NormalBlockBase -> NormalBlockMeanBase -> ZINormalBlockMeanKnownClusters
Active bindings
fittedY values predicted by the model, in Y's original units
model_para list with model parameters: B, Omega and kappa (zero-inflation probabilities)
nb_paramnumber of parameters in the model
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockBase$best_of_inits()NormalBlockBase$candidates_merge()NormalBlockBase$candidates_split()NormalBlockBase$latent_network()NormalBlockBase$optimize()NormalBlockBase$plot()NormalBlockBase$plot_loglik()NormalBlockBase$plot_network()NormalBlockBase$print()NormalBlockBase$update()NormalBlockMeanBase$merge()NormalBlockMeanBase$predict()NormalBlockMeanBase$split()NormalBlockMeanBase$warm_start_from()
ZINormalBlockMeanKnownClusters$new()
Create a new ['ZINormalBlockMeanKnownClusters'] object.
Usage
ZINormalBlockMeanKnownClusters$new( data, C, sparsity = 0, control = NB_control() )
Arguments
dataobject of NormalBlockData class, with responses and design matrix
Cclustering matrix C_jk = 1 if species j belongs to cluster k
sparsityunused here, kept for signature symmetry (must be 0)
controlstructured list of more specific parameters, to generate with NB_control
Returns
A new ['ZINormalBlockMeanKnownClusters'] object
ZINormalBlockMeanKnownClusters$clone()
The objects of this class are cloneable with this method.
Usage
ZINormalBlockMeanKnownClusters$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_mean_data(n = 50, p = 20, d = 1, q = 3)
Y <- ex$Y; Y[runif(length(Y)) < 0.2] <- 0
data <- NormalBlockData$new(Y, ex$X)
model <- normal_block(data, blocks = ex$parameters$C, model = "mean",
zero_inflation = TRUE)
model$clustering
Zero-Inflated Mean-Block Model with Unknown Clustering
Description
R6 class for a zero-inflated Normal-Block-Mean model with a fixed number of clusters (but unknown clustering), inferred by variational EM. Sigma is diagonal or spherical here. See [NormalBlockMeanBase] for why a full one is out of reach under a mask.
Super classes
NormalBlockBase -> NormalBlockMeanBase -> ZINormalBlockMeanUnknownClusters
Active bindings
fittedY values predicted by the model, in Y's original units
var_para list with the variational parameter: tau (posterior group probabilities)
model_para list with model parameters: B, Omega and kappa (zero-inflation probabilities)
nb_paramnumber of parameters in the model
entropyEntropy of the conditional distribution
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockBase$best_of_inits()NormalBlockBase$candidates_merge()NormalBlockBase$candidates_split()NormalBlockBase$latent_network()NormalBlockBase$optimize()NormalBlockBase$plot()NormalBlockBase$plot_loglik()NormalBlockBase$plot_network()NormalBlockBase$print()NormalBlockBase$update()NormalBlockMeanBase$merge()NormalBlockMeanBase$predict()NormalBlockMeanBase$split()NormalBlockMeanBase$warm_start_from()
ZINormalBlockMeanUnknownClusters$new()
Create a new ['ZINormalBlockMeanUnknownClusters'] object.
Usage
ZINormalBlockMeanUnknownClusters$new( data, q, sparsity = 0, control = NB_control() )
Arguments
dataobject of NormalBlockData class, with responses and design matrix
qnumber of clusters
sparsityunused here, kept for signature symmetry (must be 0)
controlstructured list of more specific parameters, to generate with NB_control
Returns
A new ['ZINormalBlockMeanUnknownClusters'] object
ZINormalBlockMeanUnknownClusters$clone()
The objects of this class are cloneable with this method.
Usage
ZINormalBlockMeanUnknownClusters$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_mean_data(n = 50, p = 20, d = 1, q = 3)
Y <- ex$Y; Y[runif(length(Y)) < 0.2] <- 0
data <- NormalBlockData$new(Y, ex$X)
model <- normal_block(data, blocks = 3, model = "mean", zero_inflation = TRUE)
model$clustering
Zero-Inflated Normal-Block Model with Known Clustering
Description
R6 class for a zero-inflated normal-block model with a known clustering.
Super classes
NormalBlockBase -> NormalBlockVarBase -> ZINormalBlockVarKnownClusters
Active bindings
posterior_para list with the parameters of posterior distribution W | Y
entropyEntropy of the conditional distribution
nb_paramnumber of parameters in the model
model_para list with model parameters: B (covariates), dm1 (species variance), Omega (groups precision matrix), kappa (zero-inflation probabilities)
fittedY values predicted by the model, in Y's original units
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockBase$best_of_inits()NormalBlockBase$candidates_merge()NormalBlockBase$candidates_split()NormalBlockBase$latent_network()NormalBlockBase$optimize()NormalBlockBase$plot()NormalBlockBase$plot_loglik()NormalBlockBase$plot_network()NormalBlockBase$predict()NormalBlockBase$print()NormalBlockBase$update()NormalBlockVarBase$merge()NormalBlockVarBase$split()NormalBlockVarBase$warm_start_from()
ZINormalBlockVarKnownClusters$new()
Create a new ['ZINormalBlockVarKnownClusters'] object.
Usage
ZINormalBlockVarKnownClusters$new( data, C, sparsity = 0, control = NB_control() )
Arguments
dataobject of NormalBlockData class, with responses and design matrix
Cclustering matrix C_jk = 1 if species j belongs to cluster k
sparsityto apply on variance matrix when calling GLASSO
controlstructured list of more specific parameters, to generate with NB_control
Returns
A new ['ZINormalBlockVarKnownClusters'] object
ZINormalBlockVarKnownClusters$clone()
The objects of this class are cloneable with this method.
Usage
ZINormalBlockVarKnownClusters$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3, kappa = rep(0.3, 20))
data <- NormalBlockData$new(ex$Y, ex$X)
model <- normal_block(data, blocks = ex$parameters$C, zero_inflation = TRUE,
control = NB_control(verbose = FALSE))
model$clustering
Zero-Inflated Normal-Block Model with Unknown Clustering
Description
R6 class for a zero-inflated normal-block model with a fixed number of clusters (but unknown clustering).
Super classes
NormalBlockBase -> NormalBlockVarBase -> ZINormalBlockVarUnknownClusters
Public fields
fixed_tauwhether tau should be fixed at clustering_init during optimization, useful for stability selection
Active bindings
nb_paramnumber of parameters in the model
var_para list with variational parameters
model_para list with model parameters: B (covariates), dm1 (species variance), Omega (blocks precision matrix), kappa (zero-inflation probabilities)
entropyEntropy of the conditional distribution
fittedY values predicted by the model, in Y's original units
who_am_Ia method to print what model is being fitted
Methods
Public methods
Inherited methods
NormalBlockBase$best_of_inits()NormalBlockBase$candidates_merge()NormalBlockBase$candidates_split()NormalBlockBase$latent_network()NormalBlockBase$optimize()NormalBlockBase$plot()NormalBlockBase$plot_loglik()NormalBlockBase$plot_network()NormalBlockBase$predict()NormalBlockBase$print()NormalBlockBase$update()NormalBlockVarBase$merge()NormalBlockVarBase$split()NormalBlockVarBase$warm_start_from()
ZINormalBlockVarUnknownClusters$new()
Create a new ['ZINormalBlockVarUnknownClusters'] object.
Usage
ZINormalBlockVarUnknownClusters$new( data, q, sparsity = 0, control = NB_control() )
Arguments
dataobject of NormalBlockVarData class, with responses and design matrix
qrequired number of groups
sparsityto apply on variance matrix when calling GLASSO
controlstructured list of more specific parameters
Returns
A new ['ZINormalBlockVarUnknownClusters'] object
ZINormalBlockVarUnknownClusters$clone()
The objects of this class are cloneable with this method.
Usage
ZINormalBlockVarUnknownClusters$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
ex <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3, kappa = rep(0.3, 20))
data <- NormalBlockData$new(ex$Y, ex$X)
model <- normal_block(data, blocks = 3, zero_inflation = TRUE,
control = NB_control(verbose = FALSE))
model$clustering
Breast cancer proteomics data (TCGA, RPPA)
Description
Reverse-phase protein array (RPPA) measurements of 163 proteins across 346 breast cancer tumor samples from The Cancer Genome Atlas (TCGA), along with the PAM50 molecular subtype of each sample. Used as the running example in Tous & Chiquet (2026).
Usage
brca_rppa
Format
A list with 3 elements:
- expr
a 346 x 163 numeric matrix of protein expression levels (normalized log-ratios), samples in rows (named by TCGA sample identifier), proteins in columns.
- covariates
a data frame with one row per sample, in the same order as the rows of 'expr': 'sampleId' (matches 'rownames(expr)') and 11 clinical variables, factors unless noted otherwise – 'CN_CLUSTER' (copy-number cluster, 5 levels), 'CONVERTED_STAGE' (tumor stage), 'ER_STATUS' (estrogen receptor status), 'FRACTION_GENOME_ALTERED' (numeric, in \[0, 1\]), 'HER2_STATUS', 'METASTASIS_CODED', 'METHYLATION_CLUSTER' (5 levels), 'MUTATION_COUNT' (numeric), 'PAM50_SUBTYPE' (5 levels: Basal-like, HER2-enriched, Luminal A, Luminal B, Normal-like), 'RPPA_CLUSTER' (7 levels) and 'AGE' (numeric, in years). A few of these have missing values for a handful of samples ('FRACTION_GENOME_ALTERED', 'HER2_STATUS', 'METASTASIS_CODED').
- gene_annotation
a data frame with one row per protein, in the same order as the columns of 'expr': 'protein' (matches 'colnames(expr)'), 'entrezGeneId', 'hugoGeneSymbol', 'type' ('"protein-coding"' or '"phosphoprotein"') and 'go_bp_term' (a Gene Ontology Biological Process classification, one term per protein, or '"unknown"' if none could be found – see Details).
Details
'go_bp_term' is derived from 'org.Hs.eg.db', queried by 'entrezGeneId' for '"protein-coding"' rows. Phospho-site antibodies ('type == "phosphoprotein"', e.g. '"EGFR_PY1068"') carry a placeholder, negative 'entrezGeneId' (there is no separate gene for a specific phosphorylation site, only the underlying gene) and are instead queried by gene symbol (the part of 'protein' before the first '"_"'). Each protein typically has dozens of GO Biological Process terms; 'go_bp_term' keeps, for each protein, the one term shared by the most *other* proteins in this dataset – giving a handful of non-trivial groups rather than one near-singleton group per protein, more useful for comparing against an inferred clustering. See 'data-raw/brca_rppa_go_annotation.R' for the full extraction code.
Source
TCGA breast cancer cohort (Cancer Genome Atlas Network, 2012, doi:10.1038/nature11412), downloaded via cBioPortal ('brca_tcga_pub' study, https://www.cbioportal.org). 'go_bp_term' (see Details) was added afterwards from 'org.Hs.eg.db'.
Examples
expr <- brca_rppa$expr
X <- model.matrix(~ 0 + PAM50_SUBTYPE, data = brca_rppa$covariates)
nb_data <- NormalBlockData$new(expr, X)
table(brca_rppa$gene_annotation$go_bp_term)
Extract Model Coefficients
Description
Extract coefficients from a normal-block model.
Usage
## S3 method for class 'NormalBlockBase'
coef(object, ...)
Arguments
object |
An object of class NormalBlockBase. |
... |
not used, only here for S3 compatibility |
Value
A matrix of coefficients extracted from the model.
Extract Fitted Values
Description
Extract fitted values from a normal-block model.
Usage
## S3 method for class 'NormalBlockBase'
fitted(object, ...)
Arguments
object |
An object of class NormalBlockBase. |
... |
not used, only here for S3 compatibility |
Value
A matrix of fitted values extracted from the object.
Generate Normal Block Mean Data
Description
A function to draw data from the normal block model (see details). The function returns both the generated data and the corresponding model parameters, in a list.
Usage
generate_normal_block_mean_data(
n = 100,
p = 40,
d = 1,
q = 3,
kappa = 0,
omega_structure = "erdos-renyi",
u_v = c(0.3, 0.1),
SNR = 5,
alpha = rep(1/q, q),
range_X = c(0, 10)
)
Arguments
n |
number of individuals. Default to 100. |
p |
number of variables. Default to 40. |
d |
number of covariates. Default to 1. |
q |
number of groups. Default to 3. |
kappa |
vector (or scalar) of variable-wise probability of zero inflation. Default to 0. |
omega_structure |
the structure of the graph on which the precision matrix between variables is built. Can be a symmetric matrix with p rows/columns or a character picked in "erdos-renyi", "preferential_attachment", "community" in which case a graph is drawn with sensible generation parameters. See generate_precision_matrix for details. |
u_v |
two-size vector of positive numbers v and u controlling the generation of the precision matrix Omega: v scales the off-diagonal elements of the precision matrix (magnitude of partial correlations), and u is a positive number added to the diagonal elements to ensure positive-definiteness. The default value is c(0.3, 0.1). |
SNR |
Signal to noise ratio: magnitude of the regression parameters B will be adjusted so that tr(var(XB)) and tr(Sigma) match the desired SNR. |
alpha |
the q-size vector of group proportion. Default to rep(1/q, q) |
range_X |
A 2-size vector defining the range of the uniform distribution used to draw values in X, the regressor matrix. Default is c(0, 10) |
Value
A named list with the following element - Y a matrix of responses - X a regressor/design matrix - a list of model parameters, encompassing - B: matrix of regression coefficients - C: matrix of group membership - Omega: precision matrix of the variables - Sigma: covariance matrix of the variables - kappa: vector of ZI inflation probabilities (one per variable)
Generate Normal Block Var Data
Description
A function to draw data from the normal block model (see details). The function returns both the generated data and the corresponding model parameters, in a list.
Usage
generate_normal_block_var_data(
n = 100,
p = 40,
d = 1,
q = 3,
kappa = 0,
omega_structure = "erdos-renyi",
u_v = c(0.3, 0.1),
SNR = 0.75,
alpha = rep(1/q, q),
range_X = c(0, 10),
range_D = c(0.5, 1.5)
)
Arguments
n |
number of individuals. Default to 100. |
p |
number of variables. Default to 40. |
d |
number of covariates. Default to 1. |
q |
number of groups. Default to 3. |
kappa |
vector (or scalar) of variable-wise probability of zero inflation. Default to 0. |
omega_structure |
the structure of the graph on which the precision matrix between groups is built. Can be a symmetric matrix with q rows/columns or a character picked in "erdos-renyi", "preferential_attachment", "community" in which case a graph is drawn with sensible generation parameters. See generate_precision_matrix for details. |
u_v |
two-size vector of positive numbers v and u controlling the generation of the precision matrix Omega: v scales the off-diagonal elements of the precision matrix (magnitude of partial correlations), and u is a positive number added to the diagonal elements to ensure positive-definiteness. The default value is c(0.3, 0.1). |
SNR |
Signal to noise ratio: magnitude of the regression parameters B will be adjusted so that tr(var(XB)) and tr(Sigma) match the desired SNR. |
alpha |
the q-size vector of group proportion. Default to rep(1/q, q) |
range_X |
A 2-size vector defining the range of the uniform distribution used to draw values in X, the regressor matrix. Default is c(0, 10) |
range_D |
A 2-size vector defining the range of the uniform distribution used to draw values in D, the diagonal matrix of variances of variables. Default is c(0.5, 1.5) |
Value
A named list with the following element - Y a matrix of responses - X a regressor/design matrix - a list of model parameters, encompassing - B: matrix of regression coefficients - C: matrix of group membership - D: diagonal matrix of variance of the variables - Omega: precision matrix of the groups - Sigma: covariance matrix of the groups - kappa: vector of ZI inflation probabilities (one per variable)
Create a Normal-Block Model Object
Description
Creates the appropriate normal-block model (or collection of models) depending on the parametrization.
Usage
get_model(
data,
blocks,
sparsity = 0,
zero_inflation = FALSE,
control = NB_control(),
model = c("var", "mean")
)
Arguments
data |
contains the matrix of responses (Y) and the design matrix (X). |
blocks |
either an integer (number of blocks), a vector of integer (list of possible number of block) or a p * q matrix (for indicating block membership when its known) |
sparsity |
boolean to say whether the model should have a changing penalty OR float to run model with a single penalty value |
zero_inflation |
boolean to indicate if Y is zero-inflated and adjust fitted model as a consequence |
control |
a list-like structure for detailed control on parameters should be generated with NB_control() for collections of sparse models |
model |
which model family to fit, "var" (the default) or "mean" – see [normal_block()] |
Check if an Object is a Normal-Block Model
Description
Checks if a model is of class [NormalBlockBase()], i.e. any normal-block model (variance-block or mean-block family).
Usage
isNB(object)
Arguments
object |
An R object. |
Value
A boolean telling whether object inherits from the NormalBlockBase class.
Extract Log-Likelihood of a Normal-Block Model
Description
Returns the (variational) log-likelihood of a fitted normal-block model as a '"logLik"' object, compatible with [stats::AIC()] and [stats::BIC()].
Usage
## S3 method for class 'NormalBlockBase'
logLik(object, ...)
Arguments
object |
An object of class NormalBlockBase. |
... |
not used, only here for S3 compatibility |
Value
An object of class '"logLik"'. The numeric value is the log-likelihood or its variational lower bound (ELBO). Attributes 'df' and 'nobs' hold the number of parameters and observations.
Examples
ex_data <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex_data$Y, ex_data$X)
model <- normal_block(data, blocks = 3, control = NB_control(verbose = FALSE))
logLik(model)
Extract Log-Likelihood of a Collection of Normal-Block Models
Description
Returns the log-likelihood of every model in a collection of normal-block models (see [NormalBlockVarCollectionClusters], [NormalBlockVarCollectionSparsity], [NormalBlockVarCollectionClustersSparsity]).
Usage
## S3 method for class 'NormalBlockCollection'
logLik(object, ...)
Arguments
object |
An object inheriting from NormalBlockCollection. |
... |
not used, only here for S3 compatibility |
Value
A numeric vector of log-likelihood values, one per model in the collection.
Examples
ex_data <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex_data$Y, ex_data$X)
models <- normal_block(data, blocks = 2:5, control = NB_control(verbose = FALSE))
logLik(models)
Normal-block model
Description
Fit a normal-block model with a variational or heuristic algorithm
Usage
normal_block(
data,
blocks,
sparsity = 0,
zero_inflation = FALSE,
control = NB_control(),
model = c("var", "mean")
)
Arguments
data |
NormalBlockData object, contains the matrix of responses (Y, n x p) and the design matrix (X, n x d), must be created with NormalBlockData$new. |
blocks |
either a integer (number of blocks), a vector of integer (list of possible number of block) or a p * q matrix (for indicating block membership when its known) |
sparsity |
either TRUE to run the optimization for different sparsity penalty values OR float to run model with a single sparsity penalty value |
zero_inflation |
boolean to indicate if Y is zero-inflated and adjust fitted model as a consequence |
control |
a list-like structure for detailed control on parameters should be generated with NB_control(). |
model |
which model family to fit: "var" (the default) structures the clustering in the latent covariance (see [NormalBlockVarBase]), "mean" structures it in the mean (mu_i = C B' X_i, see [NormalBlockMeanBase]). The mean-block family covers the same collections as the variance-block one ([NormalBlockMeanCollectionClusters], [NormalBlockMeanCollectionSparsity] and their crossing, [NormalBlockMeanCollectionClustersSparsity]) – each q simply fit independently, without the variance-block family's SBM-path shortcut. Zero-inflation is supported ([ZINormalBlockMeanKnownClusters], [ZINormalBlockMeanUnknownClusters], and collections of those over a range of q), with a diagonal or spherical Sigma only, hence not along a sparsity path – see [NormalBlockMeanBase]. |
Value
an R6 object with one of the model classes (or a collection of model objects).
Examples
## Normal Data
ex_data <- generate_normal_block_var_data(n=100, p=30, d=1, q=3)
data <- NormalBlockData$new(ex_data$Y, ex_data$X)
my_normal_block <- normal_block(data, blocks = 1:6)
my_normal_block$plot(c("deviance", "BIC", "ICL"))
Y_hat <- my_normal_block$get_best_model()$fitted
plot(data$Y, Y_hat, log = "xy"); abline(0,1)
## Normal Data with Zero Inflation
ex_data_zi <- generate_normal_block_var_data(n=50, p=50, d=1, q=3, kappa = rep(0.5,50))
zidata <- NormalBlockData$new(ex_data_zi$Y, ex_data_zi$X)
my_normal_block <- normal_block(zidata, blocks = 1:6, zero_inflation = TRUE)
## Mean-Block model (clustering in the mean rather than the covariance)
ex_mean <- generate_normal_block_mean_data(n=50, p=20, d=1, q=3)
mean_data <- NormalBlockData$new(ex_mean$Y, ex_mean$X)
my_mean_block <- normal_block(mean_data, blocks = 3, model = "mean")
Cluster variables in the mean, then in the residual covariance
Description
Fits the two model families one after the other: a mean-block model ([NormalBlockMeanBase]) groups the variables by how they respond to the covariates, then a variance-block model ([NormalBlockVarBase]) groups the residuals of that fit by how they co-vary. The two answer different questions and generally return unrelated partitions, so running both is often more informative than choosing one.
Usage
normal_block_sequential(
data,
blocks_mean,
blocks_var,
crit = c("ICL", "BIC"),
zero_inflation = FALSE,
control_mean = NB_control(verbose = FALSE),
control_var = NB_control(verbose = FALSE)
)
Arguments
data |
a [NormalBlockData] object |
blocks_mean |
number of clusters for the mean-block stage: an integer, a vector of integers to explore, or a p x q indicator matrix |
blocks_var |
idem for the variance-block stage, run on the residuals |
crit |
criterion used to pick a model when a range is explored, "ICL" (the default) or "BIC" |
zero_inflation |
whether Y carries structural zeros. Both stages are then zero-inflated, sharing the same mask: the second one would otherwise re-derive it from residuals, which are never exactly zero. |
control_mean |
control list for the mean-block stage, see [NB_control()] |
control_var |
control list for the variance-block stage |
Details
The second stage uses an intercept-only design on purpose: the covariate effects have already been removed by the first stage.
This is a heuristic two-stage estimator, not a joint model. On simulated data carrying two genuinely distinct structures it recovers both exactly (see 'inst/mean_block_analyses/sequential_mean_then_variance.R').
Value
an object of class 'normal_block_sequential', a list with the fitted 'mean' and 'var' models and the residual matrix 'residuals' handed from one stage to the other.
Examples
ex <- generate_normal_block_mean_data(n = 80, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex$Y, ex$X)
fit <- normal_block_sequential(data, blocks_mean = 3, blocks_var = 2)
fit
French stream fish community data (ONEMA / OFB electrofishing surveys)
Description
Fish biomass per species, aggregated by sampling station, together with environmental covariates for each station. Derived from the fish community monitoring of stream sections across metropolitan France (1995-2018) by the French Office for Biodiversity (formerly ONEMA, "Office National de l'Eau et des Milieux Aquatiques"), using electrofishing.
Usage
onema
Format
A list with 2 elements:
- biomass
a 399 x 46 numeric matrix of total biomass (grams) per species (3-letter species code, columns) and station (row names).
- covariates
a data frame with one row per station, in the same order as the rows of 'biomass': 'station' (matches 'rownames(biomass)') and 14 environmental variables – 'slope', 'alt' (altitude), 'd_source' (distance to source), 'strahler' (Strahler stream order), 'width_river_mean'/'width_river_cv', 'avg_depth_station_mean'/ 'avg_depth_station_cv', 'DBO_med'/'DBO_cv' (biological oxygen demand), 'flow_med'/'flow_cv' and 'temperature_med'/'temperature_cv' ('_med' = median, '_cv' = coefficient of variation, over the monitoring period).
Details
The source data is organized around fishing *operations* ('opcod'): several electrofishing operations can be carried out at the same *station* over time. 'onema' aggregates this to one row per station: every operation is first mapped to its station ('fishing_protocol.csv'), then biomass (in grams) is summed over every operation recorded at a given station, separately for each species (i.e. 'biomass[s, ]' is the total biomass of each species ever caught at station 's', not a single operation's catch). Stations without environmental data are dropped. Species observed at fewer than 10 stations are also dropped: at that level of rarity, a zero-inflated fit's iterative initialization can fit a species' handful of non-zero observations exactly, driving its estimated noise precision to infinity (these species also carry essentially no information for clustering anyway).
Source
Danet, A., Mouchet, M., Bonnaffe, W., Thebault, E., Fontaine, C. (2021) "Species richness and food-web structure jointly drive community biomass and its temporal stability in fish communities", data set, Zenodo, doi:10.5281/zenodo.5095656.
Examples
Y <- log(1 + onema$biomass)
X <- model.matrix(~ 1, data = onema$covariates)
nb_data <- NormalBlockData$new(Y, X)
out <- normal_block(nb_data, 2:15, control = NB_control(clustering_init = "ward2"))
Plot a Normal-Block Model
Description
Plots the evolution of the objective (log-likelihood or ELBO) across the (V)EM iterations of the last call to 'optimize()', see '$plot_loglik()'.
Usage
## S3 method for class 'NormalBlockBase'
plot(x, ...)
Arguments
x |
An object of class NormalBlockBase. |
... |
not used, only here for S3 compatibility |
Value
Invisibly returns the [ggplot2::ggplot] object; called for its side effect of plotting.
Examples
ex_data <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex_data$Y, ex_data$X)
model <- normal_block(data, blocks = 3, control = NB_control(verbose = FALSE))
plot(model)
Predict Method for Variance-Block Models
Description
Predicts observations Y for new covariates X. Specific to the variance-block family: the mean-block models have their own formula (mu = C B' X).
Usage
## S3 method for class 'NormalBlockBase'
predict(object, new_X, ...)
Arguments
object |
An object of class NormalBlockVarBase. |
new_X |
New set of covariates. |
... |
not used, only here for S3 compatibility |
Value
A n*p prediction matrix for new observations
Print a Normal-Block Model
Description
Print a short summary of a fitted normal-block model: model type, goodness-of-fit criteria, and the useful fields/methods to explore it further.
Usage
## S3 method for class 'NormalBlockBase'
print(x, ...)
Arguments
x |
An object of class NormalBlockBase. |
... |
not used, only here for S3 compatibility |
Value
Invisibly returns 'x'.
Examples
ex_data <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex_data$Y, ex_data$X)
model <- normal_block(data, blocks = 3, control = NB_control(verbose = FALSE))
print(model)
Print a Collection of Normal-Block Models
Description
Print a short summary of a collection of normal-block models: model type and the range of q/sparsity explored. See [summary.NormalBlockCollection()] for the full criteria table.
Usage
## S3 method for class 'NormalBlockCollection'
print(x, ...)
Arguments
x |
An object inheriting from NormalBlockCollection. |
... |
not used, only here for S3 compatibility |
Value
Invisibly returns 'x'.
Examples
ex_data <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex_data$Y, ex_data$X)
models <- normal_block(data, blocks = 2:5, control = NB_control(verbose = FALSE))
print(models)
Print a Sequential Mean-then-Variance Fit
Description
Reports both stages and, when aricode is available, how related the two partitions are.
Usage
## S3 method for class 'normal_block_sequential'
print(x, ...)
Arguments
x |
an object of class 'normal_block_sequential' |
... |
not used, only here for S3 compatibility |
Value
Invisibly returns 'x'.
Print a Normal-Block Model Summary
Description
Print method for objects returned by [summary.NormalBlockBase()].
Usage
## S3 method for class 'summary.NormalBlockBase'
print(x, ...)
Arguments
x |
An object of class 'summary.NormalBlockBase'. |
... |
not used, only here for S3 compatibility |
Value
Invisibly returns 'x'.
Print a Collection Summary
Description
Print method for objects returned by [summary.NormalBlockCollection()].
Usage
## S3 method for class 'summary.NormalBlockCollection'
print(x, ...)
Arguments
x |
An object of class 'summary.NormalBlockCollection'. |
... |
not used, only here for S3 compatibility |
Value
Invisibly returns 'x'.
Extract the Covariance Matrix
Description
Extract the covariance matrix 'Omega^-1': between latent blocks (q x q) for the variance-block models, between variables (p x p) for the mean-block models.
Usage
## S3 method for class 'NormalBlockBase'
sigma(object, ...)
Arguments
object |
An object of class NormalBlockBase. |
... |
not used, only here for S3 compatibility |
Value
The covariance matrix, of size q x q or p x p depending on the model.
Summarize a Normal-Block Model
Description
Summarizes a fitted normal-block model: model type, goodness-of-fit criteria, cluster sizes, and the density of the inferred network between blocks.
Usage
## S3 method for class 'NormalBlockBase'
summary(object, ...)
Arguments
object |
An object of class NormalBlockBase. |
... |
not used, only here for S3 compatibility |
Value
An object of class 'summary.NormalBlockBase' (a list with the model's 'who_am_I', 'criteria', 'cluster_sizes' and network 'density'), printed with a dedicated [print.summary.NormalBlockBase()] method.
Examples
ex_data <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex_data$Y, ex_data$X)
model <- normal_block(data, blocks = 3, control = NB_control(verbose = FALSE))
summary(model)
Summarize a Collection of Normal-Block Models
Description
Summarizes a collection of normal-block models: model type, the full criteria table, and the range of q/sparsity explored.
Usage
## S3 method for class 'NormalBlockCollection'
summary(object, ...)
Arguments
object |
An object inheriting from NormalBlockCollection. |
... |
not used, only here for S3 compatibility |
Value
An object of class 'summary.NormalBlockCollection' (a list with the collection's 'who_am_I', 'criteria', 'q_range' and 'sparsity_range'), printed with a dedicated [print.summary.NormalBlockCollection()] method.
Examples
ex_data <- generate_normal_block_var_data(n = 50, p = 20, d = 1, q = 3)
data <- NormalBlockData$new(ex_data$Y, ex_data$X)
models <- normal_block(data, blocks = 2:5, control = NB_control(verbose = FALSE))
summary(models)
University webpages text data (CMU "4 Universities" / WebKB)
Description
Term-frequency data derived from the student personal webpages of the CMU "World Wide Knowledge Base" (WebKB) project's "4 Universities" dataset (Cornell, Texas, Washington, Wisconsin computer science departments, collected January 1997). Used as one of the running examples in Tous & Chiquet (2026).
Usage
university
Format
A list with 3 elements:
- frequencies
a 504 x 1867 numeric matrix of term frequencies (row sums to 1): for each document (row, named by its original file path) and term (column), the fraction of that document's (post-preprocessing) word count made up of that term.
- entropies
a named numeric vector of length 1867 (one value per column of 'frequencies', same names/order), the normalized Shannon entropy of each term's distribution across documents.
- terms
a character vector of the 100 column names of 'frequencies' with the highest 'entropies', ordered by decreasing entropy.
Details
Each of the 504 pages (rows) is a document; each of the 1867 columns is a term retained after lower-casing, stripping URLs/HTML tags/control characters/punctuation/numbers, removing English stopwords and dropping terms occurring in fewer than 2 documents. 'entropies' ranks every term by how evenly it is spread across documents (Shannon entropy of each term's normalized document distribution, in \[0, 1\], 1 = perfectly uniform); 'terms' is the 100 highest-entropy terms, i.e. the terms that are the most informative for distinguishing documents from one another rather than just reflecting a few documents' idiosyncratic vocabulary – the transformation used by Tan et al. (2015).
Source
CMU Text Learning Group, "World Wide Knowledge Base (Web->KB) project", http://www.cs.cmu.edu/~webkb/; "4 Universities" subset, https://www.cs.cmu.edu/afs/cs/project/theo-20/www/data/. Tan, P.-N., Steinbach, M., Kumar, V. (2015) "Introduction to Data Mining" (transform used to derive 'entropies'/'terms').
Examples
Y <- log(1 + university$frequencies[, university$terms])
nb_data <- NormalBlockData$new(Y, X = matrix(1, nrow(Y), 1))
out <- normal_block(nb_data, 2:15)