scGraphVerse is a modular and extensible R package for constructing, comparing, and visualizing gene regulatory networks (GRNs) from single-cell RNAseq data. It includes several inference algorithms, utilities, and visualization functions.
Single-cell data presents unique challenges: high sparsity, batch variation, and the need to distinguish shared versus condition-specific regulation. scGraphVerse helps address these through multi-method inference consensus. It starts with SingleCellExperiment, Seurat or matrix-based objects, enabling flexible pipelines across diverse experimental setups.
While several GRN inference packages exist in Bioconductor (e.g. SCENIC), most are limited to single-method inference or lack support for multi-condition, multi-replicate, and multi-method comparisons. scGraphVerse adds value by:
The typical scGraphVerse workflow begins with one or more count matrix, or objects like SingleCellExperiment or Seurat. These are passed to the core function infer_networks(), which runs the selected inference methods and returns an adjacency matrix or list of matrices.
For benchmarking or teaching purposes, synthetic datasets can be generated using zinb_simdata() based on a known adjacency matrix. This supports method comparison across early, late, and joint integration strategies using earlyj() and compare_consensus().
An end-to-end workflow, from network inference to community detection and consensus visualization, is provided in the rest of vignettes.
As intended for both high-throughput analysis and intuitive usage, scGraphVerse supports custom workflows using its modular functions.
In this simulation study, we use scGraphVerse to:
We use a pre-computed toy adjacency matrix (toy_adj_matrix) as our ground
truth network. This matrix represents known regulatory relationships between
genes and serves as the reference for evaluating network inference performance.
# Load the toy ground truth adjacency matrix
data(toy_adj_matrix)
adj_truth <- toy_adj_matrix
# Visualize network
if (requireNamespace("igraph", quietly = TRUE) &&
    requireNamespace("ggraph", quietly = TRUE)) {
    gtruth <- igraph::graph_from_adjacency_matrix(adj_truth,mode="undirected")
    ggraph::ggraph(gtruth, layout = "fr") +
        ggraph::geom_edge_link(color = "gray") +
        ggraph::geom_node_point(color = "steelblue") +
        ggplot2::ggtitle(paste0(
            "Ground Truth: ",
            igraph::vcount(gtruth),
            " nodes, ",
            igraph::ecount(gtruth),
            " edges"
        )) +
        ggplot2::theme_minimal()
}
Now we’ll generate synthetic single-cell count data that respects our
ground-truth network structure. We simulate three experimental conditions
(batches) with 50 cells each, using different parameters to model realistic
batch effects and biological variability. The zinb_simdata() function creates
zero-inflated negative binomial count data where gene expression levels are
influenced by the regulatory relationships defined in our ground-truth network.
Key simulation parameters:
- mu_range: Different mean expression levels across conditions
- theta: Overdispersion parameter (lower = more variable)
- pi: Zero-inflation probability (dropout rate)
- depth_range: Sequencing depth variation per cell
# Simulation parameters
nodes <- nrow(adj_truth)
sims <- zinb_simdata(
    n = 50,
    p = nodes,
    B = adj_truth,
    mu_range = list(c(1, 4), c(1, 7)),
    mu_noise = c(1, 3),
    theta = c(1, 0.7),
    pi = c(0.2, 0.2),
    kmat = 2,
    depth_range = c(0.8 * nodes * 3, 1.2 * nodes * 3)
)
# Transpose to cells × genes
count_matrices <- lapply(sims, t)
Next, we apply the GENIE3 algorithm to infer gene regulatory networks from our simulated count data. GENIE3 uses random forests to predict each gene’s expression based on all other genes, then ranks the importance of potential regulatory relationships. We process all three batches to capture condition-specific and shared regulatory patterns.
Note: The package now uses Bioconductor data structures:
- count_matrices is now a MultiAssayExperiment (MAE) object
- Network outputs are stored in SummarizedExperiment (SE) objects
GENIE3 workflow: 1. Create a MAE object from the count matrices list 2. For each target gene, build random forest model using all other genes as predictors 3. Extract feature importance scores as edge weights 4. Generate weighted adjacency matrices stored in a SummarizedExperiment 5. Symmetrize the matrices using mean weights to create undirected networks
# Create MultiAssayExperiment from count matrices
mae <- create_mae(count_matrices)
# Infer networks
networks_joint <- infer_networks(
    count_matrices_list = mae,
    method = "GENIE3",
    nCores = 1
)
# Generate weighted adjacency matrices (returns SummarizedExperiment)
wadj_se <- generate_adjacency(networks_joint)
# Symmetrize weights (returns SummarizedExperiment)
swadj_se <- symmetrize(wadj_se, weight_function = "mean")
Now we evaluate how well our inferred networks recover the ground-truth regulatory relationships using ROC curve analysis. The ROC curve plots True Positive Rate (sensitivity) against False Positive Rate (1-specificity) across different edge weight thresholds. A perfect classifier would achieve AUC = 1.0, while random guessing gives AUC = 0.5.
ROC Analysis Steps: 1. Use continuous edge weights from symmetrized adjacency matrices 2. Compare against binary ground-truth network 3. Calculate Area Under Curve (AUC) as overall performance metric 4. Higher AUC indicates better recovery of true regulatory edges
if (requireNamespace("pROC", quietly = TRUE)) {
    roc_res <- plotROC(
        swadj_se,
        adj_truth,
        plot_title = "ROC Curve: GENIE3 Network Inference",
        is_binary = FALSE
    )
    roc_res$plot
    auc_joint <- roc_res$auc
}
To convert our continuous edge weights into binary networks, we need to
determine appropriate cutoff thresholds. The cutoff_adjacency() function uses
a data-driven approach: it creates shuffled versions of our count data, infers
networks from these null datasets, and sets the threshold at the 95th
percentile of shuffled edge weights. This ensures we keep only edges that are
much stronger than expected by random chance.
Cutoff Method: 1. Generate shuffled count matrices (randomize gene expression profiles) 2. Run GENIE3 on shuffled data to get null distribution of edge weights 3. Set threshold at 95th percentile of shuffled weights 4. Apply threshold to original networks to get binary adjacency matrices 5. Calculate precision metrics: TPR (sensitivity), FPR, Precision, F1-score
# Binary cutoff at 95th percentile (returns SummarizedExperiment)
binary_se <- cutoff_adjacency(
    count_matrices = mae,
    weighted_adjm_list = swadj_se,
    n = 1,
    method = "GENIE3",
    quantile_threshold = 0.95,
    nCores = 1,
    debug = TRUE
)
#> [Method: GENIE3] Matrix 1 → Cutoff = 0.06300
#> [Method: GENIE3] Matrix 2 → Cutoff = 0.06170
# Precision scores
pscores_joint <- pscores(adj_truth, binary_se)
#> Registered S3 methods overwritten by 'fmsb':
#>   method    from
#>   print.roc pROC
#>   plot.roc  pROC
head(pscores_joint)
#> $Statistics
#>   Predicted_Matrix TP  TN FP FN       TPR        FPR Precision        F1
#> 1         Matrix 1 12 538 26 19 0.3870968 0.04609929 0.3157895 0.3478261
#> 2         Matrix 2  6 540 24 25 0.1935484 0.04255319 0.2000000 0.1967213
#>         MCC
#> 1 0.3099218
#> 2 0.1533553
#> 
#> $Radar
#> $Radar$data
#>                TPR Specificity Precision        F1       MCC
#> Max      1.0000000   1.0000000 1.0000000 1.0000000 1.0000000
#> Min      0.0000000   0.0000000 0.0000000 0.0000000 0.0000000
#> Matrix 1 0.3870968   0.9539007 0.3157895 0.3478261 0.3099218
#> Matrix 2 0.1935484   0.9574468 0.2000000 0.1967213 0.1533553
#> 
#> $Radar$plot
# Network plot
if (requireNamespace("ggraph", quietly = TRUE)) {
    plotg(binary_se)
}
Since we have three binary networks (one per experimental condition), we can create a consensus network that captures edges consistently detected across conditions. The “vote” method includes an edge in the consensus only if it appears in at least 2 out of 3 individual networks, making it more robust to condition-specific noise.
Consensus Building: - Vote method: Edge included if present in majority of networks (≥2/3) - Union method: Edge included if present in any network (≥1/3) - INet method: Uses weighted evidence combination (more sophisticated)
# Consensus matrix (returns SummarizedExperiment)
consensus <- create_consensus(binary_se, method = "vote")
# Plot consensus network
if (requireNamespace("ggraph", quietly = TRUE)) {
    plotg(consensus)
}
# Compare consensus to truth using classify_edges and plot_network_comparison
if (requireNamespace("ggplot2", quietly = TRUE) &&
    requireNamespace("ggraph", quietly = TRUE)) {
    # Wrap toy_adj_matrix in a SummarizedExperiment for classify_edges
    adj_truth_se <- build_network_se(list(ground_truth = adj_truth))
    # classify_edges expects SummarizedExperiment objects
    edge_classification <- classify_edges(
        consensus_matrix = consensus,
        reference_matrix = adj_truth_se
    )
    print(edge_classification)
    # Visualize network comparison (show_fp = FALSE to hide false positives)
    comparison_plot <- plot_network_comparison(
        edge_classification = edge_classification,
        show_fp = FALSE
    )
    print(comparison_plot)
}
#> $tp_edges
#>  [1] "ACTG1-TMSB4X"  "BTF3-NACA"     "CD3D-CD3E"     "CD3E-HLA-A"   
#>  [5] "CD74-CXCR4"    "COX4I1-COX7C"  "EEF1A1-EEF1D"  "EIF1-EIF3K"   
#>  [9] "EIF4A2-PABPC1" "FOS-JUNB"      "FTH1-FTL"      "GNB2L1-UBA52" 
#> [13] "HLA-B-HLA-E"   "HLA-C-HLA-E"   "MYL12B-MYL6"  
#> 
#> $fp_edges
#>  [1] "ACTG1-CD3D"    "ACTG1-FTH1"    "ACTG1-HLA-C"   "ACTG1-MYL12B" 
#>  [5] "ARPC2-CFL1"    "ARPC2-FOS"     "ARPC2-HLA-A"   "ARPC2-UBA52"  
#>  [9] "ARPC3-BTF3"    "ARPC3-EIF3K"   "ARPC3-GNB2L1"  "ARPC3-HLA-A"  
#> [13] "BTF3-TMSB4X"   "CD3D-FTL"      "CD3D-HLA-C"    "CD3D-UBA52"   
#> [17] "CD3E-FOS"      "CD3E-JUN"      "CD3E-PFN1"     "CD74-MYL12B"  
#> [21] "CD74-NACA"     "CD74-UBA52"    "CFL1-EEF2"     "CFL1-FTH1"    
#> [25] "CFL1-GNB2L1"   "COX4I1-EEF1A1" "COX4I1-PFN1"   "COX7C-JUNB"   
#> [29] "COX7C-UBC"     "CXCR4-FOS"     "EEF1A1-JUN"    "EEF1A1-PABPC1"
#> [33] "EEF1D-JUN"     "EEF1D-JUNB"    "EEF2-HLA-E"    "EEF2-JUN"     
#> [37] "EEF2-PFN1"     "EIF1-EIF4A2"   "EIF1-HLA-B"    "EIF3K-FOS"    
#> [41] "EIF3K-HLA-A"   "FOS-FTL"       "FTL-HLA-E"     "FTL-UBC"      
#> [45] "GNB2L1-NACA"   "HLA-B-MYL12B"  "HLA-B-MYL6"    "MYL12B-NACA"  
#> [49] "MYL12B-PFN1"   "MYL6-NACA"    
#> 
#> $fn_edges
#>  [1] "ACTG1-ARPC2" "ACTG1-ARPC3" "ACTG1-CFL1"  "ACTG1-MYL6"  "ACTG1-PFN1" 
#>  [6] "ARPC2-ARPC3" "EEF2-GNB2L1" "EEF2-UBA52"  "EIF1-GNB2L1" "FOS-JUN"    
#> [11] "HLA-A-HLA-B" "HLA-A-HLA-C" "HLA-A-HLA-E" "HLA-B-HLA-C" "JUN-JUNB"   
#> [16] "UBA52-UBC"  
#> 
#> $consensus_graph
#> IGRAPH 196a3e5 UN-- 35 65 -- 
#> + attr: name (v/c)
#> + edges from 196a3e5 (vertex names):
#>  [1] ACTG1 --CD3D   ACTG1 --FTH1   ACTG1 --HLA-C  ACTG1 --MYL12B ACTG1 --TMSB4X
#>  [6] ARPC2 --CFL1   ARPC2 --FOS    ARPC2 --HLA-A  ARPC2 --UBA52  ARPC3 --BTF3  
#> [11] ARPC3 --EIF3K  ARPC3 --GNB2L1 ARPC3 --HLA-A  BTF3  --NACA   BTF3  --TMSB4X
#> [16] CD3D  --CD3E   CD3D  --FTL    CD3D  --HLA-C  CD3D  --UBA52  CD3E  --FOS   
#> [21] CD3E  --HLA-A  CD3E  --JUN    CD3E  --PFN1   CD74  --CXCR4  CD74  --MYL12B
#> [26] CD74  --NACA   CD74  --UBA52  CFL1  --EEF2   CFL1  --FTH1   CFL1  --GNB2L1
#> [31] COX4I1--COX7C  COX4I1--EEF1A1 COX4I1--PFN1   COX7C --JUNB   COX7C --UBC   
#> [36] CXCR4 --FOS    EEF1A1--EEF1D  EEF1A1--JUN    EEF1A1--PABPC1 EEF1D --JUN   
#> + ... omitted several edges
#> 
#> $reference_graph
#> IGRAPH 81c4df0 UN-- 35 31 -- 
#> + attr: name (v/c)
#> + edges from 81c4df0 (vertex names):
#>  [1] ACTG1 --ARPC2  ACTG1 --ARPC3  ACTG1 --CFL1   ACTG1 --MYL6   ACTG1 --PFN1  
#>  [6] ACTG1 --TMSB4X ARPC2 --ARPC3  BTF3  --NACA   CD3D  --CD3E   CD3E  --HLA-A 
#> [11] CD74  --CXCR4  COX4I1--COX7C  EEF1A1--EEF1D  EEF2  --GNB2L1 EEF2  --UBA52 
#> [16] EIF1  --EIF3K  EIF1  --GNB2L1 EIF4A2--PABPC1 FOS   --JUN    FOS   --JUNB  
#> [21] FTH1  --FTL    GNB2L1--UBA52  HLA-A --HLA-B  HLA-A --HLA-C  HLA-A --HLA-E 
#> [26] HLA-B --HLA-C  HLA-B --HLA-E  HLA-C --HLA-E  JUN   --JUNB   MYL12B--MYL6  
#> [31] UBA52 --UBC   
#> 
#> $edge_colors
#>  [1] "blue" "blue" "blue" "blue" "blue" "red"  "blue" "red"  "red"  "red" 
#> [11] "red"  "red"  "red"  "blue" "blue" "red"  "blue" "red"  "blue" "red" 
#> [21] "red"  "red"  "blue" "blue" "blue" "blue" "red"  "red"  "blue" "red" 
#> [31] "blue"
#> 
#> $use_stringdb
#> [1] FALSE
Community detection identifies groups of highly interconnected genes that likely share biological functions or regulatory mechanisms. We’ll detect communities in both our inferred consensus network and the ground-truth network, then compare their similarity using several metrics.
Community Detection Steps: 1. Apply Louvain algorithm to identify network modules 2. Compare community assignments using multiple similarity measures: - Variation of Information (VI): Lower values = more similar - Normalized Mutual Information (NMI): Higher values = more similar - Adjusted Rand Index (ARI): Higher values = more similar
Now we’ll detect communities in our ground-truth network to establish the reference community structure:
if (requireNamespace("igraph", quietly = TRUE)) {
    comm_truth <- community_path(adj_truth)
}
#> Detecting communities...
#> Running pathway enrichment...
#> 'select()' returned 1:1 mapping between keys and columns
#> 'select()' returned 1:1 mapping between keys and columns
#> 'select()' returned 1:1 mapping between keys and columns
# Detect communities in consensus network
if (requireNamespace("igraph", quietly = TRUE)) {
    comm_cons <- community_path(consensus)
}
#> Detecting communities...
#> Running pathway enrichment...
#> 'select()' returned 1:1 mapping between keys and columns
#> 'select()' returned 1:1 mapping between keys and columns
#> 'select()' returned 1:1 mapping between keys and columns
#> 'select()' returned 1:1 mapping between keys and columns
Finally, we’ll quantify how similar the community structures are between our inferred consensus network and the ground-truth network using the broken-down functions:
# Calculate community metrics (VI, NMI, ARI)
if (requireNamespace("igraph", quietly = TRUE)) {
    comm_metrics <- compute_community_metrics(comm_truth, list(comm_cons))
    print(comm_metrics)
    # Calculate topology metrics (modularity, density, etc.)
    # Note: compute_topology_metrics expects community_path outputs
    # Returns a list with $topology_measures and $control_topology
    topo_metrics <- compute_topology_metrics(comm_truth, list(comm_cons))
    print(topo_metrics)
    # Visualize community comparison
    if (requireNamespace("fmsb", quietly = TRUE)) {
        plot_community_comparison(
            community_metrics = comm_metrics,
            topology_measures = topo_metrics$topology_measures,
            control_topology = topo_metrics$control_topology
        )
    }
}
#>                   VI       NMI        ARI
#> Predicted_1 2.249437 0.3907966 0.03584145
#> $topology_measures
#>             Modularity Communities   Density Transitivity
#> Predicted_1  0.4304142           5 0.1092437   0.09183673
#> 
#> $control_topology
#>   Modularity  Communities      Density Transitivity 
#>   0.81373569  10.00000000   0.05210084   0.46666667
Edge mining provides a detailed analysis of network reconstruction performance by categorizing each predicted edge as True Positive (TP), False Positive (FP), True Negative (TN), or False Negative (FN). This gives us insight into which specific regulatory relationships were successfully recovered. The function now returns a list of dataframes matching the documentation.
Edge Mining Analysis: - True Positives (TP): Correctly predicted edges that exist in ground truth - False Positives (FP): Incorrectly predicted edges not in ground truth - False Negatives (FN): Missed edges that exist in ground truth - True Negatives (TN): Correctly identified non-edges
em <- edge_mining(
    consensus,
    ground_truth = adj_truth,
    query_edge_types = "TP"
)
head(em[[1]])
#>     gene1 gene2 edge_type pubmed_hits
#> 6    CD3D  CD3E        TP          60
#> 9  COX4I1 COX7C        TP           2
#> 10   CD74 CXCR4        TP         137
#> 12 EEF1A1 EEF1D        TP           6
#> 15   EIF1 EIF3K        TP           0
#> 25   FTH1   FTL        TP         100
#>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  PMIDs
#> 6                                                                                                                                                                                                                                                                                                                                                                               40969714,40831791,40750862,40725440,40702236,40577225,40394466,39958562,39780208,39493321,39220810,38816839,37942472,37841886,37627776,37571885,37478215,37274867,37113759,37031292,36806614,36291815,36276947,36146529,35720370,35303369,35198572,35090306,34966587,34692491,34108992,33901225,33748188,33688252,33628209,33604380,32509861,32424701,31921117,31842801,30885360,29977931,29920501,29653965,28368009,26459776,25946140,25557485,24748432,21883749,21856934,20478055,16264327,15546002,11261926,7757067,1386345,1981047,2331673,3248386
#> 9                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    39623245,16865251
#> 10 41127012,40952055,40951943,40948762,40932351,40913267,40831537,40796616,40766141,40740771,40736341,40682854,40575951,40421217,40356050,40342960,40255236,40186663,40066443,40055309,40018995,39915484,39914814,39834330,39712016,39691708,39633216,39502000,39351536,39345457,39323959,39323779,39111632,39084404,39079349,39079345,39030653,39010084,38992165,38874510,38786064,38712609,38674069,38663915,38650025,38455420,38386050,38319415,38237304,38169915,38106024,38061122,37961378,37946732,37725104,37671160,37648811,37642473,37616250,37529341,37508563,37335089,36895934,36816799,36738160,36709495,36096455,35885004,35784460,35563296,35509079,35276027,35252348,35011861,34424927,34098338,34041839,33447370,33239628,33173092,33008022,32104230,31811089,31745887,31745866,31581595,31414920,31105032,31009094,30737274,30716779,30682543,30680604,30567353,30506423,30439447,30371153,30160778,30127875,29935880
#> 12                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               38173097,35685457,32025546,31639400,30370994,29342219
#> 15                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <NA>
#> 25 41068355,41044642,40948800,40679566,40409664,40358793,40257585,40139473,40048981,39988734,39954839,39906141,39849491,39800242,39534872,39475272,39419454,39334701,39294687,39294443,39148171,39147356,39053339,39041134,38923019,38765702,38740757,38685226,38683121,38561847,38556118,38505909,38393256,38262246,38221933,38160863,38056574,38007415,37976599,37964337,37867341,37851191,37839303,37788777,37664922,37660254,37605582,37555866,37283515,37270049,37198940,37143164,37101205,37094356,37086630,36922863,36909561,36831385,36778397,36728677,36647288,36608444,36562685,36547083,36477858,36066504,35918659,35661779,35598199,35543324,35449524,35249107,35100981,35008695,34938499,34864093,34825691,34787054,34732689,34707088,34660571,34547407,34258619,33864445,33402128,32377595,31920471,31401526,31320750,30325535,30076742,26765579,24496804,24448401,24007662,23766848,21555518,21029774,16760464,15099026
#>    query_status
#> 6    hits_found
#> 9    hits_found
#> 10   hits_found
#> 12   hits_found
#> 15      no_hits
#> 25   hits_found
sessionInfo()
#> R version 4.5.1 Patched (2025-08-23 r88802)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 24.04.3 LTS
#> 
#> Matrix products: default
#> BLAS:   /home/biocbuild/bbs-3.22-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] stats4    stats     graphics  grDevices utils     datasets  methods  
#> [8] base     
#> 
#> other attached packages:
#>  [1] TENxPBMCData_1.27.0         HDF5Array_1.38.0           
#>  [3] h5mread_1.2.0               rhdf5_2.54.0               
#>  [5] DelayedArray_0.36.0         SparseArray_1.10.0         
#>  [7] S4Arrays_1.10.0             abind_1.4-8                
#>  [9] Matrix_1.7-4                SingleCellExperiment_1.32.0
#> [11] SummarizedExperiment_1.40.0 Biobase_2.70.0             
#> [13] GenomicRanges_1.62.0        Seqinfo_1.0.0              
#> [15] IRanges_2.44.0              S4Vectors_0.48.0           
#> [17] BiocGenerics_0.56.0         generics_0.1.4             
#> [19] MatrixGenerics_1.22.0       matrixStats_1.5.0          
#> [21] scGraphVerse_1.0.0          BiocStyle_2.38.0           
#> 
#> loaded via a namespace (and not attached):
#>   [1] R.methodsS3_1.8.2           dichromat_2.0-0.1          
#>   [3] gld_2.6.8                   Biostrings_2.78.0          
#>   [5] vctrs_0.6.5                 ggtangle_0.0.7             
#>   [7] perturbR_0.1.3              digest_0.6.37              
#>   [9] png_0.1-8                   shape_1.4.6.1              
#>  [11] proxy_0.4-27                Exact_3.3                  
#>  [13] pcaPP_2.0-5                 BiocBaseUtils_1.12.0       
#>  [15] gypsum_1.6.0                ggrepel_0.9.6              
#>  [17] bst_0.3-24                  magick_2.9.0               
#>  [19] hdrcde_3.4                  MASS_7.3-65                
#>  [21] fontLiberation_0.1.0        reshape2_1.4.4             
#>  [23] foreach_1.5.2               qvalue_2.42.0              
#>  [25] withr_3.0.2                 xfun_0.53                  
#>  [27] ggfun_0.2.0                 survival_3.8-3             
#>  [29] doRNG_1.8.6.2               memoise_2.0.1              
#>  [31] ggbeeswarm_0.7.2            clusterProfiler_4.18.0     
#>  [33] gson_0.1.0                  systemfonts_1.3.1          
#>  [35] tidytree_0.4.6              networkD3_0.4.1            
#>  [37] gtools_3.9.5                R.oo_1.27.1                
#>  [39] WeightSVM_1.7-16            KEGGREST_1.50.0            
#>  [41] httr_1.4.7                  GENIE3_1.32.0              
#>  [43] fmsb_0.7.6                  hash_2.2.6.3               
#>  [45] rhdf5filters_1.22.0         rstudioapi_0.17.1          
#>  [47] DOSE_4.4.0                  curl_7.0.0                 
#>  [49] ScaledMatrix_1.18.0         ggraph_2.2.2               
#>  [51] polyclip_1.10-7             ExperimentHub_3.0.0        
#>  [53] stringr_1.5.2               pracma_2.4.6               
#>  [55] doParallel_1.0.17           evaluate_1.0.5             
#>  [57] BiocFileCache_3.0.0         hms_1.1.4                  
#>  [59] glmnet_4.1-10               bookdown_0.45              
#>  [61] irlba_2.3.5.1               colorspace_2.1-2           
#>  [63] filelock_1.0.3              reticulate_1.44.0          
#>  [65] readxl_1.4.5                magrittr_2.0.4             
#>  [67] readr_2.1.5                 viridis_0.6.5              
#>  [69] ggtree_4.0.0                lattice_0.22-7             
#>  [71] XML_3.99-0.19               scuttle_1.20.0             
#>  [73] cowplot_1.2.0               class_7.3-23               
#>  [75] pillar_1.11.1               nlme_3.1-168               
#>  [77] iterators_1.0.14            caTools_1.18.3             
#>  [79] compiler_4.5.1              beachmat_2.26.0            
#>  [81] stringi_1.8.7               DescTools_0.99.60          
#>  [83] plyr_1.8.9                  mpath_0.4-2.26             
#>  [85] fda_6.3.0                   crayon_1.5.3               
#>  [87] scater_1.38.0               gbm_2.2.2                  
#>  [89] gridGraphics_0.5-1          chron_2.3-62               
#>  [91] haven_2.5.5                 graphlayouts_1.2.2         
#>  [93] org.Hs.eg.db_3.22.0         bit_4.6.0                  
#>  [95] rootSolve_1.8.2.4           dplyr_1.1.4                
#>  [97] fastmatch_1.1-6             codetools_0.2-20           
#>  [99] BiocSingular_1.26.0         bslib_0.9.0                
#> [101] e1071_1.7-16                lmom_3.2                   
#> [103] alabaster.ranges_1.10.0     fds_1.8                    
#> [105] MultiAssayExperiment_1.36.0 splines_4.5.1              
#> [107] Rcpp_1.1.0                  dbplyr_2.5.1               
#> [109] sparseMatrixStats_1.22.0    cellranger_1.1.0           
#> [111] knitr_1.50                  blob_1.2.4                 
#> [113] BiocVersion_3.22.0          robin_2.0.0                
#> [115] fs_1.6.6                    DelayedMatrixStats_1.32.0  
#> [117] pscl_1.5.9                  expm_1.0-0                 
#> [119] ggplotify_0.1.3             sqldf_0.4-11               
#> [121] tibble_3.3.0                tzdb_0.5.0                 
#> [123] tweenr_2.0.3                pkgconfig_2.0.3            
#> [125] tools_4.5.1                 cachem_1.1.0               
#> [127] RSQLite_2.4.3               viridisLite_0.4.2          
#> [129] DBI_1.2.3                   numDeriv_2016.8-1.1        
#> [131] distributions3_0.2.3        celldex_1.19.0             
#> [133] fastmap_1.2.0               rmarkdown_2.30             
#> [135] scales_1.4.0                grid_4.5.1                 
#> [137] AnnotationHub_4.0.0         sass_0.4.10                
#> [139] patchwork_1.3.2             BiocManager_1.30.26        
#> [141] graph_1.88.0                alabaster.schemas_1.10.0   
#> [143] SingleR_2.12.0              rpart_4.1.24               
#> [145] farver_2.1.2                tidygraph_1.3.1            
#> [147] gsubfn_0.7                  yaml_2.3.10                
#> [149] deSolve_1.40                cli_3.6.5                  
#> [151] purrr_1.1.0                 lifecycle_1.0.4            
#> [153] askpass_1.2.1               rainbow_3.8                
#> [155] mvtnorm_1.3-3               BiocParallel_1.44.0        
#> [157] gtable_0.3.6                pROC_1.19.0.1              
#> [159] parallel_4.5.1              ape_5.8-1                  
#> [161] jsonlite_2.0.0              bitops_1.0-9               
#> [163] ggplot2_4.0.0               bit64_4.6.0-1              
#> [165] yulab.utils_0.2.1           alabaster.matrix_1.10.0    
#> [167] BiocNeighbors_2.4.0         proto_1.0.0                
#> [169] jquerylib_0.1.4             alabaster.se_1.10.0        
#> [171] GOSemSim_2.36.0             R.utils_2.13.0             
#> [173] lazyeval_0.2.2              alabaster.base_1.10.0      
#> [175] htmltools_0.5.8.1           enrichplot_1.30.0          
#> [177] GO.db_3.22.0                rappdirs_0.3.3             
#> [179] data.tree_1.2.0             tinytex_0.57               
#> [181] glue_1.8.0                  STRINGdb_2.22.0            
#> [183] httr2_1.2.1                 XVector_0.50.0             
#> [185] gdtools_0.4.4               RCurl_1.98-1.17            
#> [187] qpdf_1.4.1                  treeio_1.34.0              
#> [189] mclust_6.1.1                ks_1.15.1                  
#> [191] gridExtra_2.3               boot_1.3-32                
#> [193] igraph_2.2.1                R6_2.6.1                   
#> [195] tidyr_1.3.1                 fdatest_2.1.1              
#> [197] ggiraph_0.9.2               gplots_3.2.0               
#> [199] forcats_1.0.1               labeling_0.4.3             
#> [201] cluster_2.1.8.1             rngtools_1.5.2             
#> [203] Rhdf5lib_1.32.0             aplot_0.2.9                
#> [205] plotrix_3.8-4               tidyselect_1.2.1           
#> [207] vipor_0.4.7                 ggforce_0.5.0              
#> [209] fontBitstreamVera_0.1.1     AnnotationDbi_1.72.0       
#> [211] rsvd_1.0.5                  KernSmooth_2.23-26         
#> [213] S7_0.2.0                    fontquiver_0.2.1           
#> [215] data.table_1.17.8           htmlwidgets_1.6.4          
#> [217] fgsea_1.36.0                RColorBrewer_1.1-3         
#> [219] rlang_1.1.6                 rentrez_1.2.4              
#> [221] beeswarm_0.4.0