6 Vertical Integration

In horizontal integration, we have many datasets, all with the same features. They only differ because they were gathered at different times. In contrast, for vertical integration, we instead have many datasets all with the same samples. They differ because they measure different aspects of those samples. Our goal in this situation is not to remove differences across datasets, like it was in horizontal integration, but instead to clarify the relationships across sources.

One important question that often arises in vertical integration is – are the data even alignable? That is, in our effort to look for relationships across datasets, we might accidentally miss out on interesting variation that exists within the individual assays. If the technologies are measuring very different things, we might be better off simply analyzing the data separately. To help us gauge which setting we might be in, we can simulate data where we know that we shouldn’t align the sources. If our integration methods are giving similar outputs as they give on this simulated data, then we should be more cautious.

There are a few ways in which a dataset might not be ``alignable.’’ The most general reason is that there may be no latent sources of variation in common between the sources. A simpler reason is that something that influenced one assay substantially (e.g., disease state) might not influence the other by much. Let’s see how an integration method might work in this setting.

6.1 ICU Dataset

We’ll work with the ICU sepsis dataset previously studied by Haak et al. (2021) and documented within a vignette for the MOFA package. The three datasets here are 16S bacterial, ITS fungal, and Virome assays, all applied to different healthy and sepsis patient populations. Moreover, some participants were on a course of antibiotics while others were not. The question is how either sepsis, antibiotics, or their interaction affects the microbiome viewed through these three assays. The data are printed below, they have already been filtered and CLR transformed following the MOFA vignette.

data(icu)
icu
## $Bacteria
## # A SummarizedExperiment-tibble abstraction: 10,260 × 19
## # Features=180 | Samples=57 | Assays=clr
##    .feature   .sample    clr   Age Sexs  Diagnosis Category Penicillins Cephalosporins Carbapenems Macrolides Aminoglycosides Quinolones Co_trimoxazole Metronidazole Vancomycin Acetate Propionate
##    <chr>      <chr>    <dbl> <int> <chr> <chr>     <chr>    <lgl>       <lgl>          <lgl>       <lgl>      <lgl>           <lgl>      <lgl>          <lgl>         <lgl>        <dbl>      <dbl>
##  1 Acidamino… TKI_F1  -0.717    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  2 Actinomyc… TKI_F1  -0.717    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  3 Adlercreu… TKI_F1  -0.717    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  4 Agathobac… TKI_F1  -0.717    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  5 Akkermans… TKI_F1   1.68     89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  6 Alistipes  TKI_F1  10.9      89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  7 Allisonel… TKI_F1  -0.717    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  8 Alloprevo… TKI_F1  -0.717    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  9 Anaerofil… TKI_F1  -0.717    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
## 10 Anaerofus… TKI_F1  -0.717    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
## # ℹ 40 more rows
## # ℹ 1 more variable: Butyrate <dbl>
## 
## $Fungi
## # A SummarizedExperiment-tibble abstraction: 1,026 × 19
## # Features=18 | Samples=57 | Assays=clr
##    .feature   .sample    clr   Age Sexs  Diagnosis Category Penicillins Cephalosporins Carbapenems Macrolides Aminoglycosides Quinolones Co_trimoxazole Metronidazole Vancomycin Acetate Propionate
##    <chr>      <chr>    <dbl> <int> <chr> <chr>     <chr>    <lgl>       <lgl>          <lgl>       <lgl>      <lgl>           <lgl>      <lgl>          <lgl>         <lgl>        <dbl>      <dbl>
##  1 Agaricus   TKI_F1  -1.21     89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  2 Aspergill… TKI_F1   6.63     89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  3 Aureobasi… TKI_F1  -4.25     89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  4 Candida    TKI_F1   8.16     89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  5 Cladospor… TKI_F1   1.05     89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  6 Debaryomy… TKI_F1  -0.540    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  7 Dipodascus TKI_F1  -1.86     89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  8 Filobasid… TKI_F1  -1.21     89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  9 Issatchen… TKI_F1   0.141    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
## 10 Malassezia TKI_F1   0.764    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
## # ℹ 350 more rows
## # ℹ 1 more variable: Butyrate <dbl>
## 
## $Viruses
## # A SummarizedExperiment-tibble abstraction: 2,394 × 19
## # Features=42 | Samples=57 | Assays=clr
##    .feature   .sample    clr   Age Sexs  Diagnosis Category Penicillins Cephalosporins Carbapenems Macrolides Aminoglycosides Quinolones Co_trimoxazole Metronidazole Vancomycin Acetate Propionate
##    <chr>      <chr>    <dbl> <int> <chr> <chr>     <chr>    <lgl>       <lgl>          <lgl>       <lgl>      <lgl>           <lgl>      <lgl>          <lgl>         <lgl>        <dbl>      <dbl>
##  1 Acidovora… TKI_F1  -0.602    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  2 Acinetoba… TKI_F1  -0.602    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  3 Aeromonas… TKI_F1  -0.602    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  4 Anellovir… TKI_F1  -0.602    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  5 Arthrobac… TKI_F1  -0.602    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  6 Bacillus … TKI_F1  -0.602    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  7 Bacteroid… TKI_F1  -0.602    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  8 Bacteroid… TKI_F1  -0.602    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
##  9 Brochothr… TKI_F1  -0.602    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
## 10 Burkholde… TKI_F1  -0.602    89 Fema… Sepsis, … Sepsis   FALSE       FALSE          FALSE       FALSE      TRUE            TRUE       FALSE          FALSE         TRUE          6.44       2.40
## # ℹ 32 more rows
## # ℹ 1 more variable: Butyrate <dbl>

