Overview

This tutorial demonstrates how to use SRTpipeline (>=0.1.0) to analyze a spatially-resolved transcriptomics (SRT) data from seqFISH platform. The analytical pipelines are similar to the SRTpipeline workflow for Visium SRT analysis. We emphases how to use SC-MEB model for spatial clustering and its followed applications. This tutorial will cover the following tasks, which we believe will be common for many spatial analyses:

  • Normalization
  • Dimension reduction
  • Spatial clustering
  • Detecting spatially-variable features
  • DEG analysis
  • Spatial trajectory inference
  • Visualization

First, we load SRTpipeline.

Dataset

For this tutorial, we will introduce how to create a SRTProject object with single SRT sample using SRTpipeline that includes an introduction to common analytical workflows for a single data batch. Here, we will be taking a spatial transcriptomics dataset for mouse embryo as an example. There are 23194 spots and 351 genes that were sequenced on the seqFISH platform. Our preprocessed data can be downloaded here.

We download the data to the current working path for the followed analysis by the following command:

githubURL <- "https://github.com/feiyoung/PRECAST/blob/main/vignettes_data/Embryo3_seqFISH.rds?raw=true"
# download.file(githubURL,'Embryo3_seqFISH.rds',mode='wb')

Then load to R. The data is saved in a Seurat object named Embryo3_seqFISH.rds.

load("Embryo3_seqFISH.rds")

Pre-processing workflow

Create a SRTProject object

First, we show how to create a SRTProject object step by step.

## create count matrix list: note each component has a name, i.e., `embryo3`.
count_matrix <- seu_em3[["RNA"]]@counts
cntList <- list(embryo3 = count_matrix)

## create spatial coordinate matrix
coordList <- list(cbind(seu_em3$x_global, seu_em3$y_global))

## create metadata list
meta.data <- seu_em3@meta.data
metadataList <- list(meta.data)

## create meta data for each data batches. Here we only have one data batch.
sampleMetadata <- data.frame(species = "Mouse", tissues = c("Embryo"))
row.names(sampleMetadata) <- names(cntList)

## Name of this project
projectName <- "Embryo3"

rm(seu_em3)

Next, we start creating SRTProject object. We can print the basic information of this object, including three parts. The first part have the class of this object, outputPath of data that require to output, h5filePath that save the memory-cusuming data (i.e., count, logcount, …). The second part is about the datasets basic information, such as how many data batches(sample) and the data names, sample meta data (sampleColData) and meta data for each spot (cellMetaData). The last part is about downstream analyses information that is empty when this object created.

SRTProj <- CreateSRTProject(cntList, coordList, projectName = projectName, metadataList, sampleMetadata)
SRTProj
## class: SRTProject 
## outputPath: F:\Research paper\IntegrateDRcluster\AnalysisCode\SRTpipeline\vignettes\Embryo3 
## h5filePath: F:\Research paper\IntegrateDRcluster\AnalysisCode\SRTpipeline\vignettes\Embryo3/Embryo3.h5 
## ---------Datasets basic information-----------------
## samples(1): embryo3
## sampleColData names(3): species tissues NumOfSpots
## cellMetaData names(18): orig.ident nCount_RNA ...
##   celltype_mapped_refined batch
## numberOfSpots(1): 23194
## ---------Downstream analyses information-----------------
## Low-dimensional embeddings(0):
## Inferred cluster labels: No
## Embedding for plotting(0):

Normalizing the data

After creating the SRTProject, the next step is to normalize the data. To save RAM memory, normalized values are stored in disk as a h5file.

SRTProj <- normalizeSRT(SRTProj, force = T)

Because seqFISH technology is based on target-genes, we do not select genes but use all the targeted genes by the argument use_custom_features. Then the custom features will be regarded as variable features for the followed analyses.

geneNames <- row.names(SRTProj@geneMetaData)
SRTProj <- selectVariableFeatures(SRTProj, use_custom_features = geneNames)
SRTProj
## class: SRTProject 
## outputPath: F:\Research paper\IntegrateDRcluster\AnalysisCode\SRTpipeline\vignettes\Embryo3 
## h5filePath: F:\Research paper\IntegrateDRcluster\AnalysisCode\SRTpipeline\vignettes\Embryo3/Embryo3.h5 
## ---------Datasets basic information-----------------
## samples(1): embryo3
## sampleColData names(3): species tissues NumOfSpots
## cellMetaData names(18): orig.ident nCount_RNA ...
##   celltype_mapped_refined batch
## numberOfSpots(1): 23194
## ---------Downstream analyses information-----------------
## Variable features:  351 
## Low-dimensional embeddings(0):
## Inferred cluster labels: No
## Embedding for plotting(0):

