vignettes/cerebroApp_workflow_Seurat.Rmd
cerebroApp_workflow_Seurat.Rmd
The cerebroApp
package has two main purposes: (1) Give access to the Cerebro user interface, and (2) provide a set of functions to pre-process and export scRNA-seq data for visualization in Cerebro. The Cerebro user interface was built using the Shiny framework and designed to provide numerous perspectives on a given data set that should facilitate data interpretation. This vignette will give you an example of how scRNA-seq data can be processed using the Seurat toolkit and then exported for visualization in Cerebro.
Ket features that can be accessed through Cerebro:
Before starting the workflow, we need to install cerebroApp
, as well as the Seurat
, monocle
and SingleR
packages, which are not installed as dependencies of cerebroApp because they are only necessary if you want/need to pre-process your scRNA-seq data. If you just want to launch the Cerebro user interface, e.g. because you already have the pre-processed data, you don’t need those packages.
if ( 'BiocManager' %in% installed.packages() == FALSE ) install.packages('BiocManager')
library(BiocManager)
if ( 'cerebroApp' %in% installed.packages() == FALSE ) install('romanhaa/cerebroApp')
if ( 'Seurat' %in% installed.packages() == FALSE ) install('Seurat')
if ( 'SingleR' %in% installed.packages() == FALSE ) install('SingleR')
#>
#> The downloaded binary packages are in
#> /var/folders/7z/m3l07m8s6455y1mnykf307_c0000gn/T//RtmpfbO0gJ/downloaded_packages
if ( 'monocle' %in% installed.packages() == FALSE ) install('monocle')
#>
#> The downloaded binary packages are in
#> /var/folders/7z/m3l07m8s6455y1mnykf307_c0000gn/T//RtmpfbO0gJ/downloaded_packages
Apart from the packages we just installed, we will also load the dplyr package and set a seed to make our analysis reproducible.
In this example workflow, we will load a small transcript count table from the Seurat package containing 80 cells and 230 genes. If you want to try the workflow with a real data set, you can find some transcript count matrices on the Cerebro GitHub repo.
pbmc <- read.table(
file = system.file('extdata', 'pbmc_raw.txt', package = 'Seurat'),
as.is = TRUE
)
Now, we create a Seurat
object and filter out cells with less than 50
transcripts or fewer than 10
expressed genes. Those cut-offs are only reasonable for this example data set and will likely need to be adjusted in a real data set. Then, we follow the standard Seurat workflow, including…
seurat <- CreateSeuratObject(
project = 'pbmc',
counts = pbmc,
min.cells = 5
)
seurat <- subset(seurat, subset = nCount_RNA >= 50 & nFeature_RNA >= 10)
seurat <- NormalizeData(seurat, verbose = FALSE)
seurat <- FindVariableFeatures(seurat, verbose = FALSE)
seurat <- ScaleData(seurat, vars.to.regress = 'nCount_RNA', verbose = FALSE)
seurat <- RunPCA(seurat, features = seurat@assays$RNA@var.features, verbose = FALSE)
Then, we identify clusters with a relatively low resolution, again, because of the small size of this data set.
seurat <- FindNeighbors(seurat)
#> Computing nearest neighbor graph
#> Computing SNN
seurat <- FindClusters(seurat, resolution = 0.5)
#> Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
#>
#> Number of nodes: 78
#> Number of edges: 2373
#>
#> Running Louvain algorithm...
#> Maximum modularity in 10 random starts: 0.5759
#> Number of communities: 2
#> Elapsed time: 0 seconds
seurat@meta.data$RNA_snn_res.0.5 <- NULL
We could also perform cell cycle analysis using the CellCycleScoring()
built into Seurat. However, too few of the cell cycle genes are present in this example data set so we will skip it here. The code below should work with a real data set.
seurat <- CellCycleScoring(
seurat,
g2m.features = cc.genes$g2m.genes,
s.features = cc.genes$s.genes
)
seurat@misc$gene_lists$G2M_phase_genes <- cc.genes$g2m.genes
seurat@misc$gene_lists$S_phase_genes <- cc.genes$s.genes
Next, we use the UMAP technique to generate two- and three-dimensional projections.
This example data set consists of a single sample so we just add that name to the meta data. Moreover, in order to be able to understand how we did the analysis later, we add some meta data to the misc
slot of our Seurat
object, e.g. an experiment name and the species. The info we store there will later be collected for visualization in Cerebro.
seurat@meta.data$sample <- factor('pbmc', levels = 'pbmc')
seurat@misc$experiment <- list(
experiment_name = 'pbmc',
organism = 'hg',
date_of_analysis = Sys.Date()
)
seurat@misc$parameters <- list(
gene_nomenclature = 'gene_name',
discard_genes_expressed_in_fewer_cells_than = 10,
keep_mitochondrial_genes = TRUE,
variables_to_regress_out = 'nUMI',
number_PCs = 30,
cluster_resolution = 0.5
)
seurat@misc$parameters$filtering <- list(
UMI_min = 50,
UMI_max = Inf,
genes_min = 10,
genes_max = Inf
)
seurat@misc$technical_info$cerebroApp_version <- utils::packageVersion('cerebroApp')
seurat@misc$technical_info$Seurat <- utils::packageVersion('Seurat')
seurat@misc$technical_info <- list(
'R' = capture.output(devtools::session_info())
)
#> Registered S3 method overwritten by 'cli':
#> method from
#> print.boxx spatstat
Using the SingleR
package, we can get a suggestion of cell type for each cell. Apart from the suggested cell type, we also extract the score that might help us to understand how confident the assignment was.
singler_ref <- BlueprintEncodeData()
#> Warning: 'BlueprintEncodeData' is deprecated.
#> Use 'celldex::BlueprintEncodeData' instead.
#> See help("Deprecated")
#> using temporary cache /var/folders/7z/m3l07m8s6455y1mnykf307_c0000gn/T//RtmpfbO0gJ/BiocFileCache
#> snapshotDate(): 2020-10-27
#> see ?celldex and browseVignettes('celldex') for documentation
#> downloading 1 resources
#> retrieving 1 resource
#> loading from cache
#> see ?celldex and browseVignettes('celldex') for documentation
#> downloading 1 resources
#> retrieving 1 resource
#> loading from cache
singler_results_blueprintencode_main <- SingleR(
test = GetAssayData(seurat, assay = 'RNA', slot = 'data'),
ref = singler_ref,
labels = singler_ref@colData@listData$label.main
)
seurat@meta.data$cell_type_singler_blueprintencode_main <- singler_results_blueprintencode_main@listData$labels
singler_scores <- singler_results_blueprintencode_main@listData$scores %>%
as_tibble() %>%
dplyr::mutate(assigned_score = NA)
for ( i in seq_len(nrow(singler_scores)) ) {
singler_scores$assigned_score[i] <- singler_scores[[singler_results_blueprintencode_main@listData$labels[i]]][i]
}
seurat@meta.data$cell_type_singler_blueprintencode_main_score <- singler_scores$assigned_score
Here, we calculate phylogenetic trees that represent the similarity between different subgroups, in this case clusters and cell types. To do so, we need to set the identity in the Seurat object to the current grouping of interest, calculate the tree, and then copy the result to the misc
slot in the Seurat object so it can be exported later.
Idents(seurat) <- "seurat_clusters"
seurat <- BuildClusterTree(
seurat,
dims = 1:30,
reorder = FALSE,
reorder.numeric = FALSE
)
seurat@misc$trees$seurat_clusters <- seurat@tools$BuildClusterTree
Idents(seurat) <- "cell_type_singler_blueprintencode_main"
seurat <- BuildClusterTree(
seurat,
dims = 1:30,
reorder = FALSE,
reorder.numeric = FALSE
)
seurat@misc$trees$cell_type_singler_blueprintencode_main <- seurat@tools$BuildClusterTree
Now we use a set of cerebroApp function to get more information about the data set and the contained clusters and cell types.
First, for every cell we calculate the percentage of mitochondrial and ribosomal transcripts of all transcripts using the addPercentMtRibo()
function.
seurat <- addPercentMtRibo(
seurat,
organism = 'hg',
gene_nomenclature = 'name'
)
#> [17:55:31] No mitochondrial genes found in data set.
#> [17:55:31] Calculate percentage of 1 ribosomal transcript(s) present in the data set...
Another interesting perspective is to look at the 100 most expressed genes across all cells and for every cluster and cell type. This can help in understanding the transcriptional activity of a given cell population.
seurat <- getMostExpressedGenes(
seurat,
assay = 'RNA',
groups = c('sample','seurat_clusters','cell_type_singler_blueprintencode_main')
)
#> [17:55:31] Group `sample` contains only one subgroup. Will calculate most expressed genes across all cells of this group...
#> [17:55:31] Get most expressed genes for 2 groups in `seurat_clusters`...
#> [17:55:31] Get most expressed genes for 8 groups in `cell_type_singler_blueprintencode_main`...
Marker genes are genes which are particularly strongly or weakly expressed in a given cell population, e.g. a cluster. This information can help to distinguish the role of different cell groups in the data set. We can identify marker genes using the getMarkerGenes()
function which internally uses the Seurat::FindAllMarkers()
function but also stores the results in the Seurat object under the misc
slot.
seurat <- getMarkerGenes(
seurat,
assay = 'RNA',
organism = 'hg',
groups = c('seurat_clusters','cell_type_singler_blueprintencode_main'),
name = 'cerebro_seurat',
only_pos = TRUE
)
#> Ensembl site unresponsive, trying uswest mirror
#> [17:56:26] Get marker genes for 2 groups in `seurat_clusters`...
#> Calculating cluster 0
#> Calculating cluster 1
#> [17:56:26] Get marker genes for 8 groups in `cell_type_singler_blueprintencode_main`...
#> Calculating cluster CD4+ T-cells
#> Calculating cluster CD8+ T-cells
#> Calculating cluster B-cells
#> Calculating cluster Monocytes
#> Calculating cluster NK cells
#> Calculating cluster Erythrocytes
#> Calculating cluster Endothelial cells
#> Calculating cluster Fibroblasts
Using the previously identified marker genes, we can perform a pathway enrichmeny analysis using the getEnrichedPathways()
function. The function will internally use the Enrichr API and store the results in the Seurat object under the misc
slot. All we have to do is provide the name that we specified in getMarkerGenes()
.
seurat <- getEnrichedPathways(
seurat,
marker_genes_input = 'cerebro_seurat',
adj_p_cutoff = 0.01,
max_terms = 100
)
#> [17:56:26] Found 2 groups: seurat_clusters, cell_type_singler_blueprintencode_main
#> [17:56:26] Get enriched pathways for group `seurat_clusters`...
#> [17:56:30] 47 pathways passed the thresholds across all group levels and databases.
#> [17:56:30] Get enriched pathways for group `cell_type_singler_blueprintencode_main`...
#> [17:56:46] 311 pathways passed the thresholds across all group levels and databases.
On top of querying the databases of the Enrichr service, one can also perform gene set enrichment analysis on gene sets provided as a .gmt
file, e.g. from the MSigDB. The performGeneSetEnrichmentAnalysis()
function uses the GSVA method in combination with additional statistics as published by Diaz-Mejia et. al..
example_gene_set <- system.file("extdata/example_gene_set.gmt", package = "cerebroApp")
seurat <- performGeneSetEnrichmentAnalysis(
seurat,
assay = 'RNA',
GMT_file = example_gene_set,
groups = c('seurat_clusters','cell_type_singler_blueprintencode_main')
)
Then, we perform trajectory analysis with Monocle v2 using the previously identified highly variable genes. We extract the trajectory from the generated Monocle object with the extractMonocleTrajectory()
function of cerebroApp and attach it to our Seurat object.
monocle <- newCellDataSet(
seurat@assays$RNA@counts,
phenoData = new('AnnotatedDataFrame', data = seurat@meta.data),
featureData = new('AnnotatedDataFrame', data = data.frame(
gene_short_name = rownames(seurat@assays$RNA@counts),
row.names = rownames(seurat@assays$RNA@counts))
)
)
monocle <- estimateSizeFactors(monocle)
monocle <- setOrderingFilter(monocle, seurat@assays$RNA@var.features)
monocle <- reduceDimension(monocle, max_components = 2, method = 'DDRTree')
monocle <- orderCells(monocle)
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
#> Warning in if (class(projection) != "matrix") projection <- as.matrix(projection): the condition has
#> length > 1 and only the first element will be used
seurat <- extractMonocleTrajectory(monocle, seurat, 'highly_variable_genes')
Finally, we use the exportFromSeurat()
function of cerebroApp to export our Seurat object to a .crb
file which can be loaded into Cerebro.
exportFromSeurat(
seurat,
assay = 'RNA',
slot = 'data',
file = paste0('cerebro_pbmc_seurat_', Sys.Date(), '.crb'),
experiment_name = 'pbmc',
organism = 'hg',
groups = c('sample','seurat_clusters','cell_type_singler_blueprintencode_main'),
nUMI = 'nCount_RNA',
nGene = 'nFeature_RNA',
add_all_meta_data = TRUE,
verbose = FALSE
)
#> [17:56:48] Start collecting data...
#> [17:56:48] Overview of Cerebro object:
#> class: Cerebro_v1.3
#> cerebroApp version: 1.3.1
#> experiment name: pbmc
#> organism: hg
#> date of analysis: 2021-03-12
#> date of export: 2021-03-12
#> number of cells: 78
#> number of genes: 220
#> grouping variables (3): sample, seurat_clusters, cell_type_singler_blueprintencode_main
#> cell cycle variables (0):
#> projections (2): UMAP, UMAP_3D
#> trees (2): seurat_clusters, cell_type_singler_blueprintencode_main
#> most expressed genes: sample, seurat_clusters, cell_type_singler_blueprintencode_main
#> marker genes:
#> - cerebro_seurat (2): seurat_clusters, cell_type_singler_blueprintencode_main
#> enriched pathways:
#> - cerebro_seurat_enrichr (2): seurat_clusters, cell_type_singler_blueprintencode_main
#> trajectories:
#> - monocle2 (1): highly_variable_genes
#> extra material:
#> [17:56:48] Saving Cerebro object to: cerebro_pbmc_seurat_2021-03-12.crb
#> [17:56:48] Done!
The Cerebro use interface can be launched using the launchCerebro()
function.
sessionInfo()
#> R version 4.0.3 (2020-10-10)
#> Platform: x86_64-apple-darwin17.0 (64-bit)
#> Running under: macOS Big Sur 10.16
#>
#> Matrix products: default
#> BLAS: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
#>
#> locale:
#> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
#>
#> attached base packages:
#> [1] splines parallel stats4 stats graphics grDevices utils datasets methods
#> [10] base
#>
#> other attached packages:
#> [1] celldex_1.0.0 cerebroApp_1.3.1 monocle_2.18.0
#> [4] DDRTree_0.1.5 irlba_2.3.3 VGAM_1.1-5
#> [7] ggplot2_3.3.2 Matrix_1.3-0 SingleR_1.4.1
#> [10] SummarizedExperiment_1.20.0 Biobase_2.50.0 GenomicRanges_1.42.0
#> [13] GenomeInfoDb_1.26.2 IRanges_2.24.1 S4Vectors_0.28.1
#> [16] BiocGenerics_0.36.0 MatrixGenerics_1.2.0 matrixStats_0.57.0
#> [19] Seurat_3.2.3 dplyr_1.0.2 BiocManager_1.30.10
#>
#> loaded via a namespace (and not attached):
#> [1] rappdirs_0.3.1 scattermore_0.7 ragg_1.1.0
#> [4] tidyr_1.1.2 bit64_4.0.5 knitr_1.30
#> [7] DelayedArray_0.16.1 data.table_1.13.4 rpart_4.1-15
#> [10] RCurl_1.98-1.2 generics_0.1.0 callr_3.5.1
#> [13] cowplot_1.1.1 usethis_2.0.0 RSQLite_2.2.1
#> [16] RANN_2.6.1 combinat_0.0-8 proxy_0.4-25
#> [19] future_1.21.0 bit_4.0.4 spatstat.data_2.0-0
#> [22] xml2_1.3.2 httpuv_1.5.4 assertthat_0.2.1
#> [25] viridis_0.5.1 xfun_0.19 hms_0.5.3
#> [28] evaluate_0.14 promises_1.1.1 fansi_0.4.1
#> [31] progress_1.2.2 dbplyr_2.0.0 igraph_1.2.6
#> [34] DBI_1.1.0 htmlwidgets_1.5.3 sparsesvd_0.2
#> [37] purrr_0.3.4 ellipsis_0.3.1 RSpectra_0.16-0
#> [40] annotate_1.68.0 biomaRt_2.46.0 deldir_0.2-10
#> [43] sparseMatrixStats_1.2.1 vctrs_0.3.6 remotes_2.2.0
#> [46] ROCR_1.0-11 abind_1.4-5 withr_2.3.0
#> [49] sctransform_0.3.2 prettyunits_1.1.1 goftest_1.2-2
#> [52] cluster_2.1.0 ExperimentHub_1.16.0 ape_5.4-1
#> [55] lazyeval_0.2.2 crayon_1.3.4 pkgconfig_2.0.3
#> [58] slam_0.1-48 nlme_3.1-151 pkgload_1.1.0
#> [61] devtools_2.3.2 rlang_0.4.9 globals_0.14.0
#> [64] lifecycle_0.2.0 miniUI_0.1.1.1 colourpicker_1.1.0
#> [67] BiocFileCache_1.14.0 rsvd_1.0.3 AnnotationHub_2.22.0
#> [70] rprojroot_2.0.2 polyclip_1.10-0 GSVA_1.38.0
#> [73] lmtest_0.9-38 shinyFiles_0.9.0 graph_1.68.0
#> [76] zoo_1.8-8 ggridges_0.5.3 processx_3.4.5
#> [79] pheatmap_1.0.12 png_0.1-7 viridisLite_0.3.0
#> [82] bitops_1.0-6 shinydashboard_0.7.1 KernSmooth_2.23-18
#> [85] blob_1.2.1 DelayedMatrixStats_1.12.3 stringr_1.4.0
#> [88] qvalue_2.22.0 parallelly_1.22.0 readr_1.4.0
#> [91] beachmat_2.6.4 scales_1.1.1 memoise_1.1.0
#> [94] GSEABase_1.52.1 magrittr_2.0.1 plyr_1.8.6
#> [97] ica_1.0-2 zlibbioc_1.36.0 compiler_4.0.3
#> [100] HSMMSingleCell_1.10.0 RColorBrewer_1.1-2 fitdistrplus_1.1-3
#> [103] cli_2.2.0 XVector_0.30.0 listenv_0.8.0
#> [106] patchwork_1.1.1 pbapply_1.4-3 ps_1.5.0
#> [109] MASS_7.3-53 mgcv_1.8-33 tidyselect_1.1.0
#> [112] stringi_1.5.3 textshaping_0.3.0 densityClust_0.3
#> [115] yaml_2.2.1 BiocSingular_1.6.0 askpass_1.1
#> [118] ggrepel_0.9.1 grid_4.0.3 tools_4.0.3
#> [121] future.apply_1.6.0 gridExtra_2.3 Rtsne_0.15
#> [124] digest_0.6.27 FNN_1.1.3 shiny_1.5.0
#> [127] qlcMatrix_0.9.7 Rcpp_1.0.5 BiocVersion_3.12.0
#> [130] later_1.1.0.1 RcppAnnoy_0.0.18 shinyWidgets_0.5.4
#> [133] httr_1.4.2 AnnotationDbi_1.52.0 colorspace_2.0-0
#> [136] XML_3.99-0.5 fs_1.5.0 tensor_1.5
#> [139] reticulate_1.18 uwot_0.1.10 spatstat.utils_2.0-0
#> [142] pkgdown_1.6.1 plotly_4.9.2.2 sessioninfo_1.1.1
#> [145] systemfonts_1.0.1 xtable_1.8-4 jsonlite_1.7.2
#> [148] spatstat_1.64-1 testthat_3.0.1 R6_2.5.0
#> [151] pillar_1.4.7 htmltools_0.5.1.1 mime_0.9
#> [154] glue_1.4.2 fastmap_1.0.1 DT_0.16
#> [157] BiocParallel_1.24.1 BiocNeighbors_1.8.2 interactiveDisplayBase_1.28.0
#> [160] codetools_0.2-18 pkgbuild_1.2.0 lattice_0.20-41
#> [163] tibble_3.0.4 curl_4.3 leiden_0.3.7
#> [166] shinyjs_2.0.0 openssl_1.4.3 survival_3.2-7
#> [169] limma_3.46.0 rmarkdown_2.6 docopt_0.7.1
#> [172] desc_1.2.0 fastICA_1.2-2 munsell_0.5.0
#> [175] GenomeInfoDbData_1.2.4 reshape2_1.4.4 gtable_0.3.0
#> [178] shinycssloaders_1.0.0 msigdbr_7.2.1