We can simultaneously analyze these data sources using block sPLS-DA. This is the multi-assay version of the analysis that we saw in the previous session. exper_splsda is a very light wrapper of a mixOmics function call, which you can read here. The output plot below shows that each assay differs across groups, and this is quantitatively summarized by the high estimated weights between each category and the estimated PLS directions.

fit <- exper_splsda(icu)
plotIndiv(fit)
fit$weights
##              comp1     comp2
## Bacteria 0.8580402 0.8191458
## Fungi    0.6513668 0.4845247
## Viruses  0.6118091 0.8047067

6.2 Interlude: Using map

In the examples below, we’ll find it helpful to use the function map in the purrr package. This function gives a one-line replacement for simple for-loops; it is analogous to list comprehensions in python. It can be useful many places besides the topic of this tutorial. For example, if we want to convert the vector c(1, 2, 3) into c(1, 4, 9), we can use this map:

map(1:3, ~ .^2)
## [[1]]
## [1] 1
## 
## [[2]]
## [1] 4
## 
## [[3]]
## [1] 9

The ~ notation is shorthand for defining a function, and the . represents the current vector element. More generally, we can apply map to lists. This line will update the list so that 1 is added to each element.

map(list(a = 1, b = 2, c = 3), ~ . + 1)
## $a
## [1] 2
## 
## $b
## [1] 3
## 
## $c
## [1] 4

Exercise: To test your understanding, can you write a map that computes the *mean for each vector in the list x below? What about the mean of the 10 smallest elements?

x <- list(a = rnorm(100), b = rnorm(100, 1))
map(x, mean)
## $a
## [1] 0.1177328
## 
## $b
## [1] 1.128995
map(x, ~ mean(sort(.)[1:10]))
## $a
## [1] -1.920247
## 
## $b
## [1] -0.8639795

6.3 Simulation Question

How would the output have looked if 16S community composition had not been related to disease or antibiotics groups? Since integrative analysis prioritizes similarities across sources, we expect this to mask some of the real differences in the fungal and virus data as well. We can use simulation to gauge the extent of this masking.

Our first step is to train a simulator. We’re just learning four different setes of parameters for each of the four observed groups. This is not as nuanced as learning separate effects for sepsis and antibiotics, but it will be enough for illustration. We have used map to estimate a simulator for each assay in the icu list.