Calculate the adjcence matrix

## Obtain adjacence matrix
SRTProj <- AddAdj(SRTProj, platform = "Other", radius.upper = 12)

Visualize

selectFeatures <- row.names(SRTProj@geneMetaData)[1:2]
EachExprSpaHeatMap(SRTProj, features = selectFeatures, title_name = T, quantVec = c(0.9, 0.9))

Dimension reduction

PCA is the most popular dimension reduction technique in single cell RNA sequencing (scRNA-seq) data and SRT data because of its simplicity, computational efficiency, and relatively comparable performance. SRTpipeline provided three versions of PCA: standard PCA (PCA), approximated PCA (APCA), and weighted PCA (WPCA) by the function AddPCA with default version as APCA for fastest computation. The 15-dimensional PCs are extracted by default, and users can use their own values.

After running AddPCA, we would see the output of SRTProj includes PCA in the Low-dimensional embeddings field.

## APCA
SRTProj <- AddPCA(SRTProj, n_comp = 15)
# accurate PCA

# SRTProj <- AddPCA(SRTProj, Method='PCA')

# weighted PCA

# SRTProj <- AddPCA(SRTProj, Method='WPCA')
SRTProj
## class: SRTProject 
## outputPath: F:\Research paper\IntegrateDRcluster\AnalysisCode\SRTpipeline\vignettes\Embryo3 
## h5filePath: F:\Research paper\IntegrateDRcluster\AnalysisCode\SRTpipeline\vignettes\Embryo3/Embryo3.h5 
## ---------Datasets basic information-----------------
## samples(1): embryo3
## sampleColData names(3): species tissues NumOfSpots
## cellMetaData names(18): orig.ident nCount_RNA ...
##   celltype_mapped_refined batch
## numberOfSpots(1): 23194
## ---------Downstream analyses information-----------------
## Variable features:  351 
## Low-dimensional embeddings(1): PCA
## Inferred cluster labels: No
## Embedding for plotting(0):

Clustering using SC-MEB

Some SRT clustering methods use Markov random field to model clusters of spots, such as SC-MEB and DR-SC. These approaches work extremely well for data with spatial smoothness and are standard practice in SRT data. For this reason, SRTpipeline uses existing state-of-the-art clustering methods from SRT packages for clustering.

We have had the most success using the Markov random field model implemented by SC-MEB. In SRTpipeline, SC-MEB clustering is performed using the Cluster_SCMEB() function.

SRTProj <- Cluster_SCMEB(SRTProj, K = 25, reduction = "PCA")
## diff Energy = 65.622244
SRTProj
## class: SRTProject 
## outputPath: F:\Research paper\IntegrateDRcluster\AnalysisCode\SRTpipeline\vignettes\Embryo3 
## h5filePath: F:\Research paper\IntegrateDRcluster\AnalysisCode\SRTpipeline\vignettes\Embryo3/Embryo3.h5 
## ---------Datasets basic information-----------------
## samples(1): embryo3
## sampleColData names(3): species tissues NumOfSpots
## cellMetaData names(18): orig.ident nCount_RNA ...
##   celltype_mapped_refined batch
## numberOfSpots(1): 23194
## ---------Downstream analyses information-----------------
## Variable features:  351 
## Low-dimensional embeddings(1): PCA
## Inferred cluster labels: Yes
## Embedding for plotting(0):

Visualization

To run tSNE in SRTpipeline we use the AddTSNE() function.

SRTProj <- AddTSNE(SRTProj, n_comp = 2, reduction = "PCA")
cols_cluster <- c(chooseColors(palettes_name = "Blink 23", n_colors = 23), "red4", "green4")
p_pca_tsne2 <- EmbedPlot(SRTProj, item = "cluster", plotEmbeddings = "tSNE", cols = cols_cluster,
    legend.position = "right")

To run UMAP in SRTpipeline we use the AddUMAP() function.

