Slide-seq version
data set
Here we analyze a dataset generated using Slide-seq v2 of the mouse hippocampus. This tutorial will follow much of the same structure as the Spatial Vignette of 10x Visium Data, but is tailored to provide a demonstration specific to Slide-seq data.
You can use our SeuratData package to easily access the data as shown below. After the dataset is installed, you can type ?ssHippo to see the commands used to create Seurat objects.
InstallData("ssHippo")
slide.seq <- LoadData("ssHippo")
Data preprocessing
The initial preprocessing steps for beads for gene expression data are similar to other spatial Seurat analyzes and typical scRNA-seq experiments. Here, we noticed that many beads had particularly low UMI counts, but chose to retain all detected beads for downstream analysis.
plot1 <- VlnPlot(slide.seq, features = "nCount_Spatial", pt.size = 0, log = TRUE) + NoLegend()
slide.seq$log_nCount_Spatial <- log(slide.seq$nCount_Spatial)
plot2 <- SpatialFeaturePlot(slide.seq, features = "log_nCount_Spatial") + theme(legend.position = "right")
wrap_plots(plot1, plot2)
We then used sctransform to normalize the data and perform standard scRNA-seq dimensionality reduction and clustering workflows.
slide.seq <- SCTransform(slide.seq, assay = "Spatial", ncells = 3000, verbose = FALSE)
slide.seq <- RunPCA(slide.seq)
slide.seq <- RunUMAP(slide.seq, dims = 1:30)
slide.seq <- FindNeighbors(slide.seq, dims = 1:30)
slide.seq <- FindClusters(slide.seq, resolution = 0.3, verbose = FALSE)
DimPlot()We can then visualize the results of the clustering in UMAP space (with) or in bead coordinate space using SpatialDimPlot().
plot1 <- DimPlot(slide.seq, reduction = "umap", label = TRUE)
plot2 <- SpatialDimPlot(slide.seq, stroke = 0)
plot1 + plot2
SpatialDimPlot(slide.seq, cells.highlight = CellsByIdentities(object = slide.seq, idents = c(1,
6, 13)), facet.highlight = TRUE)
Integrated with scRNA-seq reference
To facilitate cell type annotation of Slide-seq datasets, we are leveraging existing mouse single-cell RNA-seq hippocampal datasets produced by Saunders*, Macosko* et al. 2018. The data can be downloaded as processed Seurat objects and the raw count matrices are available on the DropViz website.
ref <- readRDS("../data/mouse_hippocampus_reference.rds")
ref <- UpdateSeuratObject(ref)
The original annotations of the paper are provided in the cell metadata of the Seurat object. These annotations are provided in several "resolutions", ranging from broad categories (ref class) to cell types (ref class) to cell types (refc l a ss ) to a subcluster within a cell type ( re f subcluster). For the purposes of this vignette, we will make a modification to the cell type annotation ( ref$celltype ), which we think strikes a good balance.
We will first run the Seurat label transfer method to predict the predominant cell type for each bead.
anchors <- FindTransferAnchors(reference = ref, query = slide.seq, normalization.method = "SCT",
npcs = 50)
predictions.assay <- TransferData(anchorset = anchors, refdata = ref$celltype, prediction.assay = TRUE,
weight.reduction = slide.seq[["pca"]], dims = 1:50)
slide.seq[["predictions"]] <- predictions.assay
We can then visualize the prediction scores for some of the main expected categories.
DefaultAssay(slide.seq) <- "predictions"
SpatialFeaturePlot(slide.seq, features = c("Dentate Principal cells", "CA3 Principal cells", "Entorhinal cortex",
"Endothelial tip", "Ependymal", "Oligodendrocyte"), alpha = c(0.1, 1))
slide.seq$predicted.id <- GetTransferPredictions(slide.seq)
Idents(slide.seq) <- "predicted.id"
SpatialDimPlot(slide.seq, cells.highlight = CellsByIdentities(object = slide.seq, idents = c("CA3 Principal cells",
"Dentate Principal cells", "Endothelial tip")), facet.highlight = TRUE)
Identification of spatially variable features
As mentioned in Visium vignette, we can identify spatially variable features in two general ways: differential expression tests between pre-annotated anatomical regions or statistics that measure the dependence of features on spatial location.
FindSpatiallyVariableFeatures() Here we demonstrate the latter by setting an implementation that provides Moran's I method = 'moransi'. Moran's I computes the overall spatial autocorrelation and gives a statistic (similar to the correlation coefficient) that measures the dependence of the feature on its spatial position. This allows us to rank features based on how much their expression varies across space. To facilitate quick estimation of this statistic, we implemented a basic binning strategy that draws a rectangular grid on a Slide-seq disk and averages the features and positions within each bin. The number of bins in the x and y directions is controlled by the x.cuts and y.cuts parameters respectively. Additionally, although not required, installing the optional Rfast2 package (install.packages('Rfast2')) will significantly reduce runtime through a more efficient implementation.
DefaultAssay(slide.seq) <- "SCT"
slide.seq <- FindSpatiallyVariableFeatures(slide.seq, assay = "SCT", slot = "scale.data", features = VariableFeatures(slide.seq)[1:1000],
selection.method = "moransi", x.cuts = 100, y.cuts = 100)
Now we visualize the expression of the first 6 features identified by Moran's I.
SpatialFeaturePlot(slide.seq, features = head(SpatiallyVariableFeatures(slide.seq, selection.method = "moransi"),
6), ncol = 3, alpha = c(0.1, 1), max.cutoff = "q95")
SpatialFeaturePlot(slide.seq, features = head(SpatiallyVariableFeatures(slide.seq, selection.method = "moransi"),
6), ncol = 3, alpha = c(0.1, 1), max.cutoff = "q95")
Spatial deconvolution using RCTD
While FindTransferAnchors can be used to integrate point-level data from spatial transcriptomic datasets, Seurat v5 also includes support for robust cell type decomposition, a method for deconvolving point-level data from spatial datasets when providing scRNA-seq references. calculation method. RCTD has been shown to accurately annotate spatial data from a variety of technologies, including SLIDE-seq, Visium, and the 10x Xenium in situ spatial platform.
To run RCTD, we first install spacexr from the GitHub package that implements RCTD.
devtools::install_github("dmcable/spacexr", build_vignettes = FALSE)
Extract count, cluster, and point information from Seurat queries and reference objects to construct ReferenceRCT objects used by DSpatialRNA for annotation.
library(spacexr)
# set up reference
ref <- readRDS("../data/mouse_hippocampus_reference.rds")
ref <- UpdateSeuratObject(ref)
Idents(ref) <- "celltype"
# extract information to pass to the RCTD Reference function
counts <- ref[["RNA"]]$counts
cluster <- as.factor(ref$celltype)
names(cluster) <- colnames(ref)
nUMI <- ref$nCount_RNA
names(nUMI) <- colnames(ref)
reference <- Reference(counts, cluster, nUMI)
# set up query with the RCTD function SpatialRNA
slide.seq <- SeuratData::LoadData("ssHippo")
counts <- slide.seq[["Spatial"]]$counts
coords <- GetTissueCoordinates(slide.seq)
colnames(coords) <- c("x", "y")
coords[is.na(colnames(coords))] <- NULL
query <- SpatialRNA(coords, counts, colSums(counts))
Using the referenceandquery object, we annotate the dataset and add cell type labels to the query Seurat object. RCTD parallelizes well, so multiple cores can be specified for faster performance.
RCTD <- create.RCTD(query, reference, max_cores = 8)
RCTD <- run.RCTD(RCTD, doublet_mode = "doublet")
slide.seq <- AddMetaData(slide.seq, metadata = RCTD@results$results_df)
Next, draw the RCTD annotation. Because we are running RCTD in doublet mode, the algorithm assigns a first_type sum to each barcode or point. second_type
p1 <- SpatialDimPlot(slide.seq, group.by = "first_type")
p2 <- SpatialDimPlot(slide.seq, group.by = "second_type")
p1 | p2
keep
write.csv(x = t(as.data.frame(all_times)), file = "../output/timings/spatial_vignette_times.csv")