simulator <- map(
  icu,
  ~ setup_simulator(., ~Category, ~ GaussianLSS()) |>
    estimate(nu = 0.05)
)

So far, we haven’t tried removing any relationships present in the 16S assay, and indeed our integrative analysis output on the simulated data looks comparable to that from the original study.

icu_sim <- join_copula(simulator, copula_adaptive()) |>
  sample() |>
  split_assays()

fit_sim <- exper_splsda(icu_sim)
plotIndiv(fit_sim)
fit$weights
##              comp1     comp2
## Bacteria 0.8580402 0.8191458
## Fungi    0.6513668 0.4845247
## Viruses  0.6118091 0.8047067

Exercise: Modify the simulator above so that the 16S group no longer depends on disease cateogry. This will allow us to study how the integrative analysis output changes when the data are not alignable.

null_simulator <- simulator
# fill this in
# null_simulator[[1]] <- ???

Solution: We need to define a new link that no longer depends on Category. One solution is to modify the existing simulator in place using mutate.

null_simulator[[1]] <- simulator[[1]] |>
  mutate(1:180, link = ~1) |>
  estimate(nu = 0.05)

Since we are modifying all taxa, a simpler solution is to just define a new simulator from scratch.

null_simulator[[1]] <- setup_simulator(icu[[1]], ~1, ~ GaussianLSS()) |>
  estimate(nu = 0.05)

6.4 Simulation Results

We can rerun the integrative analysis using the modified simulator. Somewhat surprisingly, the disease association in the bacteria group hasn’t been erased. This is an artifact of the integration. The other assays have associations with disease group, and since the method encourages outputs across tables to be consistent with one another, we have artificially introduced some structure into the bacteria visualization (even if it is quite weak.) Nonetheless, we still observe a large dropoff in weight for the bacterial table. Further, there seems to be a minor deterioration in the group separations for the fungal and virus communities, and the component weights are higher when we work with only the fungal and virus assays. Altogether, this suggests that we may want to check table-level associations with the response variable, especially if any of the integration outputs are ambiguous. In this case, we might be able to increase power by focusing only on class-associated assays. Nonetheless, the block sPLS-DA also seems relatively robust – considering the dramatic change in the microbiome table, the output for the remaining tables still surfaces interesting relationships.

icu_sim <- join_copula(null_simulator, copula_adaptive()) |>
  sample() |>
  split_assays()
fit_null <- exper_splsda(icu_sim)
plotIndiv(fit)
fit_null$weights
##              comp1     comp2
## Bacteria 0.6658170 0.6571177
## Fungi    0.7479665 0.6797712
## Viruses  0.7015960 0.7929047

6.5 Alignability

How do the canonical correlations compare between the real data and a reference null? First, we can compute the CCA canonical correlations using the real Bacteria and Virus data.

merged <- simulator[c(1, 3)] |>
  join_copula(copula_adaptive(thr = 0.01))

xy <- sample(merged) |>
  assay() |>
  t()
ix <- map(icu, rownames)
cca_result <- rcc(xy[, ix[[1]]], xy[, ix[[3]]], method = "shrinkage")

Next, we define a reference null and compute canonical correlations on ten replicates from this null. To define the reference null, we zero out any correlations across tables. We then draw 100 samples from the resulting distribution and compute canonical correlations for each.

rho_null <- copula_parameters(merged)
dimnames(rho_null) <- list(colnames(xy), colnames(xy))
rho_null[ix[[1]], ix[[3]]] <- 0
rho_null[ix[[3]], ix[[1]]] <- 0

null_cancor <- merged |>
  mutate_correlation(rho_null)

B <- 100
cancors <- list()
for (b in seq_len(B)) {
  xy_null <- sample(null_cancor) |>
    assay() |>
    t()

  cancors[[glue("sim_{b}")]] <- rcc(xy_null[, ix[[1]]], xy_null[, ix[[3]]], method = "shrinkage")$cor
}