SRTProj <- AddUMAP(SRTProj, n_comp = 2, reduction = "PCA")
p_pca_umap2 <- EmbedPlot(SRTProj, item = "cluster", plotEmbeddings = "UMAP", cols = cols_cluster,
    legend.position = "right", axis_names = c("UMAP1", "UMAP2"))

Next, we merge all plots into one figure.

p_all <- drawFigs(list(p_pca_tsne2, p_pca_umap2), layout.dim = c(1, 2), common.legend = TRUE)
p_all

To save the plot, we can use write_fig() function.

write_fig(p_all, filename = "SCMEB_plots.png")

Except for the embedding plots, SRTpipeline also provides a variaty of visualization functions. First, we visualize the spatial distribution of cluster labels that shows the layer structure.

## choose colors to function chooseColors
EachClusterSpaHeatMap(SRTProj, cols = cols_cluster, legend.position = "right", base_size = 16, pt_size = 0.4)

# remove the border EachClusterSpaHeatMap(SRTProj, cols=cols,
# legend.position='right',base_size=16, border_col='white')

We plotted the heatmap of Pearson’s correlation coefcients of the PCA embeddings among the detected domains shows the good separation of the estimated embeddings across domains and the correlations between deeper layers were high, e.g., there were high correlations between domain 2 and 3, while correlations among the separated layers were low, i.e., domain 1 and 4.

CCHeatMap(SRTProj, reduction = "PCA", grp_color = cols_cluster, ncol.legend = 4)

After adding the quantities for data visualization, the SRTProject object will have more information in the downstream analyses information. Now, we print this SRTProject object to check it. We observed two components added in the slot plotEmbeddings (Embeddings for plotting): tSNE and UMAP.

SRTProj
## class: SRTProject 
## outputPath: F:\Research paper\IntegrateDRcluster\AnalysisCode\SRTpipeline\vignettes\Embryo3 
## h5filePath: F:\Research paper\IntegrateDRcluster\AnalysisCode\SRTpipeline\vignettes\Embryo3/Embryo3.h5 
## ---------Datasets basic information-----------------
## samples(1): embryo3
## sampleColData names(3): species tissues NumOfSpots
## cellMetaData names(18): orig.ident nCount_RNA ...
##   celltype_mapped_refined batch
## numberOfSpots(1): 23194
## ---------Downstream analyses information-----------------
## Variable features:  351 
## Low-dimensional embeddings(1): PCA
## Inferred cluster labels: Yes
## Embedding for plotting(2): tSNE UMAP

DEG analysis

To do downstream analyses, we require to get the count data from h5file. The function getGeneSpotData() access the gene-by-spot count matrix and other data in SRTProj and then return a SpatialExperiment object, including two assays: counts, logcounts; rowData: from SRTProj@geneMetaData; colData: from SRTProj@cellMetaData, SRTProj@clusters and sample_id; reducedDim: from SRTProj@reductions.

spe <- getGeneSpotData(SRTProj)
spe
## class: SpatialExperiment 
## dim: 351 23194 
## metadata(0):
## assays(2): counts logcounts
## rownames(351): Abcc4 Acp5 ... Zfp57 Zic3
## rowData names(1): isVGs.combine
## colnames(23194): embryo3#embryo3_Pos0_cell10_z2
##   embryo3#embryo3_Pos0_cell10_z5 ... embryo3#embryo3_Pos39_cell98_z5
##   embryo3#embryo3_Pos39_cell99_z2
## colData names(20): orig.ident nCount_RNA ... clusters sample_id
## reducedDimNames(4): PCA tSNE UMAP Coord
## mainExpName: NULL
## altExpNames(0):
## spatialData names(0) :
## spatialCoords names(2) : V1 V2
## imgData names(0):

We perform differential expression analysis for all clusters by using FindAllDEGs() function, then the DE genes’ information is saved in a DataFrame object dat_degs.

