vignettes/single_Embryo_SC_tutorial.Rmd
single_Embryo_SC_tutorial.Rmd
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:
First, we load SRTpipeline
.
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")
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):
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))
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):
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):
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.
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
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
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')
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