標題:Seurat - Guided Clustering Tutorial
網址:https://satijalab.org/seurat/v3.2/pbmc3k_tutorial.html
部分內容轉載來自:caokai001 鏈接:http://www.lxweimin.com/p/7e4c205a576e
部分內容轉載來自: 劉小澤 鏈接:http://www.lxweimin.com/p/b46b6b6d344f
一、設置Seurat對象
對于本教程,我們將分析可從10X Genomics免費獲得的外周血單個核細胞(PBMC)數據集。Illumina NextSeq 500上已對2700個單細胞進行了測序。原始數據可在此處找到。
我們從讀取數據開始。該Read10X
函數從10X讀取cellranger管道的輸出,返回唯一的分子識別(UMI)計數矩陣。該矩陣中的值表示在每個單元格(列)中檢測到的每個特征(即基因;行)的分子數。
接下來,我們使用計數矩陣創建一個Seurat
對象。該對象用作包含單個單元格數據集的數據(如計數矩陣)和分析(如PCA或聚類結果)的容器。有關Seurat
對象結構的技術討論,請查看我們的GitHub Wiki。例如,計數矩陣存儲在中pbmc[["RNA"]]@counts
。
library(dplyr)
library(Seurat)
library(patchwork)
# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "./10x_Rawdata/pbmc3k_filtered_gene_bc_matrices/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
#每個基因至少在3個細胞中表達,每個細胞中至少有200個基因表達。
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
> pbmc
An object of class Seurat
13714 features across 2700 samples within 1 assay
Active assay: RNA (13714 features, 0 variable features)
# Lets examine a few genes in the first thirty cells
>pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]
## 3 x 30 sparse Matrix of class "dgCMatrix"
##
## CD3D 4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2 3 . . . . . 3 4 1 5
## TCL1A . . . . . . . . 1 . . . . . . . . . . . . 1 . . . . . . . .
## MS4A1 . 6 . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .
.矩陣中的值表示0(沒有檢測到分子)。由于scRNA-seq矩陣中的大多數值為0,因此Seurat盡可能使用稀疏矩陣表示。這樣可以為Drop-seq / inDrop / 10x數據節省大量內存并節省速度。
>dense.size <- object.size(as.matrix(pbmc.data))
>dense.size
## 709591472 bytes
>sparse.size <- object.size(pbmc.data)
>sparse.size
## 29905192 bytes
>dense.size/sparse.size
## 23.7 bytes
二、標準的預處理流程
以下步驟包含Seurat中scRNA-seq數據的標準預處理工作流程。這些代表基于質量控制指標,數據歸一化和縮放以及高度可變特征的檢測來選擇和過濾細胞。
2.1 質控和選擇細胞進行進一步分析
通過Seurat,您可以輕松地探索質量控制指標并根據任何用戶定義的條件過濾單元。社區常用的一些質量控制指標包括
- 每個細胞中檢測到的獨特基因的數量。
- 低質量的細胞或空液滴通常很少有基因
- 細胞雙峰或多重峰可能顯示異常高的基因計數
- 同樣,細胞內檢測到的分子總數(與獨特基因高度相關)
- 映射到線粒體基因組的讀段的百分比
- 低質量/瀕死細胞通常表現出廣泛的線粒體污染
- 我們使用
PercentageFeatureSet
函數計算線粒體QC指標,該函數計算源自一組功能的計數的百分比 - 我們使用所有
MT-
以線粒體基因開頭的基因
> pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
> head(pbmc@meta.data,5)
orig.ident nCount_RNA nFeature_RNA percent.mt
AAACATACAACCAC-1 pbmc3k 2419 779 3.0177759
AAACATTGAGCTAC-1 pbmc3k 4903 1352 3.7935958
AAACATTGATCAGC-1 pbmc3k 3147 1129 0.8897363
AAACCGTGCTTCCG-1 pbmc3k 2639 960 1.7430845
AAACCGTGTATGCG-1 pbmc3k 980 521 1.2244898
在下面的示例中,我們可視化QC指標,并使用它們來過濾單元格。
- 過濾 unique feature counts 超過2500或少于200的細胞
- 過濾線粒體 > 5%的細胞
> VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
plot1 + plot2
#CombinePlots(plots = list(plot1,plot2))
過濾
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
>pbmc
An object of class Seurat
13714 features across 2638 samples within 1 assay
Active assay: RNA (13714 features, 0 variable features)
之前是13714 features across 2700 samples ,過濾掉了62個細胞
三、 預處理之歸一化
關于Seurat歸一化原理,可以看這一篇:https://www.biorxiv.org/content/biorxiv/early/2019/03/18/576827.full.pdf
標準化是一個比較簡單的過程,使用的是"logNormalize", 就是將每個基因的表達量對該細胞總表達量進行平衡,然后乘以一個因子(scale factor, 默認值為10,000), 然后中進行對數轉換。
默認是進行一個全局的LogNormalize
操作:log1p(value/colSums[cell-idx] *scale_factor)
,其中log1p指的是log(x + 1)
,得到的結果存儲在:pbmc[["RNA"]]@data
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
四、鑒定差異基因HVGs(highly variable features)
我們在Seurat3的流程詳細描述在這里,并通過直接建模在單細胞數據固有的均方差關系改進了以前的版本,并在實現FindVariableFeatures
功能。V3默認選擇2000個差異基因。這些將用于下游分析,例如PCA。
如果手動計算,相當于計算變異系數,而不是標準差。因為標準差對于數據呈現對稱分布,及單峰情況體現差異比較好,但是對于雙峰情況,變異系數cv 可能更好。
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)
SLM <<- FindVariableFeatures(SLM, selection.method = "mvp", mean.cutoff = c(0.1,100),dispersion.cutoff=c(-1,Inf))
##"mvp"這種寫法,最后鑒定出來了4000多個差異基因,不受默認值影響。
# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(pbmc), 10)
- V3橫坐標范圍設定參數改成:mean.cutoff;縱坐標改成:dispersion.cutoff
- 鑒定差異基因的算法包含三種:vst(默認)、mean.var.plot、dispersion
- vst:首先利用loess對 log(variance) 和log(mean) 擬合一條直線,然后利用觀測均值和期望方差對基因表達量進行標準化。最后根據保留最大的標準化的表達量計算方差
- mean.var.plot: 首先利用mean.function和 dispersion.function分別計算每個基因的平均表達量和離散情況;然后根據平均表達量將基因們分散到一定數量(默認是20個)的小區間(bin)中,并且計算每個bin中z-score
- dispersion:挑選最高離散值的基因
- V3默認選擇2000個差異基因,檢查方法也不同(V3用VariableFeatures(sce)檢查,V2用sce@var.genes檢查)
# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
> plot1 + plot2
Error in grid.Call(C_convert, x, as.integer(whatfrom), as.integer(whatto), :
Viewport has zero dimension(s)
此外: Warning messages:
1: Transformation introduced infinite values in continuous x-axis
2: Transformation introduced infinite values in continuous x-axis
有問題,未實現圖片:
紅色的HVGs 有2000個,從上面 FindVariableFeatures ,命令參數就可以知道.
五、標準化
從上圖中,我們可以看到很多基因都表現出很大的差異性,但是這些差異性并不一定都是事實,有些可能是因為實驗,或者數據采集的方式導入的。因此人們想盡量的消除這些因素帶來的差異。這些差異有可能是因為batch-effect, 或者cell alignment rate,或者其它。這些因素都可以寫入metadata中,然后通過ScaleData函數來消除。
ScaleData 可以通過metadata信息,消除很多其他因素影響。
5.1 縮放的標準
? 應用線性變換縮放數據,這是一個標準的預處理步驟,比PCA等降維技術更重要。使用ScaleData函數:
(1)使每個基因在所有細胞間的表達量均值為0
(2)使每個基因在所有細胞間的表達量方差為1
縮放操作給予下游分析同等的權重,這樣高表達基因就不會占主導地位,其結果存儲在pbmc[["RNA"]]@scale.data中,這里默認ScaleData 進行了中心化,標準化。
## 全局縮放
all.genes <- rownames(pbmc)
pbmc <- ScaleData(object = pbmc, features = all.genes)
> head(pbmc[["RNA"]]@scale.data[, 1:3])
## AAACATACAACCAC AAACATTGAGCTAC AAACCGTGCTTCCG
## AL627309.1 -0.06452497 -0.06452497 -0.06452497
## AP006222.2 -0.03726409 -0.03726409 -0.03726409
## RP11-206L10.2 -0.04153370 -0.04153370 -0.04153370
## RP11-206L10.9 -0.03734170 -0.03734170 -0.03734170
## LINC00115 -0.08343360 -0.08343360 -0.08343360
## NOC2L -0.32126699 -0.32126699 -0.32126699
縮放是Seurat工作流程中必不可少的步驟,但僅限于將用作PCA輸入的基因。因此,默認設置ScaleData是僅對先前確定的變量特征執行縮放(默認為2,000)
。為此,請忽略features上一個函數調用中的參數,即
>pbmc <- ScaleData(pbmc) #默認為2,000個高邊基因
這樣操作的結果中降維和聚類不會被影響,但是只對HVGs基因進行標準化,下面畫的熱圖依然會受到全部基因中某些極值的影響。所以為了熱圖的結果,還是對所有基因進行標準化比較好。
ScaleData
的操作過程是怎樣的?
看一下幫助文檔就能了解:
ScaleData
這個函數有兩個默認參數:do.scale = TRUE
和do.center = TRUE
,然后需要輸入進行scale/center
的基因名(默認是取前面FindVariableFeatures
的結果)。
scale
和center
這兩個默認參數應該不陌生了,center
就是對每個基因在不同細胞的表達量都減去均值;
scale
就是對每個進行center后的值再除以標準差(就是進行了一個z-score的操作)
再看一個來自BioStar的討論:https://www.biostars.org/p/349824/
問題1:為什么在NormalizeData()
之后,還需要進行ScaleData
操作?
前面NormalizeData
進行的歸一化主要考慮了測序深度/文庫大小的影響(reads *10000 divide by total reads, and then log
),但實際上歸一化的結果還是存在基因表達量分布區間不同的問題;而ScaleData
做的就是在歸一化的基礎上再添zero-centres
(mean/sd =》 z-score),將各個表達量放在了同一個范圍中,真正實現了”表達量的同一起跑線“。
另外,新版的ScaleData
函數還支持設定回歸參數,如(nUMI、percent.mito),來校正一些技術噪音
問題2: FindVariableGenes() or RunPCA() or FindCluster()
這些參數是基于歸一化Normalized_Data
還是標準化Scaled_Data
?
所有操作都是基于標準化的數據Scaled_Data
,因為這個數據是針對基因間比較的。例如有兩組基因表達量如下:
g1 10 20 30 40 50
g2 20 40 60 80 100
雖然它們看起來是g2的表達量是g1的兩倍,但真要降維聚類時,就要看scale
的結果:
> scale(c(10,20,30,40,50))
[,1]
[1,] -1.2649111
[2,] -0.6324555
[3,] 0.0000000
[4,] 0.6324555
[5,] 1.2649111
attr(,"scaled:center")
[1] 30
attr(,"scaled:scale")
[1] 15.81139
> scale(c(20,40,60,80,100))
[,1]
[1,] -1.2649111
[2,] -0.6324555
[3,] 0.0000000
[4,] 0.6324555
[5,] 1.2649111
attr(,"scaled:center")
[1] 60
attr(,"scaled:scale")
[1] 31.62278
二者標準化后的分布形態是一樣的(只是中位數不同),而我們后來聚類也是看數據的分布,分布相似聚在一起。所以歸一化差兩倍的兩個基因,根據標準化的結果依然聚在了一起
問題3: ScaleData()
在scRNA分析中一定要用嗎?
實際上標準化這個過程不是單細胞分析固有的,在很多機器學習、降維算法中比較不同feature的距離時經常使用。當不進行標準化時,有時feature之間巨大的差異(就像??問題2中差兩倍的基因表達量,實際上可能差的倍數會更多)會影響分析結果,讓我們誤以為它們的數據分布相差很遠。
很多時候,我們會混淆normalization
和scale
:那么看一句英文解釋:
Normalization "normalizes" within the cell for the difference in sequenicng depth / mRNA throughput. 主要著眼于樣本的文庫大小差異
Scaling "normalizes" across the sample for differences in range of variation of expression of genes . 主要著眼于基因的表達分布差異
另外,看scale()
函數的幫助文檔就會發現,它實際上是對列進行操作:
那么具體操作中是要先對表達矩陣轉置,然后scale,最后轉回來
t(scale(t(dat[genes,])))
問題4:RunCCA()
函數需要歸一化數據還是標準化數據?
通過看這個函數的幫助文檔:
RunCCA(object, object2, group1, group2, group.by, num.cc = 20, genes.use,
scale.data = TRUE, rescale.groups = FALSE, ...)
顯示scale.data = TRUE
,那么就需要標準化后的數據
刪除不需要的數據
使用ScaleData函數從單細胞數據集中刪除不需要的變量。例如,我們可以“regress out”與細胞周期階段或線粒體污染相關的異質性(去除不需要的變量,即校正協變量,校正線粒體基因比例的影響)。如下:
# 刪除不需要的數據,校正線粒體基因引起的影響
# 這個步驟非常耗時
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
我們對矩陣進行了細胞水平質控,但是如何對基因進行質控,當然我們創建seurat 對象時候,已經設定一個cutoff. 基因必須早多少個細胞中表達. 但是如果直接用這些基因進行聚類和降維(T-sne/UMAP 可視化 可能引起偏差,所以需要先進行一下PCA 初步選取主要的主成分,對應著權重不同的基因,再用這些基因進行聚類,降維可視化效果更好)
六、PCA
接下來,我們對縮放后的數據執行PCA。默認情況下,僅將先前確定的變量特征用作輸入,但是features如果您希望選擇其他子集,則可以使用arguments進行定義。默認使用標準化的數據
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
## PC_ 1
## Positive: CST3, TYROBP, LST1, AIF1, FTL
## Negative: MALAT1, LTB, IL32, IL7R, CD2
## PC_ 2
## Positive: CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1
## Negative: NKG7, PRF1, CST7, GZMB, GZMA
## PC_ 3
## Positive: HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1
## Negative: PPBP, PF4, SDPR, SPARC, GNG11
## PC_ 4
## Positive: HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1
## Negative: VIM, IL7R, S100A6, IL32, S100A8
## PC_ 5
## Positive: GZMB, NKG7, S100A8, FGFBP2, GNLY
## Negative: LTB, IL7R, CKB, VIM, MS4A7
Seurat提供了多種手段來查看PCA分析的結果,其中包括PrintPCA
, VizPCA
, PCAPlot
, 以及PCHeatmap
【一維可視化】 對每一個維度,權重較大的基因進行可視化
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
【二維可視化】 將細胞降維到二維空間
DimPlot(object = pbmc, reduction = "pca")
這個圖中每個點就是一個樣本,它根據PCA的結果坐標進行畫圖,這個坐標保存在了cell.embeddings中:
> head(pbmc[['pca']]@cell.embeddings)[1:2,1:2]
PC_1 PC_2
AAACATACAACCAC -4.7296855 -0.5184265
AAACATTGAGCTAC -0.5174029 4.5918957
其實還支持定義分組:根據pbmc@meta.data中的ident分組:
> table(pbmc@meta.data$orig.ident)
pbmc3k
2638
# 當然這里只有一個分組
Tips: 下圖以PC_1 來看,是解釋細胞分布最大的基因組合方向,所有的基因是維度,有些基因對這個方向共享很大,也就是說更容易分開細胞,這些基因可能更加重要。下面是熱圖1展示這些基因對于區分細胞的效果,可以看到將很多細胞區分成紫色和黃色.效果不錯.
可以看到5,6維度貌似區分不開了。
探索異質性來源—DimHeatmap
每個細胞和基因都根據PCA結果得分進行了排序,默認畫前30個基因(nfeatures設置),1個主成分(dims設置),細胞數沒有默認值(cells設置)
> DimHeatmap(pbmc, dims = 1:12, cells = 500, balanced = TRUE)
# 其中balanced表示正負得分的基因各占一半
降維的真實目的是盡可能減少具有相關性的變量數目,例如原來有700個樣本,也就是700個維度/變量,但實際上根據樣本中的基因表達量來歸類,它們或多或少都會有一些關聯,這樣有關聯的一些樣本就會聚成一小撮,表示它們的”特征距離“相近。最后直接分析這些”小撮“,就用最少的變量代表了實際最多的特征
既然每個主成分都表示具有相關性的一小撮變量(稱之為”metafeature“,元特征集),那么問題來了:
降維后怎么選擇合適數量的主成分來代表整個數據集?
七、確定PCA的維數
Suerat使用了jackStraw方法[4]來估計應該使用多少個principal components的基因來進行下游分析。
# 注意: 這可能是一個非常費時的過程。
pbmc <- JackStraw(pbmc, num.replicate = 100) # 重復一百次
pbmc <- ScoreJackStraw(pbmc, dims = 1:20) # 選擇20個PC
JackStrawPlot
以及PCElbowPlot
函數提供給我們兩種可視化手段來查看jackStraw的結果。使用JackStrawPlot
可以查看每個PC的p value,這樣方便我們通過p值進行篩選。PCElbowPlot
可以方便的查看從哪個PC開始,差分度就進入的平臺期。
- 1.
JackStrawPlot
JackStrawPlot(pbmc, dims = 1:15)
-
2.
PCElbowPlot
: 拐點圖 # 最大可設置到50ElbowPlot(pbmc,ndims = 50, reduction = "pca") # 最大可設置到50
它是根據每個主成分對總體變異水平的貢獻百分比排序得到的圖,我們主要關注”肘部“的PC,它是一個轉折點(也即是這里的PC9-10),說明取前10個主成分可以比較好地代表總體變化
但官方依然建議我們,下游分析時多用幾個成分試試(10個、15個甚至50個),如果起初選擇的合適,結果不會有太大變化;另外推薦開始不確定時要多選一些主成分,也不要直接就定下5個成分進行后續分析,那樣很有可能會出錯
先擇PC,對于得到正確的結果具體關鍵性的作用。除了上面的方法以外,還可以使用其它的一些辦法,比如說使用GSEA等富集分析的辦法來選擇PC,或者說使用一個隨機模型來查看具體哪些PC會比較有效果。但是后者這一方法在實現起來需要消耗過多的資源。
在本例中,因為是Seurat挑選的例子,所以通過上面的JackStraw方法,只要把cut.off值設置在7-10之間,就可以得到差不多的結果。
Tips: 確定進行聚類和降維的基因和細胞后,下一步就是聚類了,在這里需要搞情況聚類和降維作用是不一樣的。特別是T-sne是降維可視化作用,而不是用它來聚類.為什么看到T-sne 圖是不同顏色的色塊呢?常見的聚類包括kmeans/hclust .
八、細胞聚類
當決定了使用哪些PC中的基因對細胞進行分類之后,就可以使用FindClusters
來對細胞聚類了。分群后的結果會保存在object@ident
slot中。
Seurat 3版本提供了graph-based
聚類算法,參考兩篇文章:[SNN-Cliq, Xu and Su, Bioinformatics, 2015]和 [PhenoGraph, Levine et al., Cell, 2015]. 簡言之,這些graph
的方法都是將細胞嵌入一個算法圖層中,例如:K-nearest neighbor (KNN) graph
中,每個細胞之間的連線就表示相似的基因表達模式,然后按照這個相似性將圖分隔成一個個的高度相關的小群體(名叫‘quasi-cliques’ or ‘communities’
);
(Step-1)在PhenoGraph中,首先根據PCA的歐氏距離結果,構建了KNN圖,找到了各個近鄰組成的小社區;然后根據近鄰中兩兩住戶(細胞)之間的交往次數(shared overlap)計算每條線的權重(術語叫Jaccard similarity) 。這些計算都是用包裝好的函數FindNeighbors() 得到的,它的輸入就是前面降維最終確定的主成分。
(Step-2)得到權重后,為了對細胞進行聚類,使用了計算模塊的算法(默認使用Louvain,另外還有包括SLM的其他三種),使用FindClusters() 進行聚類。其中包含了一個resolution的選項,它會設置一個”間隔“值,該值越大,間隔越大,得到的cluster數量越多。一般來說,這個值在細胞數量為3000左右時設為0.4-1.2 會有比較好的結果
pbmc <- FindNeighbors(pbmc, dims = 1:10) ## dims 作為輸入的維度
pbmc <- FindClusters(pbmc, resolution = 0.6) ## 分辨率參數,和cluster 個數有關系,如何你想獲得粗糙的分類,需要調成大一些.
# 查看一下前幾個的cluster,結果聚成3類.可能發現新的細胞系.
head(Idents(pbmc), 5)
## AAACATACAACCAC AAACATTGAGCTAC AAACCGTGCTTCCG AAACCGTGTATGCG AAACGCTGGTTCTT
## 4 3 0 6 4
## Levels: 0 1 2 3 4 5 6 7 8
九、降維后,用聚類的類別可視化【UMAP/tSNE】
使用UMAP或者tSNE的好處在于將多維的PC圖降維至2維圖像中來,這樣方便分集細胞的可視化。 UMAP皺縮成團分不開,而tSNE圖則分散得多。
pbmc <- RunUMAP(pbmc, dims = 1:10)
P1 <- DimPlot(pbmc, reduction = "umap", label = TRUE)
pbmc <- RunTSNE(pbmc, dims = 1:10)
P2 <- DimPlot(pbmc, reduction = "tsne",label = TRUE)
P1 + P2
您可以在此時保存該對象,以便可以輕松地將其裝入,而不必重新運行上面執行的計算密集型步驟,也可以輕松地與協作者共享該對象。
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
得到聚類分組結果,通常需要繼續分析,在每組里面那些標記基因。由于10x genomic 對每一個細胞都進行標簽化,不知道每一個標簽對應那種細胞,可以通過每組的標記基因對每組進行細胞類型判別(根據文獻說明的已知marker),進而發現新的標記基因.
十、尋找分群marker基因
生成了tSNE圖像后,我們還需要確認這一堆堆的細胞都分別是些什么細胞,這時,可以使用特定細胞的marker來對不同的細胞群進行標記。但是想要對它們進行標記,首先需要得到每個集群差異表達的基因。
在比較時,Seurat使用一比多的辦法。如果需要對cluster 1的細胞(ident.1
)進行差異分析時,它比較的對象將是除了cluster 1以外的其它所有的細胞。也可以使用ident.2
參數來傳遞需要比較的對象。 在FindMarkers
函數中,min.pct
是指的marker基因所占細胞數的最低比例,這里使用1/4。 使用max.cells.per.ident
可以讓函數對細胞進行抽樣,以加速計算。 FindAllMarkers
可以一次性找到所有的高表達的marker。
FindAllMarkers()
函數,它默認會對單獨的一個細胞群與其他幾群細胞進行比較找到正、負表達biomarker(這里的正負有點上調、下調基因的意思;正marker表示在我這個cluster中表達量高,而在其他的cluster中低)。
# find all markers of cluster 1
cluster1.markers <- FindMarkers(object = pbmc, ident.1 = 1, min.pct = 0.25)
head(cluster1.markers, n = 5)
## p_val avg_logFC pct.1 pct.2 p_val_adj
## RPS12 4.371171e-118 0.5264969 1 0.990 5.994624e-114
## RPS6 1.681008e-114 0.5234111 1 0.994 2.305334e-110
## RPS27 1.719993e-107 0.5242477 1 0.991 2.358799e-103
## RPS14 1.546910e-105 0.4500125 1 0.993 2.121432e-101
## RPS25 5.848778e-98 0.5427189 1 0.973 8.021015e-94
上面這個代碼中min.pct的意思是:一個基因在任何兩群細胞中的占比最低不能低于多少,當然這個可以設為0,但會大大加大計算量.
還可以計算cluster 5與(cluster0+cluster3)的差異基因
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(object = pbmc, ident.1 = 5,
ident.2 = c(0,3), min.pct = 0.25)
head(cluster5.markers, n = 5)
## p_val avg_logFC pct.1 pct.2 p_val_adj
## FCGR3A 3.849393e-139 2.723391 0.981 0.098 5.279058e-135
## RHOC 1.149445e-91 1.665090 0.865 0.130 1.576350e-87
## CDKN1C 6.799344e-75 1.061123 0.519 0.022 9.324621e-71
## IFITM2 1.347125e-73 1.560680 1.000 0.644 1.847448e-69
## HES4 3.616785e-69 1.107357 0.596 0.052 4.960059e-65
計算所有類和其他類的標記基因,(對所有cluster都比較一下,only.pos = TRUE為只挑出來正表達marker):
pbmc.markers <- FindAllMarkers(object = pbmc, only.pos = TRUE,
min.pct = 0.25, logfc.threshold = 0.25)
#挑每個cluster的前2個
pbmc.markers %>% group_by(cluster) %>% top_n(n = 2, wt = avg_logFC)
## # A tibble: 18 x 7
## # Groups: cluster [9]
## p_val avg_logFC pct.1 pct.2 p_val_adj cluster gene
## <dbl> <dbl> <dbl> <dbl> <dbl> <fct> <chr>
## 1 0\. 3.72 0.969 0.136 0\. 0 S100A8
## 2 6.30e-298 3.77 0.996 0.236 8.63e-294 0 S100A9
## 3 7.44e- 94 0.807 0.938 0.587 1.02e- 89 1 LDHB
## 4 3.14e- 61 0.848 0.426 0.105 4.31e- 57 1 CCR7
## 5 1.22e- 80 0.975 0.981 0.635 1.67e- 76 2 LTB
## 6 5.02e- 69 0.956 0.783 0.315 6.88e- 65 2 IL7R
## 7 0\. 2.95 0.931 0.045 0\. 3 CD79A
## 8 5.62e-214 2.46 0.617 0.024 7.71e-210 3 TCL1A
## 9 3.86e-164 2.39 0.973 0.22 5.30e-160 4 CCL5
## 10 2.97e-142 2.12 0.595 0.052 4.07e-138 4 GZMK
## 11 1.66e-171 2.34 0.981 0.135 2.27e-167 5 FCGR3A
## 12 1.68e-106 1.90 1 0.368 2.30e-102 5 LST1
## 13 2.24e-211 3.48 0.972 0.063 3.07e-207 6 GZMB
## 14 1.84e-127 3.52 0.943 0.138 2.52e-123 6 GNLY
## 15 1.11e-180 2.68 0.806 0.013 1.52e-176 7 FCER1A
## 16 5.01e- 20 1.93 1 0.548 6.87e- 16 7 HLA-DPB1
## 17 4.08e-171 5.02 1 0.012 5.60e-167 8 PF4
## 18 6.09e- 99 5.96 1 0.026 8.35e- 95 8 PPBP
>top2 <- pbmc.markers %>% group_by(cluster) %>% top_n(n = 2, wt = avg_logFC)
> top2$gene
[1] "LDHB" "CCR7" "LTB" "AQP3" "S100A9" "S100A8" "CD79A" "TCL1A"
[9] "CCL5" "GZMK" "FCGR3A" "LST1" "GZMB" "GNLY" "TBCB" "NDUFA2"
[17] "FCER1A" "HLA-DPB1" "PF4" "PPBP"
還可以使用不同的算法來尋找差異表達的基因。在test.use
選項中設置(詳見:DE vignette )例如:
cluster1.markers <- FindMarkers(object = pbmc, ident.1 = 0,
thresh.use = 0.25, test.use = "roc",
only.pos = TRUE)
想了解更多關于查找差異表達基因的信息,可以查看Seurat的vignette。
【一維可視化】標記基因在不同cluster 表達量
拿到差異表達基因后,可以使用VlnPlot來查看結果。
VlnPlot(object = pbmc, features = c("MS4A1", "CD79A"))
# you can plot raw UMI counts as well
VlnPlot(pbmc, features = c("MS4A1", "CD79A"), slot = "counts", log = TRUE)
## RidgePlot
## RidgePlot
RidgePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", "CD8A"))
## DotPlot
DotPlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", "CD8A"))
【二維可視化】標記基因在不同細胞表達量
FeaturePlot(object = pbmc,
features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A",
"FCGR3A", "LYZ", "PPBP", "CD8A"),
cols = c("blue", "red"))
提取所有cluster 的top10 標記基因可視化
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
# 設置slim.col.label=TRUE將避免打印每個細胞的名稱,而只打印cluster的ID.
DoHeatmap(object = pbmc, features = top10$gene) + NoLegend()
目前我們通過聚類知道了,將細胞分成8個類別,但是并不知道具體是那種細胞。所有需要進一步通過已知的特定細胞標記基因對cluster 打上細胞類型標簽.
十一、對分群進行細胞類型標記
對于示例數據,我們已經有一些比較常見的細胞marker了,很方便的就可以對分集的細胞進行標記了。
Cluster ID | Markers | Cell Type |
---|---|---|
0 | IL7R, CCR7 | Naive CD4+ T |
1 | IL7R, S100A4 | Memory CD4+ |
2 | CD14, LYZ | CD14+ Mono |
3 | MS4A1 | B |
4 | CD8A | CD8+ T |
5 | FCGR3A, MS4A7 | FCGR3A+ Mono |
6 | GNLY, NKG7 | NK |
7 | FCER1A, CST3 | DC |
8 | PPBP | Platelet |
將原來的cluster 0-9 ,修改成對應的細胞名稱
new.cluster.ids <- c("Naive CD4 T", "Memory CD4 T",
"CD14+ Mono", "B", "CD8 T",
"FCGR3A+ Mono",
"NK", "DC", "Platelet","NULL")
names(new.cluster.ids) <- levels(pbmc)
pbmc <- RenameIdents(pbmc, new.cluster.ids)
P1 <- DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend()
P2 <- DimPlot(pbmc, reduction = "tsne", label = TRUE, pt.size = 0.5) + NoLegend()
P1 + P2
saveRDS(pbmc, file = "./output/pbmc3k_final.rds")
當我們修改了聚類的參數,結果會不同。比如分辨率參數.
# 生成一個快照, 其實就是把pbmc@ident中的數據拷貝到pbmc@meta.data中。
# 當我們想把pbmc@meta.data中的值賦值給pbmc@ident的話,可以使用SetAllIdent函數。
# 比如pbmc <- SetAllIdent(object=pbmc, id = 'orig.ident')
pbmc <- StashIdent(object = pbmc, save.name = "ClusterNames_0.6")
# 現在我們使用不同的resolution來重新分群。當我們提高resolution的時候,
# 我們可以得到更多的群。
# 之前我們在FindClusters中設置了save.snn=TRUE,所以可以不用再計算SNN了。
# 下面就直接提高一下區分度,設置resolution = 0.8
pbmc <- FindClusters(pbmc, resolution = 0.8)
番外
分辨率左圖是0.8,右圖0.6
# 并排畫兩個tSNE,右邊的是用ClusterNames_0.6 (resolution=0.6) 來分組顏色的。
# 我們可以看到當resolution提高之后,CD4 T細胞被分成了兩個亞群。
plot1 <- DimPlot(object = pbmc, reduction = "umap", label = TRUE) + NoLegend()
plot2 <- DimPlot(object = pbmc, reduction = "umap", label = TRUE,
group.by = "ClusterNames_0.6") +NoLegend()
plot1 + plot2
類別不同,我們又可以按照這一次聚類結果,尋找marker基因
# 我們再一次尋找不同分集中的marders。
tcell.markers <- FindMarkers(object = pbmc, ident.1 = 0, ident.2 = 1)
# Most of the markers tend to be expressed in C1 (i.e. S100A4).
# However, we can see that CCR7 is upregulated in
# C0, strongly indicating that we can differentiate memory from naive CD4 cells.
# cols.use demarcates the color palette from low to high expression
FeaturePlot(object = pbmc, features = c("S100A4", "CCR7"),
cols = c("blue", "red"))