dat_degs <- FindAllDEGs(spe)
dat_degs
## DataFrame with 4031 rows and 7 columns
##               p_val avg_log2FC     pct.1     pct.2   p_val_adj  cluster
##           <numeric>  <numeric> <numeric> <numeric>   <numeric> <factor>
## Sox4    9.98183e-60  -1.136041     0.165     0.672 3.50362e-57        1
## Marcks  9.93938e-55  -1.108176     0.142     0.606 3.48872e-52        1
## Setd1a  1.09492e-46  -1.001061     0.136     0.569 3.84318e-44        1
## Kmt2b   1.66724e-46  -0.971486     0.169     0.632 5.85201e-44        1
## F2r     3.07166e-45  -1.023345     0.078     0.452 1.07815e-42        1
## ...             ...        ...       ...       ...         ...      ...
## Gypa.4  1.42749e-05  -0.256357     0.071     0.131  0.00501048       25
## Isl1.21 1.57008e-05  -0.264269     0.128     0.200  0.00551099       25
## Bmp2.12 1.87106e-05  -0.262016     0.106     0.173  0.00656742       25
## T.12    5.11573e-05  -0.254265     0.113     0.178  0.01795622       25
## Fgf15.5 5.60192e-05  -0.252738     0.072     0.128  0.01966273       25
##                gene
##         <character>
## Sox4           Sox4
## Marcks       Marcks
## Setd1a       Setd1a
## Kmt2b         Kmt2b
## F2r             F2r
## ...             ...
## Gypa.4         Gypa
## Isl1.21        Isl1
## Bmp2.12        Bmp2
## T.12              T
## Fgf15.5       Fgf15

We identify the significant DE genes by two criteria: (a) adjustd p-value less than 0.01 and (b) average log fold change greater than 0.4.

degs_sig <- subset(dat_degs, p_val_adj < 0.01 & avg_log2FC > 1)
degs_sig
## DataFrame with 203 rows and 7 columns
##                  p_val avg_log2FC     pct.1     pct.2    p_val_adj  cluster
##              <numeric>  <numeric> <numeric> <numeric>    <numeric> <factor>
## Foxa1.1              0    1.66291     0.767     0.131            0        2
## Cdh1.1               0    1.62270     0.750     0.121            0        2
## Shh.1                0    1.59177     0.639     0.097            0        2
## Cldn4.1              0    1.57513     0.788     0.157            0        2
## Foxa2.1              0    1.40669     0.624     0.112            0        2
## ...                ...        ...       ...       ...          ...      ...
## Pax8.5     7.00383e-97    1.06645     0.407     0.109  2.45835e-94       24
## Gata3.16   1.86058e-82    1.01690     0.492     0.187  6.53064e-80       24
## Prrx1.15   0.00000e+00    1.39438     0.810     0.235  0.00000e+00       25
## Tfap2a.15 2.08217e-248    1.30171     0.653     0.164 7.30841e-246       25
## Msx1.19   8.48764e-138    1.02382     0.601     0.212 2.97916e-135       25
##                  gene
##           <character>
## Foxa1.1         Foxa1
## Cdh1.1           Cdh1
## Shh.1             Shh
## Cldn4.1         Cldn4
## Foxa2.1         Foxa2
## ...               ...
## Pax8.5           Pax8
## Gata3.16        Gata3
## Prrx1.15        Prrx1
## Tfap2a.15      Tfap2a
## Msx1.19          Msx1

In the following, we perform gene set enrichment analysis for the DE genes of each Domain identified by SC-MEB model using R package gprofiler2.

library(gprofiler2)
termList <- list()
for (k in 1:25) {
    # k <- 1
    cat("k = ", k, "\n")
    if (sum(degs_sig$cluster == k) > 0) {
        dat_degs_sub <- subset(degs_sig, cluster == k)
        que1 <- dat_degs_sub$gene
        gostres <- gost(query = que1, organism = "hsapiens", correction_method = "fdr")
        termList[[k]] <- gostres
    }

}
## k =  1 
## k =  2 
## k =  3 
## k =  4 
## k =  5 
## k =  6 
## k =  7 
## k =  8 
## k =  9 
## k =  10 
## k =  11 
## k =  12 
## k =  13 
## k =  14 
## k =  15 
## k =  16 
## k =  17 
## k =  18 
## k =  19 
## k =  20 
## k =  21 
## k =  22 
## k =  23 
## k =  24 
## k =  25
head(termList[[2]]$result)
##     query significant      p_value term_size query_size intersection_size
## 1 query_1        TRUE 4.066137e-05       946         10                 7
## 2 query_1        TRUE 5.426093e-05        21         10                 3
## 3 query_1        TRUE 6.671020e-05         2         10                 2
## 4 query_1        TRUE 6.671020e-05        28         10                 3
## 5 query_1        TRUE 1.760578e-04      1521         10                 7
## 6 query_1        TRUE 1.760578e-04        43         10                 3
##   precision      recall    term_id source
## 1       0.7 0.007399577 GO:0098609  GO:BP
## 2       0.3 0.142857143 GO:2000047  GO:BP
## 3       0.2 1.000000000 GO:0060738  GO:BP
## 4       0.3 0.107142857 GO:0044331  GO:BP
## 5       0.7 0.004602235 GO:0007155  GO:BP
## 6       0.3 0.069767442 GO:0071542  GO:BP
##                                                                 term_name
## 1                                                      cell-cell adhesion
## 2                   regulation of cell-cell adhesion mediated by cadherin
## 3 epithelial-mesenchymal signaling involved in prostate gland development
## 4                                 cell-cell adhesion mediated by cadherin
## 5                                                           cell adhesion
## 6                                     dopaminergic neuron differentiation
##   effective_domain_size source_order                            parents
## 1                 21092        21975                         GO:0007155
## 2                 21092        29255             GO:0022407, GO:0044331
## 3                 21092        17471 GO:0022414, GO:0030850, GO:0060684
## 4                 21092        12705                         GO:0098609
## 5                 21092         3051                         GO:0009987
## 6                 21092        19530                         GO:0030182

