CorNetto builds knowledge-guided multi-omic correlation networks from normalized assay data stored in a MultiAssayExperiment. It is intended for workflows where transcriptomic, proteomic, metabolomic, or related assays are already normalized and the analysis question is whether groups differ in correlation structure, prior-supported connectivity, or node-level rewiring.
The package uses standard Bioconductor containers for assay and sample metadata, and returns standardized edge tables that can be combined, converted to igraph objects, or exported as Cytoscape-ready node and edge tables.
CorNetto is for downstream analysis after assay-level preprocessing. It uses Bioconductor containers, implements the Fisher z-difference test for differential correlation, and uses igraph for graph representation. The package adds the glue needed for prior-guided candidate-edge differential correlation, knowledge-network-aware integration, focused subnetworks, and rewiring summaries in a single reproducible workflow.
The Bioconductor package dcanr provides several methods and an evaluation framework for differential co-expression or association network inference. CorNetto has a narrower role. It works directly with MultiAssayExperiment, tests prespecified within- or cross-assay edges from heterogeneous prior networks, and carries those results through network integration and node-level rewiring summaries. It is therefore complementary to dcanr rather than a replacement for its method-comparison and benchmarking framework.
Green boxes are CorNetto functions, blue boxes are the objects they return, and orange boxes are inputs and the MultiAssayExperiment that carries results between steps.
The diagram outlines how the functions relate to one another. Inputs (yellow)
are read either by readKnowledgeNetwork(), for prior-knowledge databases, or
by createAnalysisData(), for multi-omic abundance data and sample metadata.
Each returns a package-native object: a prior network, or a CorNetto
MultiAssayExperiment. From there the package builds correlation networks,
differential correlation networks, rewiring scores and permuted rewiring
scores.
The order shown is illustrative, not prescriptive. You could equally run
createDifferentialCorrelationNetwork(), narrow the result with
filterNetworkByNodes(), then call createNetworkGraph() to obtain a focused
differential-correlation graph.
The bottom-right panel shows the two ways results are handled: a function can
return its result directly, or store it inside the CorNetto
MultiAssayExperiment, from which getCorNettoResult() retrieves it by name.
Both work; which you use is a matter of preference.
Figure 1: The CorNetto workflow, from input data and prior knowledge through to rewiring validation and export
c(
R = R.version.string,
Bioconductor = as.character(BiocManager::version()),
CorNetto = as.character(utils::packageVersion("CorNetto"))
)
#> R Bioconductor
#> "R version 4.6.1 (2026-06-24)" "3.24"
#> CorNetto
#> "0.99.1"
After acceptance to Bioconductor, install CorNetto with:
if (!requireNamespace("BiocManager", quietly = TRUE)) {
install.packages("BiocManager")
}
BiocManager::install("CorNetto")
analysisData <- exampleAnalysisData()
knowledgeNetwork <- exampleKnowledgeNetwork()
seedNodes <- exampleSeedNodes()
analysisData
#> A MultiAssayExperiment object of 3 listed
#> experiments with user-defined names and respective classes.
#> Containing an ExperimentList class object of length 3:
#> [1] protein: SummarizedExperiment with 5 rows and 20 columns
#> [2] transcript: SummarizedExperiment with 5 rows and 20 columns
#> [3] metabolite: SummarizedExperiment with 4 rows and 20 columns
#> Functionality:
#> experiments() - obtain the ExperimentList instance
#> colData() - the primary/phenotype DataFrame
#> sampleMap() - the sample coordination DataFrame
#> `$`, `[`, `[[` - extract colData columns, subset, or experiment
#> *Format() - convert into a long or wide DataFrame
#> assays() - convert ExperimentList to a SimpleList of matrices
#> exportClass() - save data to flat files
summarizeAnalysisData(analysisData, groupColumn = "clinicalGroup", quiet = TRUE)
#> $assays
#> DataFrame with 3 rows and 9 columns
#> assayName featureCount sampleCount missingValueCount missingValueFraction
#> <character> <integer> <integer> <integer> <numeric>
#> 1 protein 5 20 0 0
#> 2 transcript 5 20 0 0
#> 3 metabolite 4 20 0 0
#> zeroVarianceFeatureCount allMissingFeatureCount highMissingFeatureCount
#> <integer> <integer> <integer>
#> 1 0 0 0
#> 2 0 0 0
#> 3 0 0 0
#> samplesMissingFromColData
#> <integer>
#> 1 0
#> 2 0
#> 3 0
#>
#> $samples
#> $samples$overall
#> DataFrame with 1 row and 2 columns
#> sampleCount samplesInAnyAssay
#> <integer> <integer>
#> 1 20 20
#>
#> $samples$groups
#> DataFrame with 2 rows and 2 columns
#> groupLevel sampleCount
#> <character> <integer>
#> 1 PASC 10
#> 2 Recovered 10
#>
#>
#> $warnings
#> character(0)
head(knowledgeNetwork)
#> DataFrame with 6 rows and 30 columns
#> fromFeatureIdentifier toFeatureIdentifier fromFeatureName toFeatureName
#> <character> <character> <character> <character>
#> 1 P1 P2 CFH C3
#> 2 P1 P3 CFH CR1
#> 3 T1 T2 CFH transcript C3 transcript
#> 4 T1 P1 CFH transcript CFH
#> 5 T2 P2 C3 transcript C3
#> 6 M1 P1 Citrate CFH
#> fromAssayName toAssayName edgeType edgeDirection sourceType
#> <character> <character> <character> <character> <character>
#> 1 protein protein proteinProteinIntera.. undirected knowledge
#> 2 protein protein proteinProteinIntera.. undirected knowledge
#> 3 transcript transcript coexpressionPrior undirected knowledge
#> 4 transcript protein rnaProtein directed knowledge
#> 5 transcript protein rnaProtein directed knowledge
#> 6 metabolite protein proteinMetabolite directed knowledge
#> correlationScope correlationMethod knowledgeSource groupName
#> <character> <character> <character> <character>
#> 1 NA NA CorNettoSynthetic NA
#> 2 NA NA CorNettoSynthetic NA
#> 3 NA NA CorNettoSynthetic NA
#> 4 NA NA CorNettoSynthetic NA
#> 5 NA NA CorNettoSynthetic NA
#> 6 NA NA CorNettoSynthetic NA
#> comparisonName correlationValue group1CorrelationValue group2CorrelationValue
#> <character> <numeric> <numeric> <numeric>
#> 1 NA NA NA NA
#> 2 NA NA NA NA
#> 3 NA NA NA NA
#> 4 NA NA NA NA
#> 5 NA NA NA NA
#> 6 NA NA NA NA
#> pValue adjustedPValue group1PValue group2PValue group1AdjustedPValue
#> <numeric> <numeric> <numeric> <numeric> <numeric>
#> 1 NA NA NA NA NA
#> 2 NA NA NA NA NA
#> 3 NA NA NA NA NA
#> 4 NA NA NA NA NA
#> 5 NA NA NA NA NA
#> 6 NA NA NA NA NA
#> group2AdjustedPValue zScoreDifference sampleCount group1SampleCount
#> <numeric> <numeric> <numeric> <numeric>
#> 1 NA NA NA NA
#> 2 NA NA NA NA
#> 3 NA NA NA NA
#> 4 NA NA NA NA
#> 5 NA NA NA NA
#> 6 NA NA NA NA
#> group2SampleCount edgeWeight evidenceScore isDirected
#> <numeric> <numeric> <numeric> <logical>
#> 1 NA 0.95 0.95 FALSE
#> 2 NA 0.92 0.92 FALSE
#> 3 NA 0.80 0.80 FALSE
#> 4 NA 1.00 1.00 TRUE
#> 5 NA 1.00 1.00 TRUE
#> 6 NA 0.88 0.88 TRUE
seedNodes
#> [1] "P1" "T1" "M1"
The synthetic example contains three assays named protein,
transcript, and metabolite. The example prior network also contains a
drug-target edge to demonstrate that prior networks can include static
knowledge beyond the measured assays. Prior-guided candidate-edge
analyses must therefore be given only prior edges whose assay names are
present in the analysis object.
measuredAssays <- c("protein", "transcript", "metabolite")
measuredKnowledgeNetwork <- knowledgeNetwork[
knowledgeNetwork$fromAssayName %in% measuredAssays &
knowledgeNetwork$toAssayName %in% measuredAssays,
,
drop = FALSE
]
createCorrelationNetwork() computes all pairwise within-omic
correlations for one assay and one group. Dense all-pairs mode is
intended for small-to-medium assays; for large assays, prefer
prior-guided candidate-edge testing when suitable.
recoveredProteinNetwork <- createCorrelationNetwork(
analysisData = analysisData,
assayName = "protein",
groupColumn = "clinicalGroup",
groupLevel = "Recovered",
correlationMethod = "pearson",
minimumAbsoluteCorrelation = 0,
adjustedPValueThreshold = 1,
pAdjustMethod = "fdr",
storeResult = FALSE
)
head(recoveredProteinNetwork)
#> DataFrame with 6 rows and 30 columns
#> fromFeatureIdentifier toFeatureIdentifier fromFeatureName toFeatureName
#> <character> <character> <character> <character>
#> 1 P1 P2 CFH C3
#> 2 P1 P3 CFH CR1
#> 3 P2 P3 C3 CR1
#> 4 P1 P4 CFH CFB
#> 5 P2 P4 C3 CFB
#> 6 P3 P4 CR1 CFB
#> fromAssayName toAssayName edgeType edgeDirection sourceType
#> <character> <character> <character> <character> <character>
#> 1 protein protein correlation positive correlation
#> 2 protein protein correlation positive correlation
#> 3 protein protein correlation positive correlation
#> 4 protein protein correlation negative correlation
#> 5 protein protein correlation negative correlation
#> 6 protein protein correlation negative correlation
#> correlationScope correlationMethod knowledgeSource groupName comparisonName
#> <character> <character> <character> <character> <character>
#> 1 withinOmic pearson NA Recovered NA
#> 2 withinOmic pearson NA Recovered NA
#> 3 withinOmic pearson NA Recovered NA
#> 4 withinOmic pearson NA Recovered NA
#> 5 withinOmic pearson NA Recovered NA
#> 6 withinOmic pearson NA Recovered NA
#> correlationValue group1CorrelationValue group2CorrelationValue pValue
#> <numeric> <numeric> <numeric> <numeric>
#> 1 0.878752 NA NA 0.000814789
#> 2 0.747338 NA NA 0.012972274
#> 3 0.787569 NA NA 0.006833154
#> 4 -0.431744 NA NA 0.212790881
#> 5 -0.509253 NA NA 0.132731940
#> 6 -0.475459 NA NA 0.164878371
#> adjustedPValue group1PValue group2PValue group1AdjustedPValue
#> <numeric> <numeric> <numeric> <numeric>
#> 1 0.00226296 NA NA NA
#> 2 0.02162046 NA NA NA
#> 3 0.01366631 NA NA NA
#> 4 0.23643431 NA NA NA
#> 5 0.18961706 NA NA NA
#> 6 0.20609796 NA NA NA
#> group2AdjustedPValue zScoreDifference sampleCount group1SampleCount
#> <numeric> <numeric> <numeric> <numeric>
#> 1 NA NA 10 NA
#> 2 NA NA 10 NA
#> 3 NA NA 10 NA
#> 4 NA NA 10 NA
#> 5 NA NA 10 NA
#> 6 NA NA 10 NA
#> group2SampleCount edgeWeight evidenceScore isDirected
#> <numeric> <numeric> <numeric> <logical>
#> 1 NA 0.878752 NA FALSE
#> 2 NA 0.747338 NA FALSE
#> 3 NA 0.787569 NA FALSE
#> 4 NA -0.431744 NA FALSE
#> 5 NA -0.509253 NA FALSE
#> 6 NA -0.475459 NA FALSE
testDifferentialCorrelation() can test only feature pairs supported by
a prior network when candidateEdgeTable is supplied. This is the sparse
mode for differential correlation: it avoids exhaustive cross-omic
testing and keeps the dynamic network aligned to interpretable prior
knowledge.
priorGuidedDifferentialResults <- testDifferentialCorrelation(
analysisData = analysisData,
candidateEdgeTable = measuredKnowledgeNetwork,
groupColumn = "clinicalGroup",
groupLevels = c("PASC", "Recovered"),
minimumAbsoluteCorrelation = 0,
adjustedPValueThreshold = 1,
pAdjustMethod = "fdr",
storeResult = FALSE
)
priorGuidedDifferentialNetwork <- createDifferentialCorrelationNetwork(
differentialCorrelationTable = priorGuidedDifferentialResults,
minimumAbsoluteCorrelation = 0
)
c(nrow(priorGuidedDifferentialResults), nrow(priorGuidedDifferentialNetwork))
#> [1] 7 7
permuteRewiringScores() permutes group labels, recomputes the
differential-correlation statistics over a fixed edge universe, and compares
each node’s observed rewiring score with the permutation distribution.
When both candidateEdgeTable and assayName are omitted, that universe is
built from dense within-omic pairs in every assay; cross-omic pairs are not
generated.
The fixed edge set is attempted in every permutation. An edge can still
be unscored if a permuted group has insufficient pairwise-complete data or a
constant feature, and contributingPermutations records the resulting loss.
Supplying candidateEdgeTable with all observed-data filters disabled, as
below, lets CorNetto fix the candidate universe before inspecting the group
labels. The result is marked as a randomization p-value only when every edge
and the selected node score are estimable under the permitted allocations. The
user is still responsible for prespecifying the candidates and for the
exchangeability assumption.
backend <- BiocParallel::SnowParam(workers = 2, type = "SOCK")
rewiringValidation <- permuteRewiringScores(
analysisData = analysisData,
candidateEdgeTable = measuredKnowledgeNetwork,
groupColumn = "clinicalGroup",
groupLevels = c("PASC", "Recovered"),
minimumAbsoluteCorrelation = 0,
adjustedPValueThreshold = NULL,
pAdjustMethod = "fdr",
nPermutations = 99,
seed = 1,
# Remove the three lines below to run serially:
verbose = TRUE,
progressEvery = 50,
BPPARAM = backend
)
#> Scoring 99 permutations with 2 workers.
#> Completed 50 of 99 permutations (50.5%).
#> Completed 99 of 99 permutations (100.0%).
head(rewiringValidation$rewiringTable)
#> DataFrame with 6 rows and 18 columns
#> nodeKey nodeIdentifier nodeName assayName totalConnections
#> <character> <character> <character> <character> <integer>
#> 1 protein::P1 P1 CFH protein 4
#> 2 transcript::T1 T1 CFH transcript transcript 2
#> 3 transcript::T2 T2 C3 transcript transcript 2
#> 4 metabolite::M1 M1 Citrate metabolite 1
#> 5 metabolite::M2 M2 Succinate metabolite 1
#> 6 protein::P2 P2 C3 protein 3
#> rawRewiringScore rootMeanSquareRewiringScore degreeBin degreeMatchedZScore
#> <numeric> <numeric> <character> <numeric>
#> 1 2.58494 1.29247 (2,3] NA
#> 2 1.83367 1.29660 (1,2] NA
#> 3 2.51915 1.78131 (1,2] NA
#> 4 0.71149 0.71149 [0,1] NA
#> 5 1.40686 1.40686 [0,1] NA
#> 6 2.97487 1.71754 (1,2] NA
#> permutationTailProbability adjustedPermutationTailProbability nullMeanScore
#> <numeric> <numeric> <numeric>
#> 1 0.06 0.140 1.476106
#> 2 0.14 0.175 1.094358
#> 3 0.14 0.175 1.373130
#> 4 0.26 0.260 0.554030
#> 5 0.02 0.140 0.567395
#> 6 0.05 0.140 1.391005
#> nullSdScore contributingPermutations scoreColumn nPermutations
#> <numeric> <integer> <character> <integer>
#> 1 0.570168 99 rawRewiringScore 99
#> 2 0.578007 99 rawRewiringScore 99
#> 3 0.792259 99 rawRewiringScore 99
#> 4 0.431635 99 rawRewiringScore 99
#> 5 0.353340 99 rawRewiringScore 99
#> 6 0.736635 99 rawRewiringScore 99
#> blockColumn inferenceStatus
#> <character> <character>
#> 1 NA randomization p-value
#> 2 NA randomization p-value
#> 3 NA randomization p-value
#> 4 NA randomization p-value
#> 5 NA randomization p-value
#> 6 NA randomization p-value
rewiringValidation$inferenceStatus
#> [1] "randomization p-value"
For a fully scored node, the smallest tail probability is
1 / (nPermutations + 1), so 99 permutations bottom out at 0.01.
contributingPermutations records how many permutations produced a score for
each node. Treat the values as conditional rankings whenever
inferenceStatus says so.
The call above uses a BiocParallel socket backend,
which is the portable choice on Windows. Keep examples and automated checks at
two workers or fewer. verbose and progressEvery control progress reporting;
BPPARAM selects the backend. A fixed seed gives the same label allocations
whatever the worker count, so serial and parallel runs agree numerically.
testDifferentialCorrelation() compares correlation coefficients between
two groups. createDifferentialCorrelationNetwork() converts the test
results to a weighted network, and calculateRewiringScores() summarizes
node-level rewiring. When assayName is omitted, every assay is tested, but
pairs are generated only within each assay: protein-protein and
transcript-transcript pairs are included, for example, whereas
protein-transcript pairs are not.
differentialResults <- testDifferentialCorrelation(
analysisData = analysisData,
groupColumn = "clinicalGroup",
groupLevels = c("PASC", "Recovered"),
correlationMethod = "pearson",
minimumAbsoluteCorrelation = 0,
adjustedPValueThreshold = 1,
pAdjustMethod = "fdr",
storeResult = FALSE
)
differentialNetwork <- createDifferentialCorrelationNetwork(
differentialCorrelationTable = differentialResults,
minimumAbsoluteCorrelation = 0
)
rewiringScores <- calculateRewiringScores(
differentialCorrelationNetwork = differentialNetwork,
storeResult = FALSE
)
head(rewiringScores)
#> DataFrame with 6 rows and 9 columns
#> nodeKey nodeIdentifier nodeName assayName totalConnections
#> <character> <character> <character> <character> <integer>
#> 1 protein::P3 P3 CR1 protein 4
#> 2 protein::P1 P1 CFH protein 4
#> 3 protein::P2 P2 C3 protein 4
#> 4 protein::P4 P4 CFB protein 4
#> 5 transcript::T1 T1 CFH transcript transcript 4
#> 6 transcript::T3 T3 CR1 transcript transcript 4
#> rawRewiringScore rootMeanSquareRewiringScore degreeBin degreeMatchedZScore
#> <numeric> <numeric> <character> <numeric>
#> 1 6.18963 3.09481 (2,3] 0.968730
#> 2 5.71175 2.85588 (2,3] 0.768908
#> 3 4.81787 2.40894 (2,3] 0.395134
#> 4 2.79769 1.39884 (2,3] -0.449601
#> 5 2.61704 1.30852 (2,3] -0.525138
#> 6 2.73210 1.36605 (2,3] -0.477028
The three scores are descriptive, not tests. rawRewiringScore is the L2
norm of a node’s incident z-scores and grows with degree.
rootMeanSquareRewiringScore divides that by sqrt(degree) and is the one
to compare across nodes of different degree. degreeMatchedZScore
standardizes within bins of log2(degree + 1), so it is a within-bin
ranking aid rather than a z-score against a null model; it is NA for bins
holding fewer than five nodes, since a smaller bin cannot produce a
meaningful spread. permuteRewiringScores() adds a permutation reference;
its inferenceStatus states whether the result meets the computational
conditions for randomization inference.
Features are mutually tested only against features in the same assay. In this example, each protein and transcript node therefore has degree four, while each metabolite node has degree three. On a real network with a spread of degrees, the bins do the work they are named for.
combineNetworks() merges static prior knowledge,
group-specific correlation layers, and differential-correlation layers.
createFocusedNetwork() extracts a seed-centered neighborhood, which is
useful for pathway-driven analyses.
integratedNetwork <- combineNetworks(
knowledgeNetwork = knowledgeNetwork,
correlationNetwork = recoveredProteinNetwork,
differentialCorrelationNetwork = list(
priorGuidedDifferentialNetwork,
differentialNetwork
),
includeReverseEdges = TRUE
)
focusedNetwork <- createFocusedNetwork(
networkEdgeTable = integratedNetwork,
seedNodes = seedNodes,
neighborhoodOrder = 1
)
cytoscapeTables <- prepareCytoscapeTables(
networkEdgeTable = focusedNetwork,
rewiringTable = rewiringScores
)
names(cytoscapeTables)
#> [1] "nodes" "edges"
nrow(cytoscapeTables$nodes)
#> [1] 14
nrow(cytoscapeTables$edges)
#> [1] 96
createNetworkGraph() converts a standardized CorNetto edge table to an
igraph object. Plotting can then use standard igraph
methods.
A node is one feature in one assay, drawn with an assay-specific colour and shape. An edge is a connection between two features. Node colour could equally encode a rewiring score, a permutation tail probability, or any other node-level column.
displayGraph <- igraph::simplify(
igraph::as_undirected(createNetworkGraph(focusedNetwork), mode = "collapse")
)
assayStyle <- data.frame(
assay = c("protein", "transcript", "metabolite"),
colour = c("#2B8CBE", "#31A354", "#E6842A"),
shape = c("circle", "square", "csquare")
)
idx <- match(igraph::V(displayGraph)$assayName, assayStyle$assay)
set.seed(1)
plot(
displayGraph,
layout = igraph::layout_with_fr(displayGraph),
vertex.color = assayStyle$colour[idx],
vertex.shape = assayStyle$shape[idx],
vertex.label = igraph::V(displayGraph)$nodeName,
vertex.label.cex = 0.7,
vertex.label.color = "black",
vertex.label.family = "sans",
vertex.frame.color = "white",
vertex.size = 20,
edge.color = "grey65",
main = "Focused CorNetto network around the seed nodes"
)
legend(
"bottomleft",
legend = assayStyle$assay,
pt.bg = assayStyle$colour,
pch = c(21, 22, 23),
pt.cex = 1.6,
bty = "n",
title = "Assay"
)
c(nodes = igraph::gorder(displayGraph),
connections = igraph::gsize(displayGraph))
#> nodes connections
#> 14 30
The 96 exported edge rows reduce to 30 drawn connections for two reasons, and no edge is filtered out on the way.
First, combineNetworks(includeReverseEdges = TRUE) stores each undirected
edge in both directions, which accounts for most of the difference. Reverse
copies are added for undirected edges only. This is a workaround rather than a
claim about biology: several Cytoscape algorithms require an explicit
direction to traverse an edge, while the edges themselves are not inherently
directed, as with a correlation or a protein-protein interaction. Storing both
orientations lets those algorithms move either way across such an edge.
Genuinely directed edges are left untouched.
Second, one feature pair can carry several rows when more than one layer supports it, since prior knowledge, a group-specific correlation and a differential-correlation result are separate rows describing the same pair.
The display graph shows one line per connected pair; the exported tables keep every row.
Use writeNetworkTables() when Cytoscape-ready files
are needed. The
example writes to a temporary directory.
writtenFiles <- writeNetworkTables(
networkTables = cytoscapeTables,
directoryPath = tempdir(),
prefix = "cornettoExample",
fileFormat = "tsv"
)
basename(writtenFiles)
#> [1] "cornettoExample_nodes.tsv" "cornettoExample_edges.tsv"
citation("CorNetto")
#> To cite CorNetto in publications, use:
#>
#> Ward B, Balligand J-L, Bamps L, Bommer G, Cani PD, De Greef J, Dewulf
#> JP, Gatto L, Haufroid V, Kabamba B, Pyr dit Ruys S, Vertommen D,
#> Yombi JC, Belkhir L, Elens L (2026). Longitudinal multi-omic network
#> rewiring at the complement-coagulation interface in post-acute
#> sequelae of COVID-19 (PASC). medRxiv. doi:
#> 10.64898/2026.07.14.26358048.
#>
#> A BibTeX entry for LaTeX users is
#>
#> @Article{,
#> title = {Longitudinal multi-omic network rewiring at the complement-coagulation interface in post-acute sequelae of COVID-19 (PASC)},
#> author = {Bradley Ward and Jean-Luc Balligand and Laurence Bamps and Guido Bommer and Patrice D. Cani and Julien {De Greef} and Joseph P. Dewulf and Laurent Gatto and Vincent Haufroid and Benoît Kabamba and Sébastien {Pyr dit Ruys} and Didier Vertommen and Jean Cyr Yombi and Leïla Belkhir and Laure Elens},
#> journal = {medRxiv},
#> year = {2026},
#> doi = {10.64898/2026.07.14.26358048},
#> }
#>
#> Leïla Belkhir and Laure Elens are joint senior authors.
sessionInfo()
#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 24.04.4 LTS
#>
#> Matrix products: default
#> BLAS: /home/biocbuild/bbs-3.24-bioc/R/lib/libRblas.so
#> LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0 LAPACK version 3.12.0
#>
#> locale:
#> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
#> [3] LC_TIME=en_GB LC_COLLATE=C
#> [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
#> [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
#> [9] LC_ADDRESS=C LC_TELEPHONE=C
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
#>
#> time zone: America/New_York
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] CorNetto_0.99.1 BiocStyle_2.41.0
#>
#> loaded via a namespace (and not attached):
#> [1] sass_0.4.10 generics_0.1.4
#> [3] SparseArray_1.13.2 lattice_0.23-1
#> [5] digest_0.6.39 magrittr_2.0.5
#> [7] evaluate_1.0.5 grid_4.6.1
#> [9] bookdown_0.48 fastmap_1.2.0
#> [11] jsonlite_2.0.0 Matrix_1.7-6
#> [13] tinytex_0.60 BiocManager_1.30.27
#> [15] codetools_0.2-20 jquerylib_0.1.4
#> [17] abind_1.4-8 cli_3.6.6
#> [19] rlang_1.3.0 XVector_0.53.0
#> [21] Biobase_2.73.2 withr_3.0.3
#> [23] cachem_1.1.0 DelayedArray_0.39.6
#> [25] yaml_2.3.12 otel_0.2.0
#> [27] BiocBaseUtils_1.15.1 S4Arrays_1.13.0
#> [29] tools_4.6.1 parallel_4.6.1
#> [31] BiocParallel_1.47.0 SummarizedExperiment_1.43.0
#> [33] BiocGenerics_0.59.12 MultiAssayExperiment_1.39.1
#> [35] R6_2.6.1 magick_2.9.1
#> [37] matrixStats_1.5.0 stats4_4.6.1
#> [39] lifecycle_1.0.5 Seqinfo_1.3.2
#> [41] S4Vectors_0.51.9 IRanges_2.47.5
#> [43] pkgconfig_2.0.3 bslib_0.12.0
#> [45] Rcpp_1.1.2 xfun_0.60
#> [47] GenomicRanges_1.65.4 MatrixGenerics_1.25.0
#> [49] knitr_1.52 htmltools_0.5.9
#> [51] snow_0.4-4 igraph_2.3.3
#> [53] rmarkdown_2.32 compiler_4.6.1