思考題:
+ 如何將空間數據與表達數據關聯在一起?
+ 有了空間轉錄組數據,如何與單細胞轉錄組數據聯用?
+ 做了多層切片如何展示真實的三維空間的轉錄本信息?
隨著轉錄組技術的發展,空間轉錄組已經正式走向商業化時代,作為單細胞數據分析的工具箱的Seurat與時俱進,也相應地開發了空間轉錄組分析的一套函數,讓我們跟隨卑微小王看看Seurat官網教程吧。
本教程演示如何使用Seurat v3.2分析空間解析的RNA-seq數據。雖然分析流程類似于Seurat的單細胞RNA-seq分析流程,但我們引入了交互可視化工具,特別強調了空間和分子信息的集成。本教程將介紹以下任務,我們相信這些任務在許多空間分析中都很常見:
- 歸一化
- 降維與聚類
- 檢測spatially-variable特性
- 交互式可視化
- 與單細胞RNA-seq數據集成
- 處理多個片(multiple slices)
我們分析了使用來自10x Genomics 的Visium技術(Visium technology)生成的數據集。我們將在不久的將來擴展Seurat以處理其他數據類型,包括SLIDE-Seq、STARmap和MERFISH。
安裝
devtools::install_github("satijalab/seurat", ref = "spatial")
這種方法,只能只能好運。直接下載安裝包,本地安裝。在遇到問題的時候,假裝這是你寫的R包參考《R包開發》這本書,嘗試本地重構:
devtools::load_all('H:\\singlecell\\Seurat\\seurat-master\\seurat')
但是,一般用不到這么復雜,下載安裝包,本地安裝基本就可以了:
[https://codeload.github.com/satijalab/seurat/legacy.tar.gz/spatial](https://codeload.github.com/satijalab/seurat/legacy.tar.gz/spatial) # 下載地址
install.packages("H:/singlecell/Seurat/satijalab-seurat-v3.1.1-302-g1cb8a3d.tar.gz", repos = NULL, type = "source")
注意,別和之前的包安裝沖突啦,這個3.2還處在開發中(2019-12-19)
library(Seurat)
library(SeuratData)
library(ggplot2)
library(cowplot)
library(dplyr)
數據集
和以往一樣,seurat為了使其教程的可用,會提供測試的已發表的數據集。在這里,我們將使用最新發布的使用Visium v1化學生成的sagital小鼠大腦切片數據集。有兩個連續的前段和兩個(匹配的)連續的后段。
您可以在這里here下載數據,并使用Load10X_Spatial函數將其加載到Seurat。這將讀取spaceranger管道的輸出,并返回Seurat對象,該對象包含spot級別的表達數據以及相關的組織切片圖像。您還可以使用我們的SeuratData包方便地訪問數據,如下所示。安裝數據集之后,可以鍵入?stxBrain以了解更多信息。
InstallData("stxBrain")
每次我在國內直接用這種方法下載數據集都沒有成功,如上,下載安裝包,本地安裝:
install.packages("H:/singlecell/Seurat/stxBrain.SeuratData_0.1.1.tar.gz", repos = NULL, type = "source")
brain <- LoadData("stxBrain", type = "anterior1")
當然,我們不推薦這種讀取數據的方法,畢竟沒有人把我們的數據也打包成一個R包的樣子,我們拿到的是10 X Space Ranger的輸出結果:
├── analysis
│?? ├── clustering
│?? ├── diffexp
│?? ├── pca
│?? ├── tsne
│?? └── umap
├── cloupe.cloupe
├── filtered_feature_bc_matrix
│?? ├── barcodes.tsv.gz
│?? ├── features.tsv.gz
│?? └── matrix.mtx.gz
├── filtered_feature_bc_matrix.h5
├── metrics_summary.csv
├── molecule_info.h5
├── possorted_genome_bam.bam
├── possorted_genome_bam.bam.bai
├── raw_feature_bc_matrix
│?? ├── barcodes.tsv.gz
│?? ├── features.tsv.gz
│?? └── matrix.mtx.gz
├── raw_feature_bc_matrix.h5
├── spatial # 空間信息全在這 :這些文件是用戶提供的原始全分辨率brightfield圖像的下采樣版本。
下采樣是通過box濾波實現的,它對全分辨率圖像中像素塊的RGB值進行平均,得到下采樣圖像中一個像素點的RGB值。
│?? ├── aligned_fiducials.jpg 這個圖像的尺寸是tissue_hires_image.png。由基準對齊算法發現的基準點用紅色高亮顯示。此文件對于驗證基準對齊是否成功非常有用。
│?? ├── detected_tissue_image.jpg
│?? ├── scalefactors_json.json
│?? ├── tissue_hires_image.png 圖像的最大尺寸為2,000像素
│?? ├── tissue_lowres_image.png 圖像的最大尺寸為600像素。
│?? └── tissue_positions_list.csv
└── web_summary.html
其實只要 Space Ranger的輸出結果 filtered_feature_bc_matrix.h5文件和一個spatial文件夾就可以了,一如?stxBrain中給出的示例:
setwd("H:\\singlecell\\spaceranger\\V1_Mouse_Brain_Sagittal_Anterio/")
# Load the expression data
expr.url <- 'H:\\singlecell\\spaceranger\\V1_Mouse_Brain_Sagittal_Anterio/V1_Mouse_Brain_Sagittal_Anterior_filtered_feature_bc_matrix.h5'
expr.data <- Seurat::Read10X_h5(filename = expr.url )
anterior1 <- Seurat::CreateSeuratObject(counts = expr.data, project = 'anterior1', assay = 'Spatial')
anterior1$slice <- 1
anterior1$region <- 'anterior'
# Load the image data
img.url <- 'H:\\singlecell\\spaceranger\\V1_Mouse_Brain_Sagittal_Anterio/V1_Mouse_Brain_Sagittal_Anterior_spatial.tar.gz'
untar(tarfile = img.url)
img <- Seurat::Read10X_Image(image.dir = 'H:\\singlecell\\spaceranger\\V1_Mouse_Brain_Sagittal_Anterio/spatial')
Seurat::DefaultAssay(object = img) <- 'Spatial'
img <- img[colnames(x = anterior1)]
anterior1[['image']] <- img
anterior1
An object of class Seurat
31053 features across 2696 samples within 1 assay
Active assay: Spatial (31053 features)
}
如果這兩個文件在同一個文件下的話,也可以這樣讀入:
list.files("H:\\singlecell\\spaceranger\\V1_Mouse_Brain_Sagittal_Anterio") # 注意命名要正確
# [1] "filtered_feature_bc_matrix.h5" "spatial"
# [3] "V1_Mouse_Brain_Sagittal_Anterior_filtered_feature_bc_matrix.h5" "V1_Mouse_Brain_Sagittal_Anterior_spatial.tar.gz"
brain<-Seurat::Load10X_Spatial("H:\\singlecell\\spaceranger\\V1_Mouse_Brain_Sagittal_Anterio")
?Load10X_Spatial
brain
An object of class Seurat
31053 features across 2696 samples within 1 assay
Active assay: Spatial (31053 features)
空間數據如何存儲在Seurat中?
來自10x的visium數據包括以下數據類型:
- 通過基因表達矩陣得到一個點(spot )
- 組織切片圖像(采集數據時H&E染色)
- 用于顯示的原始高分辨率圖像與低分辨率圖像之間的比例因子。
在Seurat對象中,spot by基因表達矩陣與典型的“RNA”分析類似,但包含spot水平,而不是單細胞水平的數據。圖像本身存儲在Seurat對象中的一個images 槽(slot )中。圖像槽還存儲必要的信息,以將斑點與其在組織圖像上的物理位置相關聯。
數據預處理
在spot中基因表達數據進行初始的預處理步驟與典型的scRNA-seq相似。我們首先需要對數據進行規范化,以考慮數據點之間測序深度的差異。我們注意到,對于空間數據集來說,分子數/點的差異可能是巨大的,特別是在整個組織的細胞密度存在差異的情況下。我們在這里看到大量的異質性,這需要有效的標準化。
熟悉的函數名~
plot1 <- VlnPlot(brain, features = "nCount_Spatial", pt.size = 0.1) + NoLegend()
plot2 <- SpatialFeaturePlot(brain, features = "nCount_Spatial") + theme(legend.position = "right")
plot_grid(plot1, plot2)
這些圖表明,分子計數(molecular counts)在點間的差異不僅是技術性的,而且還依賴于組織解剖。例如,組織中神經元消耗的區域(如皮層白質),可再生地顯示出較低的分子計數。因此,標準方法(如LogNormalize函數)可能會有問題,因為它會強制每個數據點在標準化之后具有相同的底層“大小”。
作為一種替代方法,我們推薦使用sctransform (Hafemeister和Satija,已出版),它構建了基因表達的正則化負二項模型,以便在保留生物差異的同時考慮技術因素。有關sctransform的更多信息,請參見 here的預印和here的Seurat教程。sctransform將數據歸一化,檢測高方差特征,并將數據存儲在SCT分析中。
brain <- SCTransform(brain, assay = "Spatial", return.only.var.genes = FALSE, verbose = FALSE)
sct 與log-歸一化相比,結果如何?
為了探究規范化方法的不同,我們研究了sctransform和log規范化結果如何與UMIs的數量相關。為了進行比較,我們首先重新運行sctransform來存儲所有基因的值(這將會比較慢),并通過NormalizeData運行一個log規范化過程。
# rerun normalization to store sctransform residuals for all genes
brain <- SCTransform(brain, assay = "Spatial", return.only.var.genes = FALSE, verbose = FALSE)
# also run standard log normalization for comparison
brain <- NormalizeData(brain, verbose = FALSE, assay = "Spatial")
# Computes the correlation of the log normalized data and sctransform residuals with the number
# of UMIs
brain <- GroupCorrelation(brain, group.assay = "Spatial", assay = "Spatial", slot = "data", do.plot = FALSE)
brain <- GroupCorrelation(brain, group.assay = "Spatial", assay = "SCT", slot = "scale.data", do.plot = FALSE)
p1 <- GroupCorrelationPlot(brain, assay = "Spatial", cor = "nCount_Spatial_cor") + ggtitle("Log Normalization") +
theme(plot.title = element_text(hjust = 0.5))
p2 <- GroupCorrelationPlot(brain, assay = "SCT", cor = "nCount_Spatial_cor") + ggtitle("SCTransform Normalization") +
theme(plot.title = element_text(hjust = 0.5))
plot_grid(p1, p2)
對于上面的箱形圖,我們計算每個特征(基因)與UMIs數量(這里的nCount_Spatial變量)的相關性。然后,我們根據基因的平均表達將它們分組,并生成這些相關性的箱形圖。您可以看到,log-normalization未能充分規范化前三組的基因,這表明技術因素影響高表達基因的規范化表達估計值。相反,sctransform規范化降低了這種效果。差別真的很大么?讀者諸君自行判斷。
基因表達可視化
在Seurat v3.2中,我們加入了新的功能來探索和與空間數據固有的可視化特性。Seurat的SpatialFeaturePlot功能擴展了FeaturePlot,可以將表達數據覆蓋在組織組織上。例如,在這組小鼠大腦數據中,Hpca基因是一個強的海馬marker ,Ttr是一個脈絡叢marker 。
SpatialFeaturePlot(brain, features = c("Hpca", "Ttr"))
Seurat的默認參數強調分子數據的可視化。然而,你也可以調整斑點的大小(和它們的透明度)來改善組織學圖像的可視化,通過改變以下參數:
- pt.size。因素-這將比例大小的斑點。默認為1.6
- alpha -最小和最大透明度。默認是c(1,1)
- 嘗試設置為alpha c(0.1, 1),以降低表達式較低的點的透明度
降維、聚類和可視化
然后,我們可以使用與scRNA-seq分析相同的工作流,對RNA表達數據進行降維和聚類。我們可以在UMAP空間(使用DimPlot)或使用SpatialDimPlot將分群的結果顯示在圖像上。
brain <- RunPCA(brain, assay = "SCT", verbose = FALSE)
brain <- FindNeighbors(brain, reduction = "pca", dims = 1:30)
brain <- FindClusters(brain, verbose = FALSE)
brain <- RunUMAP(brain, reduction = "pca", dims = 1:30)
Warning: The default method for RunUMAP has changed from calling Python UMAP via reticulate to the R-native UWOT using the cosine metric
To use Python UMAP via reticulate, set umap.method to 'umap-learn' and metric to 'correlation'
This message will be shown once per session
22:08:28 UMAP embedding parameters a = 0.9922 b = 1.112
22:08:28 Read 2696 rows and found 30 numeric columns
22:08:28 Using Annoy for neighbor search, n_neighbors = 30
22:08:28 Building Annoy index with metric = cosine, n_trees = 50
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
22:08:30 Writing NN index file to temp file C:\Users\ADMINI~1\AppData\Local\Temp\Rtmp08OC2k\file3ddc1e802bb6
22:08:30 Searching Annoy index using 1 thread, search_k = 3000
22:08:31 Annoy recall = 100%
22:08:32 Commencing smooth kNN distance calibration using 1 thread
22:08:33 Initializing from normalized Laplacian + noise
22:08:33 Commencing optimization for 500 epochs, with 106630 positive edges
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
22:08:50 Optimization finished
p1 <- DimPlot(brain, reduction = "umap", label = TRUE)
p2 <- SpatialDimPlot(brain, label = TRUE, label.size = 3)
plot_grid(p1, p2)
因為有許多顏色,所以可視化哪個體素屬于哪個簇是很有挑戰性的。我們有一些策略來幫助解決這個問題。通過設置label參數,可以在每個集群的中間位置放置一個彩色框(參見上面的圖)以及do.hover。SpatialDimPlot的懸停參數允許交互式查看當前的spot標識。
# move your mouse
SpatialDimPlot(brain, do.hover = TRUE)
Warning messages:
1: In if (is.na(col)) { :
the condition has length > 1 and only the first element will be used
2: In if (is.na(col)) { :
the condition has length > 1 and only the first element will be used
3: `error_y.color` does not currently support multiple values.
4: `error_x.color` does not currently support multiple values.
5: `line.color` does not currently support multiple values.
6: The titlefont attribute is deprecated. Use title = list(font = ...) instead.
你也可以使用cells.highlight,用于在空間坐標圖上劃分感興趣的特定單元格。這對于區分單個集群的空間定位非常有用,如下所示:
SpatialDimPlot(brain, cells.highlight = CellsByIdentities(object = brain, idents = c(1, 2, 5, 3,
4, 8)), facet.highlight = TRUE, ncol = 3)
LinkedDimPlot和LinkedFeaturePlot函數支持交互式可視化。這些圖將UMAP表示與組織圖像表示聯系起來,并允許交互選擇。例如,您可以在UMAP圖中選擇一個區域,圖像表示中相應的點將突出顯示。
LinkedDimPlot(brain)
空間變量特征的識別
Seurat提供了兩個工作流程來識別與組織空間位置相關的分子特征。第一種是根據組織內預先標注的解剖區域進行差異表達,這種差異表達可以通過非監督聚類或先驗知識來確定。這種策略在這種情況下有效,因為上面的集群顯示出明顯的空間差異。
de_markers <- FindMarkers(brain, ident.1 = 4, ident.2 = 6)
|++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=37s
SpatialFeaturePlot(object = brain, features = rownames(de_markers)[1:3], alpha = c(0.1, 1), ncol = 3)
在FindSpatiallyVariables中實現的另一種方法是在沒有預注釋的情況下搜索顯示空間模式的特性。默認的方法(method = 'markvariogram ')受到 Trendsceek,的啟發,后者將空間轉錄組學數據建模為標記點過程,并計算一個' variogram ',它識別其表達水平取決于其空間位置的基因。更具體地說,這個過程計算伽瑪(r)值,測量兩個點之間一定的“r”距離的相關性。默認情況下,我們在這些分析中使用的r值為‘5’,并且只計算可變基因的這些值(其中的變異是獨立于空間位置計算的),以節省時間。
現在,我們可視化的表達前6個特征確定了這一措施。
brain <- FindSpatiallyVariableFeatures(brain, assay = "SCT", features = VariableFeatures(brain)[1:1000],
selection.method = "markvariogram")
top.features <- head(SpatiallyVariableFeatures(brain, selection.method = "markvariogram"), 6)
SpatialFeaturePlot(brain, features = top.features, ncol = 3, alpha = c(0.1, 1))
可視化解剖區域的子集
與單細胞對象一樣,您可以對該對象進行子集設置,以將重點放在數據的子集上。在這里,我們大致劃分了額葉皮質。這個過程也促進了這些數據與下一節的皮層scRNA-seq數據集的整合。首先,我們取集群的一個子集,然后根據精確的位置進一步細分。設置好亞組后,我們可以在完整圖像或裁剪圖像上看到皮質細胞。
cortex <- subset(brain, idents = c(1, 2, 3, 5, 6, 7))
# now remove additional cells, use SpatialDimPlots to visualize what to remove
# SpatialDimPlot(cortex,cells.highlight = WhichCells(cortex, expression = image_imagerow > 400 |
# image_imagecol < 150))
cortex <- subset(cortex, image_imagerow > 400 | image_imagecol < 150, invert = TRUE)
cortex <- subset(cortex, image_imagerow > 275 & image_imagecol > 370, invert = TRUE)
cortex <- subset(cortex, image_imagerow > 250 & image_imagecol > 440, invert = TRUE)
p1 <- SpatialDimPlot(cortex, crop = TRUE, label = TRUE)
p2 <- SpatialDimPlot(cortex, crop = FALSE, label = TRUE, pt.size.factor = 1, label.size = 3)
plot_grid(p1, p2)
與單細胞數據關聯分析(空間細胞類型定義)
在~50um時,visium檢測的斑點將包含多個細胞的表達譜。對于越來越多可用scRNA-seq數據的系統,用戶可能有興趣“反卷積”每個空間體素,以預測單元類型的底層組成。在準備這篇文章的過程中,我們測試了各種各樣的脫卵方法和整合方法(decovonlution and integration methods),使用的是來自Allen研究所的參考scRNA-seq數據集(reference scRNA-seq dataset),其中包含了大約14000只成年小鼠的皮層細胞分類,并使用SMART-Seq2 protocol 生成。
我們一致認為,使用集成方法(與反褶積方法相反)可以獲得更好的性能,這可能是因為空間和單細胞數據集的噪聲模型本質上是不同的,而集成方法的特殊設計是為了對這些差異具有魯棒性。因此我們應用“錨”的集成工作流一如最近在 Seurat v3介紹的,使注釋的概率從一個reference 數據query 數據集轉移。因此,我們遵循這里介紹的標簽轉移流程,利用sctransform正常化,但預測新方法被開發來完成這項任務。
我們首先加載數據( here提供下載,我只能假裝我下載成功了_),預處理scRNA-seq 參考數據集,然后執行標簽傳輸。該過程為每個spot輸出每個scRNA-seq派生類的概率分類。我們將這些預測添加到Seurat對象中作為新的試驗。
allen_reference <- readRDS("~/Downloads/allen_cortex.rds")
# note that setting ncells=3000 normalizes the full dataset but learns noise models on 3k cells
# this speeds up SCTransform dramatically with no loss in performance
library(dplyr)
allen_reference <- SCTransform(allen_reference, ncells = 3000, verbose = FALSE) %>% RunPCA(verbose = FALSE) %>%
RunUMAP(dims = 1:30)
# After subsetting, we renormalize cortex
cortex <- SCTransform(cortex, assay = "Spatial", verbose = FALSE) %>% RunPCA(verbose = FALSE)
# the annotation is stored in the 'subclass' column of object metadata
DimPlot(allen_reference, group.by = "subclass", label = TRUE)
anchors <- FindTransferAnchors(reference = allen_reference, query = cortex, normalization.method = "SCT")
predictions.assay <- TransferData(anchorset = anchors, refdata = allen_reference$subclass, prediction.assay = TRUE,
weight.reduction = cortex[["pca"]])
cortex[["predictions"]] <- predictions.assay
現在,我們得到了每個班每個點的預測分數。在額葉皮層區域特別有趣的是層狀興奮性神經元。在這里,我們可以區分這些神經元亞型的不同順序層,例如:
DefaultAssay(cortex) <- "predictions"
SpatialFeaturePlot(cortex, features = c("L2/3 IT", "L4"), pt.size.factor = 1.6, ncol = 2, crop = TRUE)
根據這些預測分數,我們還可以預測位置受到空間限制的細胞類型。我們使用基于標記點過程的相同方法來定義空間變量特征,但使用細胞類型預測評分作為“標記”,而不是使用基因表達。
cortex <- FindSpatiallyVariableFeatures(cortex, assay = "predictions", features = rownames(cortex),
r.metric = 5, slot = "data")
top.clusters <- head(SpatiallyVariableFeatures(cortex), 4)
SpatialPlot(object = cortex, features = top.clusters, ncol = 2)
最后,我們證明我們的整合程序能夠恢復已知的神經元和非神經元亞群的空間定位模式,包括層興奮性亞群、第1層星形膠質細胞和皮層灰質。
SpatialFeaturePlot(cortex, features = c("Astro", "L2/3 IT", "L4", "L5 PT", "L5 IT", "L6 CT", "L6 IT",
"L6b", "Oligo"), pt.size.factor = 1, ncol = 2, crop = FALSE, alpha = c(0.1, 1))
處理Seurat中的多個slices
這個老鼠大腦的數據集包含了另一個與大腦另一半相對應的切片。這里我們讀取它并執行相同的初始規范化。
brain2 <- LoadData("stxBrain", type = "posterior1")
brain2 <- SCTransform(brain2, assay = "Spatial", verbose = FALSE)
為了處理同一個Seurat對象中的多個片,我們提供了merge函數。其實之前就有的呀。
brain.merge <- merge(brain, brain2)
這樣就可以對底層的RNA表達數據進行聯合降維和聚類。
DefaultAssay(brain.merge) <- "SCT"
VariableFeatures(brain.merge) <- c(VariableFeatures(brain), VariableFeatures(brain2))
brain.merge <- RunPCA(brain.merge, verbose = FALSE)
brain.merge <- FindNeighbors(brain.merge, dims = 1:30)
brain.merge <- FindClusters(brain.merge, verbose = FALSE)
brain.merge <- RunUMAP(brain.merge, dims = 1:30)
最后,可以在單個UMAP圖中共同可視化數據。SpatialDimPlot和SpatialFeaturePlot將默認將所有片繪制為列,將groupings/features 繪制為行。
DimPlot(brain.merge, reduction = "umap", group.by = c("ident", "orig.ident"))
SpatialDimPlot(brain.merge)
SpatialFeaturePlot(brain.merge, features = c("Hpca", "Plp1"))
我們要感謝Nigel Delaney和Stephen Williams對Seurat 分析空間數據代碼的有益反饋和貢獻。