劉小澤寫於2020.7.16
爲何取名叫“交響樂”?因爲單細胞分析就像一個大樂團,需要各個流程的協同配合
單細胞交響樂1-常用的數據結構SingleCellExperiment
單細胞交響樂2-scRNAseq從實驗到下游簡介
單細胞交響樂3-細胞質控
單細胞交響樂4-歸一化
單細胞交響樂5-挑選高變化基因
單細胞交響樂6-降維
單細胞交響樂7-聚類分羣
單細胞交響樂8-marker基因檢測
單細胞交響樂9-細胞類型註釋
單細胞交響樂9-細胞類型註釋
單細胞交響樂10-數據集整合後的批次矯正
單細胞交響樂11-多樣本間差異分析
單細胞交響樂12-檢測Doublet
1 前言
有時我們希望從scRNA數據中獲得細胞週期的信息,一般來講,細胞在各個週期的分佈可能與真實情況還是存在差距,但是可以用這種方法看看不同亞羣之間或者各個處理之間的擴增差異。許多細胞週期相關的關鍵節點(比如通過檢查點)屬於轉錄後調控,在轉錄組數據中不可見,但通過表達量的變化也可以進行初步的推斷。
另外還是先要放一張細胞週期的圖片:https://en.wikipedia.org/wiki/Cell_cycle
下面就用416B數據來看看
load('../0-data/clusted.sce.416b.RData')
sce.416b
## class: SingleCellExperiment
## dim: 46604 185
## metadata(0):
## assays(3): counts logcounts corrected
## rownames(46604): 4933401J01Rik Gm26206 ... CAAA01147332.1
## CBFB-MYH11-mcherry
## rowData names(4): Length ENSEMBL SYMBOL SEQNAME
## colnames(185): SLX-9555.N701_S502.C89V9ANXX.s_1.r_1
## SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 ...
## SLX-11312.N712_S507.H5H5YBBXX.s_8.r_1
## SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1
## colData names(11): Source Name cell line ... sizeFactor label
## reducedDimNames(2): PCA TSNE
## altExpNames(2): ERCC SIRV
2 使用細胞週期蛋白
2.1 先找細胞週期蛋白基因,再對照數據集
細胞週期蛋白(cyclins)控制着整個細胞週期的進展,並在細胞週期各階段的表達模式具有一定特點。例如:
- cyclin A在S和G2期表達;
- cyclin B在G2後期和M(mitosis有絲分裂期)表達量最高
- cyclin D在整個過程都表達,但在G1期表達最高;
- cyclin E在G1/S過渡期表達最高
根據相關基因在各個cluster的表達可以幫助判斷:
cyclin.genes <- grep("^Ccn[abde][0-9]$", rowData(sce.416b)$SYMBOL)
cyclin.genes <- rownames(sce.416b)[cyclin.genes]
cyclin.genes
## [1] "Ccnb3" "Ccna2" "Ccna1" "Ccne2" "Ccnd2" "Ccne1" "Ccnd1" "Ccnb2" "Ccnb1"
## [10] "Ccnd3"
畫個熱圖
library(scater)
plotHeatmap(sce.416b, order_columns_by="label",
cluster_rows=FALSE, features=sort(cyclin.genes))
圖中可以看到:cluster1很明顯ccnd系列的基因表達量高,說明它可能是G1期,而其他幾個clusters分散在後面的時期
2.2 先找marker基因,再對應細胞週期蛋白
不管怎樣,416b數據的對應關係還是很不錯的,界限清晰,但並非任何數據都像它一樣,尤其是一些異質性較高的數據中,細胞週期可能不是驅動基因表達變化的主力。
不過好在,即使不非常清楚地知道每個cluster的每個細胞所處的週期,也還是能回答一下細胞週期相關的問題。例如:我們可以利用常規的尋找差異基因的方法,找找有沒有基因在細胞週期蛋白中上調,來幫助判斷某個cluster中是否有更多細胞屬於某個細胞週期。
首先尋找marker基因
library(scran)
markers <- findMarkers(sce.416b, subset.row=cyclin.genes,
test.type="wilcox", direction="up")
# 4個cluster都各自找了細胞週期蛋白基因的排名
> markers
List of length 4
names(4): 1 2 3 4
然後對應細胞週期蛋白
比如看cluster4,它的Ccnb系列基因AUC指標高於其餘的基因,說明在cyclin B中表達量較高,存在更多的細胞處於G2/M期
markers[[4]]
這種直接通過表達量判斷的方法很直觀,也很好理解。但需要保證得到每個細胞週期蛋白基因表達量,而且需要一個假設:細胞週期蛋白基因的表達不受其他生物因素的影響,尤其對於那些非常容易混淆正常細胞週期的事件,如惡性癌細胞的擴增。
3 輔以參考數據
就是使用別人已經做好的細胞週期註釋數據,來輔助我們自己的數據進行註釋【有沒有很像之前細胞類型註釋的環節?】加入參考註釋的目的是:更精確地尋找細胞週期相關的基因
這裏使用的參考數據是來自 Buettner et al. 2015 的小鼠胚胎幹細胞結果
library(scRNAseq)
sce.ref <- BuettnerESCData()
sce.ref
## class: SingleCellExperiment
## dim: 38293 288
## metadata(0):
## assays(1): counts
## rownames(38293): ENSMUSG00000000001 ENSMUSG00000000003 ...
## ENSMUSG00000097934 ENSMUSG00000097935
## rowData names(3): EnsemblTranscriptID AssociatedGeneName GeneLength
## colnames(288): G1_cell1_count G1_cell2_count ... G2M_cell95_count
## G2M_cell96_count
## colData names(1): phase
## reducedDimNames(0):
## altExpNames(1): ERCC
> table(sce.ref$phase)
G1 G2M S
96 96 96
爲了提高判斷的精準度,可以除了參考數據集的註釋結果外,再加上GO中與細胞週期相關的基因,再與我們自己的基因取個交集
# 細胞週期通路(https://www.ebi.ac.uk/QuickGO/term/GO:0007049)基因
library(org.Mm.eg.db)
cycle.anno <- select(org.Mm.eg.db, keytype="GOALL", keys="GO:0007049",
columns="ENSEMBL")[,"ENSEMBL"]
# 再取交集
candidates <- Reduce(intersect,
list(rownames(sce.ref), rowData(sce.416b)$ENSEMBL, cycle.anno))
str(candidates)
## chr [1:1605] "ENSMUSG00000000001" "ENSMUSG00000000028" ...
用三者交集的基因,代入到註釋好的參考數據集中,繼續找marker基因(相當於再過濾一遍)
sce.ref <- logNormCounts(sce.ref)
phase.stats <- pairwiseWilcox(logcounts(sce.ref), sce.ref$phase,
direction="up", subset.row=candidates)
cycle.markers <- getTopMarkers(phase.stats[[1]], phase.stats[[2]])
將得到的marker基因給到416b數據
# 由於參考數據中的基因ID是Ensembl,所以這裏也使用Ensembl
test.data <- logcounts(sce.416b)
rownames(test.data) <- rowData(sce.416b)$ENSEMBL
library(SingleR)
assignments <- SingleR(test.data, ref=sce.ref,
label=sce.ref$phase, genes=cycle.markers)
tab <- table(assignments$labels, colLabels(sce.416b))
tab
##
## 1 2 3 4
## G1 71 7 19 1
## G2M 2 60 1 13
## S 5 2 4 0
# 可以再添加一步檢驗,看看兩個cluster之間細胞分佈的差異大小
chisq.test(tab[,1:2])
##
## Pearson's Chi-squared test
##
## data: tab[, 1:2]
## X-squared = 107.91, df = 2, p-value < 2.2e-16
可以看到,cluster1大部分的細胞都在G1期,和之前利用細胞週期蛋白得到的結果差不多。但和之前的方法不同的是,這次我們是清楚看到有多少細胞處於哪個時期,而不是通過圖去觀察
4 用已發表的分類器
例如Scialdone et al. (2015)發表了一個cyclone
的分類器,屬於scran包,其中也是包括了小鼠和人的訓練數據集
# 加載內置數據
set.seed(100)
library(scran)
mm.pairs <- readRDS(system.file("exdata", "mouse_cycle_markers.rds",
package="scran"))
> class(mm.pairs)
[1] "list"
> names(mm.pairs)
[1] "G1" "S" "G2M"
> head(mm.pairs$G1)
first second
1 ENSMUSG00000000001 ENSMUSG00000001785
2 ENSMUSG00000000001 ENSMUSG00000005470
3 ENSMUSG00000000001 ENSMUSG00000012443
4 ENSMUSG00000000001 ENSMUSG00000015120
5 ENSMUSG00000000001 ENSMUSG00000022033
6 ENSMUSG00000000001 ENSMUSG00000023015
# 進行比較
assignments <- cyclone(sce.416b, mm.pairs, gene.names=rowData(sce.416b)$ENSEMBL)
> class(assignments)
[1] "list"
> names(assignments)
[1] "phases" "scores"
[3] "normalized.scores"
> dim(assignments$scores)
[1] 185 3
> head(assignments$scores)
G1 S G2M
1 0.663 0.995 0.000
2 0.960 0.456 0.003
3 0.055 0.517 0.144
4 0.000 0.768 1.000
5 0.927 0.473 0.002
6 0.914 0.944 0.000
看這個score結果
其中對416b數據中的每個細胞都劃定了一個分數,分數越高就越傾向於那個週期,比如看看G1和G2/M期
plot(assignments$score$G1, assignments$score$G2M,
xlab="G1 score", ylab="G2/M score", pch=16)
判斷標準
如果G1 分數高於0.5並且大於G2/M的分數,那麼就判斷爲G1期;同樣的方法可以判斷G2/M期;如果二者分數都不大於0.5,那就是S期
table(assignments$phases, colLabels(sce.416b))
##
## 1 2 3 4
## G1 74 8 20 0
## G2M 1 48 0 13
## S 3 13 4 1
這種方法使用簡單,就是實際使用過程可能會耗時
5 移除細胞週期導致的差異
有時擔心細胞週期帶來的數據差異會影響下游分析,如果要去掉這部分影響,可以先按照上面的方法推斷出細胞週期,然後將每個週期當成一個獨立的批次,再進行批次矯正。最簡單的方法是使用線性模型(如regressBatches()
)來移除這個影響
library(batchelor)
sce.nocycle <- regressBatches(sce.416b, batch=assignments$phases)
# 另外其他支持block的函數也是可以移除這個影響的
dec.nocycle <- modelGeneVarWithSpikes(sce.416b, "ERCC",
block=assignments$phases)
marker.nocycle <- findMarkers(sce.416b, block=assignments$phases)
不過,這個操作並非常規的分析流程。因爲大部分數據中,細胞週期導致的差異是次要的,不會超過細胞真實生物差異的影響。
歡迎關注我們的公衆號~_~
我們是兩個農轉生信的小碩,打造生信星球,想讓它成爲一個不拽術語、通俗易懂的生信知識平臺。需要幫助或提出意見請後臺留言或發送郵件到[email protected]