To understand the functions of the identified spatial domains by DR-SC model, we compare the top significant biological process (BP) pathways in GO database for the DE genes from Domain 1 and 2. Here, we only show to visualize the significant BP pathways and users can explore the other databases such as KEGG and HPA.

## Most commonly used databases
source_set <- c("GO:BP", "GO:CC", "GO:MF", "KEGG", "HPA")
cols <- c("steelblue3", "goldenrod", "brown3", "#f98866", "#CE6DBD")
## Here, we show GO:BP
source1 <- "GO:BP"
ss <- which(source_set == source1)
ntop = 5
names(cols) <- source_set
pList_enrich <- list()
for (ii in 1:25) {
    ## ii <- 4
    message("ii=", ii)
    dat <- termList[[ii]]$result
    if (!is.null(dat)) {
        dat1 <- subset(dat, term_size < 500)
        dat1 <- get_top_pathway(dat1, ntop = ntop, source_set = source1)
        dat1 <- dat1[complete.cases(dat1), ]
        dat1$nlog10P <- -log10(dat1$p_value)

        pList_enrich[[ii]] <- barPlot_enrich(dat1[order(dat1$nlog10P), ], source = "source", "term_name",
            "nlog10P", cols = cols[source_set[ss]], base_size = 14) + ylab("-log10(p-adj)") + xlab("Biological terms") +
            ggtitle(paste0("Domain", ii))
    }

}

drawFigs(pList_enrich[c(2:3)], common.legend = T, layout.dim = c(2, 1), align = "hv")

We take out the top DE genes for each cluster for visualization.

library(dplyr)
n <- 3
dat_degs %>%
    as.data.frame %>%
    group_by(cluster) %>%
    top_n(n = n, wt = avg_log2FC) -> topGene
topGene
## # A tibble: 75 x 7
## # Groups:   cluster [25]
##          p_val avg_log2FC pct.1 pct.2 p_val_adj cluster gene 
##          <dbl>      <dbl> <dbl> <dbl>     <dbl> <fct>   <chr>
##  1 0.000000117     -0.285 0.027 0.103 0.0000411 1       Wisp1
##  2 0.000000160     -0.282 0.031 0.108 0.0000562 1       Tdo2 
##  3 0.000000223     -0.283 0.027 0.1   0.0000781 1       Mixl1
##  4 0                1.66  0.767 0.131 0         2       Foxa1
##  5 0                1.62  0.75  0.121 0         2       Cdh1 
##  6 0                1.59  0.639 0.097 0         2       Shh  
##  7 0                1.43  0.802 0.208 0         3       Cdh5 
##  8 0                1.35  0.835 0.263 0         3       Plvap
##  9 0                1.31  0.68  0.172 0         3       Cd34 
## 10 0                1.42  0.908 0.271 0         4       Foxf1
## # ... with 65 more rows

We visualize the DE genes for each cluster group by gene-by-cell heatmap using the GCHeatMap() function.

p1 <- EachGCHeatMap(spe, features = topGene$gene, grp_color = cols_cluster, y_text_size = 6, ncol.legend = 3)
p1