To help with later visualization, we combine both the real and reference canonical correlations into a tidy data.frame. These are visualized in a hidden chunk below – if you want to see the source code, you can review it here.

cancors[["true"]] <- cca_result$cor
contrast_data <- bind_rows(cancors, .id = "rep") |>
  pivot_longer(-rep, names_to = "loading") |>
  mutate(
    source = grepl("true", rep),
    loading = as.integer(loading)
  )
head(contrast_data)
## # A tibble: 6 × 4
##   rep   loading value source
##   <chr>   <int> <dbl> <lgl> 
## 1 sim_1       1 0.913 FALSE 
## 2 sim_1       2 0.880 FALSE 
## 3 sim_1       3 0.848 FALSE 
## 4 sim_1       4 0.826 FALSE 
## 5 sim_1       5 0.815 FALSE 
## 6 sim_1       6 0.797 FALSE
## R version 4.4.1 Patched (2024-08-21 r87049)
## Platform: aarch64-apple-darwin20
## Running under: macOS Sonoma 14.5
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib 
## LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.0
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## time zone: America/Chicago
## tzcode source: internal
## 
## attached base packages:
##  [1] splines   parallel  stats4    stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] lubridate_1.9.3                 readr_2.1.5                     tidyverse_2.0.0                 doRNG_1.8.6                     rngtools_1.5.2                 
##  [6] foreach_1.5.2                   ggpubr_0.6.0                    ggrepel_0.9.6                   edgeR_4.3.16                    limma_3.61.10                  
## [11] ANCOMBC_2.7.0                   stringr_1.5.1                   ks_1.14.3                       tidySummarizedExperiment_1.15.1 ttservice_0.4.1                
## [16] SimBench_0.99.1                 wesanderson_0.3.7               mia_1.13.36                     MultiAssayExperiment_1.31.5     TreeSummarizedExperiment_2.13.0
## [21] Biostrings_2.73.1               XVector_0.45.0                  SingleCellExperiment_1.27.2     gamlss_5.4-22                   nlme_3.1-166                   
## [26] gamlss.dist_6.1-1               gamlss.data_6.0-6               scDesigner_0.0.0.9000           purrr_1.0.2                     MIGsim_0.0.0.9000              
## [31] tidyr_1.3.1                     tibble_3.2.1                    scico_1.5.0                     pwr_1.3-0                       patchwork_1.3.0                
## [36] mutoss_0.1-13                   mvtnorm_1.3-1                   mixOmics_6.29.0                 lattice_0.22-6                  MASS_7.3-61                    
## [41] glue_1.8.0                      ggplot2_3.5.1                   ggdist_3.3.2                    gamboostLSS_2.0-7               mboost_2.9-11                  
## [46] stabs_0.6-4                     forcats_1.0.0                   dplyr_1.1.4                     SummarizedExperiment_1.35.1     Biobase_2.65.1                 
## [51] GenomicRanges_1.57.1            GenomeInfoDb_1.41.1             IRanges_2.39.2                  S4Vectors_0.43.2                BiocGenerics_0.51.1            
## [56] MatrixGenerics_1.17.0           matrixStats_1.4.1               SpiecEasi_1.1.3                 CovTools_0.5.4                 
## 
## loaded via a namespace (and not attached):
##   [1] igraph_2.0.3                ica_1.0-3                   plotly_4.10.4               Formula_1.2-5               scater_1.33.4               BiocBaseUtils_1.7.3        
##   [7] zlibbioc_1.51.1             tidyselect_1.2.1            bit_4.5.0                   doParallel_1.0.17           pspline_1.0-20              blob_1.2.4                 
##  [13] S4Arrays_1.5.8              png_0.1-8                   plotrix_3.8-4               cli_3.6.3                   CVXR_1.0-14                 pulsar_0.3.11              
##  [19] arrayhelpers_1.1-0          multtest_2.61.0             goftest_1.2-3               textshaping_0.4.0           bluster_1.15.1              BiocNeighbors_1.99.1       
##  [25] uwot_0.2.2                  mime_0.12                   evaluate_1.0.0              tidytree_0.4.6              leiden_0.4.3.1              stringi_1.8.4              
##  [31] backports_1.5.0             XML_3.99-0.17               lmerTest_3.1-3              Exact_3.3                   gsl_2.1-8                   httpuv_1.6.15              
##  [37] AnnotationDbi_1.67.0        magrittr_2.0.3              mclust_6.1.1                ADGofTest_0.3               pcaPP_2.0-5                 rootSolve_1.8.2.4          
##  [43] sctransform_0.4.1           lpSolve_5.6.21              ggbeeswarm_0.7.2            DBI_1.2.3                   genefilter_1.87.0           jquerylib_0.1.4            
##  [49] withr_3.0.1                 corpcor_1.6.10              systemfonts_1.1.0           class_7.3-22                lmtest_0.9-40               sva_3.53.0                 
##  [55] compositions_2.0-8          htmlwidgets_1.6.4           fs_1.6.4                    labeling_0.4.3              SparseArray_1.5.38          DEoptimR_1.1-3             
##  [61] cellranger_1.1.0            DESeq2_1.45.3               tidybayes_3.0.7             extrafont_0.19              annotate_1.83.0             lmom_3.0                   
##  [67] flare_1.7.0.1               reticulate_1.39.0           minpack.lm_1.2-4            geigen_2.3                  zoo_1.8-12                  knitr_1.48                 
##  [73] nnls_1.5                    UCSC.utils_1.1.0            svUnit_1.0.6                SHT_0.1.8                   timechange_0.3.0            decontam_1.25.0            
##  [79] fansi_1.0.6                 grid_4.4.1                  rhdf5_2.49.0                data.table_1.16.0           ruv_0.9.7.1                 vegan_2.6-8                
##  [85] RSpectra_0.16-2             irlba_2.3.5.1               extrafontdb_1.0             DescTools_0.99.56           ellipsis_0.3.2              fastDummies_1.7.4          
##  [91] ade4_1.7-22                 lazyeval_0.2.2              yaml_2.3.10                 survival_3.7-0              scattermore_1.2             crayon_1.5.3               
##  [97] mediation_4.5.0             tensorA_0.36.2.1            phyloseq_1.49.0             RcppAnnoy_0.0.22            RColorBrewer_1.1-3          progressr_0.14.0           
## [103] later_1.3.2                 ggridges_0.5.6              codetools_0.2-20            base64enc_0.1-3             Seurat_5.1.0                KEGGREST_1.45.1            
## [109] Rtsne_0.17                  shape_1.4.6.1               randtoolbox_2.0.4           foreign_0.8-87              pkgconfig_2.0.3             xml2_1.3.6                 
## [115] spatstat.univar_3.0-1       downlit_0.4.4               scatterplot3d_0.3-44        spatstat.sparse_3.1-0       ape_5.8                     viridisLite_0.4.2          
## [121] xtable_1.8-4                highr_0.11                  car_3.1-2                   fastcluster_1.2.6           plyr_1.8.9                  httr_1.4.7                 
## [127] rbibutils_2.2.16            tools_4.4.1                 globals_0.16.3              SeuratObject_5.0.2          kde1d_1.0.7                 beeswarm_0.4.0             
## [133] htmlTable_2.4.3             broom_1.0.6                 checkmate_2.3.2             rgl_1.3.1                   assertthat_0.2.1            lme4_1.1-35.5              
## [139] rngWELL_0.10-9              digest_0.6.37               bayesm_3.1-6                permute_0.9-7               numDeriv_2016.8-1.1         bookdown_0.40              
## [145] Matrix_1.7-0                tzdb_0.4.0                  farver_2.1.2                reshape2_1.4.4              yulab.utils_0.1.7           viridis_0.6.5              
## [151] DirichletMultinomial_1.47.0 rpart_4.1.23                cachem_1.1.0                polyclip_1.10-7             WGCNA_1.73                  Hmisc_5.1-3                
## [157] generics_0.1.3              dynamicTreeCut_1.63-1       parallelly_1.38.0           biomformat_1.33.0           statmod_1.5.0               impute_1.79.0              
## [163] huge_1.3.5                  ragg_1.3.3                  RcppHNSW_0.6.0              ScaledMatrix_1.13.0         carData_3.0-5               minqa_1.2.8                
## [169] pbapply_1.7-2               glmnet_4.1-8                spam_2.10-0                 utf8_1.2.4                  gtools_3.9.5                shapes_1.2.7               
## [175] readxl_1.4.3                preprocessCore_1.67.0       inum_1.0-5                  ggsignif_0.6.4              energy_1.7-12               gridExtra_2.3              
## [181] shiny_1.9.1                 GenomeInfoDbData_1.2.12     rhdf5filters_1.17.0         memoise_2.0.1               rmarkdown_2.28              scales_1.3.0               
## [187] gld_2.6.6                   stabledist_0.7-2            partykit_1.2-22             svglite_2.1.3               future_1.34.0               RANN_2.6.2                 
## [193] spatstat.data_3.1-2         rstudioapi_0.16.0           cluster_2.1.6               spatstat.utils_3.1-0        hms_1.1.3                   fitdistrplus_1.2-1         
## [199] munsell_0.5.1               cowplot_1.1.3               colorspace_2.1-1            ellipse_0.5.0               rlang_1.1.4                 quadprog_1.5-8             
## [205] copula_1.1-4                DelayedMatrixStats_1.27.3   sparseMatrixStats_1.17.2    dotCall64_1.1-1             scuttle_1.15.4              mgcv_1.9-1                 
## [211] xfun_0.47                   coda_0.19-4.1               e1071_1.7-16                TH.data_1.1-2               posterior_1.6.0             iterators_1.0.14           
## [217] rARPACK_0.11-0              abind_1.4-8                 libcoin_1.0-10              treeio_1.29.1               gmp_0.7-5                   Rhdf5lib_1.27.0            
## [223] DECIPHER_3.1.4              Rdpack_2.6.1                promises_1.3.0              RSQLite_2.3.7               sandwich_3.1-1              proxy_0.4-27               
## [229] DelayedArray_0.31.11        Rmpfr_0.9-5                 GO.db_3.20.0                compiler_4.4.1              prettyunits_1.2.0           boot_1.3-31                
## [235] distributional_0.5.0        beachmat_2.21.6             rbiom_1.0.3                 listenv_0.9.1               Rcpp_1.0.13                 Rttf2pt1_1.3.12            
## [241] BiocSingular_1.21.4         tensor_1.5                  progress_1.2.3              BiocParallel_1.39.0         insight_0.20.5              spatstat.random_3.3-2      
## [247] R6_2.5.1                    fastmap_1.2.0               multcomp_1.4-26             rstatix_0.7.2               vipor_0.4.7                 ROCR_1.0-11                
## [253] rsvd_1.0.5                  nnet_7.3-19                 gtable_0.3.5                KernSmooth_2.23-24          miniUI_0.1.1.1              deldir_2.0-4               
## [259] htmltools_0.5.8.1           ggthemes_5.1.0              RcppParallel_5.1.9          bit64_4.5.2                 spatstat.explore_3.3-2      lifecycle_1.0.4            
## [265] nloptr_2.1.1                sass_0.4.9                  vctrs_0.6.5                 robustbase_0.99-4           VGAM_1.1-12                 slam_0.1-53                
## [271] spatstat.geom_3.3-3         sp_2.1-4                    future.apply_1.11.2         pracma_2.4.4                rvinecopulib_0.6.3.1.1      bslib_0.8.0                
## [277] pillar_1.9.0                locfit_1.5-9.10             jsonlite_1.8.9              expm_1.0-0