Trajectory inference

Next, we performed trajectory inference using the PCA embeddings and domain labels estimated by SC-MEB model. The EmbedPlot() function can be used to visualize the inferred pseudotime on a specified embedding. If there is only one data batch, the function EachEmbedPlot() plays the same role as function EmbedPlot().

spe <- AddTrajectory(spe, reduction = "PCA", name = "PT")
p1 <- EmbedPlot(spe, reduction = "PCA", colour_by = "PT")
p2 <- EmbedPlot(spe, reduction = "Coord", colour_by = "PT")
drawFigs(list(p1, p2), layout.dim = c(1, 2), common.legend = TRUE, legend.position = "right")

# EachEmbedPlot(spe, reduction = 'PCA', colour_by='TrajPT') save(spe, SRTProj,
# file=paste0(SRTProj@projectMetadata$outputPath,'/SRTProj.rds')) load('F:/Research
# paper/IntegrateDRcluster/AnalysisCode/SRTpipeline/vignettes/Embryo3/SRTProj.rds')

Other downstream analyses

Session Info

## R version 4.1.2 (2021-11-01)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 22621)
## 
## Matrix products: default
## 
## locale:
## [1] LC_COLLATE=Chinese (Simplified)_China.936 
## [2] LC_CTYPE=Chinese (Simplified)_China.936   
## [3] LC_MONETARY=Chinese (Simplified)_China.936
## [4] LC_NUMERIC=C                              
## [5] LC_TIME=Chinese (Simplified)_China.936    
## 
## attached base packages:
## [1] parallel  stats4    stats     graphics  grDevices utils     datasets 
## [8] methods   base     
## 
## other attached packages:
##  [1] scater_1.25.1               scuttle_1.4.0              
##  [3] slingshot_2.2.0             TrajectoryUtils_1.2.0      
##  [5] princurve_2.1.6             gprofiler2_0.2.1           
##  [7] SpatialExperiment_1.4.0     SingleCellExperiment_1.16.0
##  [9] SummarizedExperiment_1.24.0 Biobase_2.54.0             
## [11] GenomicRanges_1.46.1        GenomeInfoDb_1.30.1        
## [13] IRanges_2.28.0              MatrixGenerics_1.6.0       
## [15] matrixStats_0.62.0          colorspace_2.0-3           
## [17] SC.MEB_1.1                  mclust_5.4.10              
## [19] irlba_2.3.5                 DR.SC_3.1                  
## [21] spatstat.geom_2.4-0         spatstat.data_3.0-0        
## [23] ggplot2_3.3.6               dplyr_1.0.9                
## [25] Matrix_1.4-0                sp_1.5-0                   
## [27] SeuratObject_4.1.0          Seurat_4.1.1               
## [29] hdf5r_1.3.5                 ff_4.0.7                   
## [31] bit_4.0.4                   S4Vectors_0.32.3           
## [33] BiocGenerics_0.40.0         rhdf5_2.38.0               
## [35] SRTpipeline_0.1.1          
## 
## loaded via a namespace (and not attached):
##   [1] scattermore_0.8           ggthemes_4.2.4           
##   [3] R.methodsS3_1.8.1         GiRaF_1.0.1              
##   [5] ragg_1.2.2                tidyr_1.2.0              
##   [7] bit64_4.0.5               knitr_1.37               
##   [9] DelayedArray_0.20.0       R.utils_2.11.0           
##  [11] data.table_1.14.2         rpart_4.1.16             
##  [13] RCurl_1.98-1.6            generics_0.1.2           
##  [15] ScaledMatrix_1.2.0        cowplot_1.1.1            
##  [17] RANN_2.6.1                future_1.26.1            
##  [19] httpuv_1.6.5              assertthat_0.2.1         
##  [21] viridis_0.6.2             xfun_0.29                
##  [23] jquerylib_0.1.4           evaluate_0.15            
##  [25] promises_1.2.0.1          fansi_1.0.3              
##  [27] igraph_1.3.5              DBI_1.1.2                
##  [29] htmlwidgets_1.5.4         purrr_0.3.4              
##  [31] ellipsis_0.3.2            RSpectra_0.16-1          
##  [33] ggpubr_0.4.0              backports_1.4.1          
##  [35] deldir_1.0-6              sparseMatrixStats_1.6.0  
##  [37] vctrs_0.4.1               ROCR_1.0-11              
##  [39] abind_1.4-5               cachem_1.0.6             
##  [41] withr_2.5.0               PRECAST_1.4              
##  [43] progressr_0.10.1          sctransform_0.3.3        
##  [45] goftest_1.2-3             cluster_2.1.2            
##  [47] lazyeval_0.2.2            crayon_1.5.1             
##  [49] edgeR_3.36.0              pkgconfig_2.0.3          
##  [51] labeling_0.4.2            nlme_3.1-155             
##  [53] vipor_0.4.5               rlang_1.0.2              
##  [55] globals_0.15.0            lifecycle_1.0.1          
##  [57] miniUI_0.1.1.1            rsvd_1.0.5               
##  [59] rprojroot_2.0.3           polyclip_1.10-0          
##  [61] lmtest_0.9-40             carData_3.0-5            
##  [63] Rhdf5lib_1.16.0           zoo_1.8-10               
##  [65] beeswarm_0.4.0            ggridges_0.5.3           
##  [67] rjson_0.2.21              png_0.1-7                
##  [69] viridisLite_0.4.0         bitops_1.0-7             
##  [71] R.oo_1.24.0               KernSmooth_2.23-20       
##  [73] rhdf5filters_1.6.0        DelayedMatrixStats_1.16.0
##  [75] stringr_1.4.0             parallelly_1.32.0        
##  [77] spatstat.random_2.2-0     rstatix_0.7.0            
##  [79] ggsignif_0.6.3            beachmat_2.10.0          
##  [81] scales_1.2.0              memoise_2.0.1            
##  [83] magrittr_2.0.3            plyr_1.8.7               
##  [85] ica_1.0-2                 zlibbioc_1.40.0          
##  [87] compiler_4.1.2            dqrng_0.3.0              
##  [89] RColorBrewer_1.1-3        fitdistrplus_1.1-8       
##  [91] cli_3.2.0                 XVector_0.34.0           
##  [93] listenv_0.8.0             patchwork_1.1.1          
##  [95] pbapply_1.5-0             formatR_1.11             
##  [97] MASS_7.3-55               mgcv_1.8-39              
##  [99] tidyselect_1.1.2          stringi_1.7.6            
## [101] textshaping_0.3.6         highr_0.9                
## [103] yaml_2.3.6                BiocSingular_1.10.0      
## [105] locfit_1.5-9.4            ggrepel_0.9.1            
## [107] grid_4.1.2                sass_0.4.1               
## [109] tools_4.1.2               future.apply_1.9.0       
## [111] rstudioapi_0.13           gridExtra_2.3            
## [113] farver_2.1.0              Rtsne_0.16               
## [115] DropletUtils_1.14.2       digest_0.6.29            
## [117] rgeos_0.5-9               shiny_1.7.1              
## [119] Rcpp_1.0.10               car_3.0-12               
## [121] broom_0.7.12              later_1.3.0              
## [123] RcppAnnoy_0.0.19          httr_1.4.3               
## [125] fs_1.5.2                  tensor_1.5               
## [127] reticulate_1.25           splines_4.1.2            
## [129] uwot_0.1.11               spatstat.utils_3.0-1     
## [131] pkgdown_2.0.6             plotly_4.10.0            
## [133] systemfonts_1.0.4         xtable_1.8-4             
## [135] jsonlite_1.8.0            R6_2.5.1                 
## [137] pillar_1.7.0              htmltools_0.5.2          
## [139] mime_0.12                 glue_1.6.2               
## [141] fastmap_1.1.0             BiocParallel_1.28.3      
## [143] BiocNeighbors_1.12.0      codetools_0.2-18         
## [145] utf8_1.2.2                lattice_0.20-45          
## [147] bslib_0.3.1               spatstat.sparse_2.1-1    
## [149] tibble_3.1.7              ggbeeswarm_0.6.0         
## [151] leiden_0.4.2              gtools_3.9.2.2           
## [153] magick_2.7.3              survival_3.2-13          
## [155] limma_3.50.1              CompQuadForm_1.4.3       
## [157] rmarkdown_2.11            desc_1.4.0               
## [159] munsell_0.5.0             GenomeInfoDbData_1.2.7   
## [161] HDF5Array_1.22.1          reshape2_1.4.4           
## [163] gtable_0.3.0              spatstat.core_2.4-4