劉小澤寫于19.8.9-第三單元第五講:利用scRNAseq包學習scater
筆記目的:根據生信技能樹的單細胞轉錄組課程探索smart-seq2技術相關的分析技術
課程鏈接在:http://jm.grazy.cn/index/mulitcourse/detail.html?cid=53
復習
我們之前在第14篇筆記中學習了scRNAseq包的數據,知道了它可以分成4組:pluripotent stem cells 分化而成的 neural progenitor cells (NPC,神經前體細胞) ,還有 GW16(radial glia,放射狀膠質細胞) 、GW21(newborn neuron,新生兒神經元) 、GW21+3(maturing neuron,成熟神經元) ,其中NPC和其他組區別較大。并且使用常規的操作進行了初步的探索,但是畢竟是單細胞數據,就會有專業的包對它進行處理,于是這次就來介紹第一款:scater包(https://www.bioconductor.org/packages/release/bioc/html/scater.html)
首先來看官網教程
親測,6個小時就能學完Scater官方提供的三個教程
這個包是EMBL和劍橋大學發布的,是為分析單細胞轉錄組數據而開發,它包含了一些特性:
- 它需要利用
SingleCellExperiment
這個對象,就是這個東西(來自Bioconductor-workshop):
- 可以導入非比對工具 kallisto and Salmon 得到的定量結果
- 計算了大量的QC指標,方便過濾
- 可視化方面做得不錯,設計了大量的函數(尤其針對質控),并且功能如其名
- 從2017年7月,scater包就改變了整體架構,從之前的
SCESet
對象更改成了更多人都在用的SingleCellExperiment
,使用Bioconductor 3.6 (2017.10發布)安裝的包,都會是SingleCellExperiment
對象。如果要更迭也不難,官方給了許多解決方案,例如:toSingleCellExperiment
函數、updateSCESet
函數
假設現在有一個包含表達量信息的矩陣,其中包含的feature信息可以是gene, exon, region, etc.
第一步 創建一個SingleCellExperiment
對象 (官網 24 May 2019)
- 需要注意的是,官方友情提示,在導入對象之前,最好是將表達量數據存為矩陣;
- 如果是較大的數據集,官方建議使用
chunk-by-chunk
的方法,參考Matrix 包,然后使用readSparseCounts
函數,有效減少內存使用量(因為它可以不將大量的0表達量放進內存); - 如果是導入10X的數據,使用DropletUtils 包的
read10xCounts
函數即可,它會自動生成一個SingleCellExperiment
對象 - 對于非比對定量工具,scater也提供了
readSalmonResults
、readKallistoResults
支持兩款軟件,它的背后利用的是tximport
rm(list = ls())
Sys.setenv(R_MAX_NUM_DLLS=999) ##在R3.3版本中,只能有100個固定的動態庫限制,到了3.4版本以后,就能夠使用Sys.setenv(R_MAX_NUM_DLLS=xxx)進行設置,而這個數字根據個人情況設定
options(stringsAsFactors = F)
# 使用包自帶的測試數據進行操作
library(scater)
data("sc_example_counts")
data("sc_example_cell_info")
> dim(sc_example_counts)
[1] 2000 40
> sc_example_counts[1:3,1:3] # 基因表達矩陣
Cell_001 Cell_002 Cell_003
Gene_0001 0 123 2
Gene_0002 575 65 3
Gene_0003 0 0 0
> sc_example_cell_info[1:3,1:3] # 樣本注釋信息
Cell Mutation_Status Cell_Cycle
Cell_001 Cell_001 positive S
Cell_002 Cell_002 positive G0
Cell_003 Cell_003 negative G1
# 接下來就是構建對象(日后只需要復制粘貼替換即可)
example_sce <- SingleCellExperiment(
assays = list(counts = sc_example_counts),
colData = sc_example_cell_info
)
> example_sce
class: SingleCellExperiment
dim: 2000 40
metadata(0):
assays(1): counts
rownames(2000): Gene_0001 Gene_0002 ... Gene_1999 Gene_2000
rowData names(0):
colnames(40): Cell_001 Cell_002 ... Cell_039 Cell_040
colData names(4): Cell Mutation_Status Cell_Cycle Treatment
reducedDimNames(0):
spikeNames(0):
注意到上面構建對象時使用了counts = sc_example_counts
這么一個定義,官方也推薦,使用counts
作為導入表達矩陣的名稱,這樣會方面下面的counts
函數提取;另外還支持exprs
、tmp
、cpm
、fpkm
這樣的輸入名稱
> str(counts(example_sce))
int [1:2000, 1:40] 0 575 0 0 0 0 0 0 416 12 ...
- attr(*, "dimnames")=List of 2
..$ : chr [1:2000] "Gene_0001" "Gene_0002" "Gene_0003" "Gene_0004" ...
..$ : chr [1:40] "Cell_001" "Cell_002" "Cell_003" "Cell_004" ...
調用或修改行或列的metadata比較方便:
# 默認調用/修改 列,所以example_sce$whee就是新增一列metadata
example_sce$whee <- sample(LETTERS, ncol(example_sce), replace=TRUE)
colData(example_sce)
# 如果對行新增一行metadata(注意這里rowData和原來的矩陣沒有關系,它操作的是一些注釋信息)
rowData(example_sce)$stuff <- runif(nrow(example_sce))
rowData(example_sce)
除此以外,還有一些比較復雜的函數:例如isSpike
對spike-in操作,sizeFactors
是進行標準化時對細胞文庫大小計算的結果、reducedDim
對降維結果(reduced dimensionality results)操作
另外,對這個對象取子集也是很方便的,例如要過濾掉在所有細胞中都不表達的基因:
# 過濾不表達基因
keep_feature <- rowSums(counts(example_sce) > 0) > 0
example_sce <- example_sce[keep_feature,]
第二步 (可選)計算一堆表達統計值 (官網 24 May 2019)
如果要計算CPM值,之前一直使用log2(edgeR::cpm(dat)+1)
進行計算,這個包自己做了一個函數:
# 計算的CPM值存到example_sce對象的標準命名(cpm)中去
cpm(example_sce) <- calculateCPM(example_sce)
另外還可以提供歸一化:normalize
函數,它計算得到:log2-transformed normalized expression values
# 總體計算方法是:dividing each count by its size factor (or scaled library size, if no size factors are defined), adding a pseudo-count and log-transforming (翻譯一下:將每個count值除以size factor,記得之前edgeR進行標準化就計算了這么一個值,它就是為了均衡各個樣本文庫差異;如果沒有size factor,也可以對文庫大小進行歸一化),接著加一個值(例如1,為了不讓log為難),最后log計算
example_sce <- normalize(example_sce) # 結果保存在logcounts中
assayNames(example_sce)
## [1] "counts" "cpm" "logcounts"
注意:表達矩陣的標準命名中,
exprs
和logcounts
是同義詞,它是為了和老版本的scater函數兼容:identical(exprs(example_sce), logcounts(example_sce)) ## [1] TRUE
另外,我們也可以根據需要創建一個和原始count矩陣同樣維度的新矩陣,存儲在assay
中
# 比如創建一個判斷的矩陣,看看原來count矩陣中的每個值是不是都大于0,結果是一堆的邏輯值
assay(example_sce, "is_expr") <- counts(example_sce)>0
還有,calcAverage
函數可以計算樣本歸一化以后,各個基因的平均表達量(如果樣本還沒進行標準化,那么它首先會計算size factor)
head(calcAverage(example_sce))
## Gene_0001 Gene_0002 Gene_0003 Gene_0004 Gene_0005 Gene_0006
## 305.551749 325.719897 183.090462 162.143201 1.231123 187.167913
第三步 數據可視化(官網 24 May 2019)
重點包含這幾方面:
-
plotExpression
:畫出一個或多個基因在細胞中的表達量水平 -
plotReducedDim
:(計算或)繪制降維后的坐標 - 其他的QC圖
# 創建并標準化
library(scater)
data("sc_example_counts")
data("sc_example_cell_info")
example_sce <- SingleCellExperiment(
assays = list(counts = sc_example_counts),
colData = sc_example_cell_info
)
example_sce <- normalize(example_sce)
example_sce
## class: SingleCellExperiment
## dim: 2000 40
## metadata(1): log.exprs.offset
## assays(2): counts logcounts
## rownames(2000): Gene_0001 Gene_0002 ... Gene_1999 Gene_2000
## rowData names(0):
## colnames(40): Cell_001 Cell_002 ... Cell_039 Cell_040
## colData names(4): Cell Mutation_Status Cell_Cycle Treatment
## reducedDimNames(0):
## spikeNames(0):
先來繪制基因表達相關的圖:
通過這種方式,可以方便檢查差異分析、擬時序分析等等的feature結果;它默認使用標準化后的logcounts
值,當然,可以定義exprs_values
參數來修改
# 最簡單的圖
# 默認使用標準化后的logcounts值
plotExpression(example_sce, rownames(example_sce)[1:6])
# 增加分組信息:定義x是一個離散型分組變量
plotExpression(example_sce, rownames(example_sce)[1:6],
x = "Mutation_Status", exprs_values = "logcounts")
# 查看繪制的x這個metadata
> colData(example_sce)$Mutation_Status
[1] "positive" "positive" "negative" "negative" "negative" "negative" "positive" "positive"
[9] "negative" "positive" "negative" "negative" "positive" "negative" "negative" "negative"
[17] "positive" "negative" "negative" "negative" "positive" "positive" "negative" "positive"
[25] "negative" "positive" "positive" "negative" "positive" "negative" "negative" "positive"
[33] "positive" "negative" "positive" "negative" "negative" "negative" "negative" "negative"
不難看到,它是將細胞先根據x = "Mutation_Status"
進行了分組,然后對6個基因繪制了表達分布圖
這個
x
參數的設置很講究:它的英文含義是 covariate to be shown on the x-axis,定義了x軸上的協變量。簡單理解,就是x軸上按照什么來定義,如果x是一個分類的離散型變量(比如這里的positive、negative),那么x軸就是為了分組,結果就是小提琴圖;如果x是一個連續的變量(比如下面??要演示的某個基因表達量),那么x軸就是為了看數值的變化,結果就是散點圖
# 定義x是一個連續型變量
plotExpression(example_sce, rownames(example_sce)[1:6],
x = "Gene_0001")
可以自定義顏色、形狀、大小的區分,例如:
plotExpression(example_sce, rownames(example_sce)[1:6],
colour_by = "Cell_Cycle", shape_by = "Mutation_Status",
size_by = "Gene_0002")
# 利用兩個metadata:Cell_Cycle(區分顏色)、Mutation_Status(區分形狀)
# 利用一個表達量指標:Gene_0002(區分大小)
上面這張圖可以再加上之前說的
x
參數,還是按照Mutation_Status進行x軸分組
# 添加中位線、x軸分組
plotExpression(example_sce, rownames(example_sce)[7:12],
x = "Mutation_Status", exprs_values = "counts",
colour = "Cell_Cycle", show_median = TRUE,
xlab = "Mutation Status", log = TRUE)
再來繪制降維相關的圖:
SingleCellExperiment
對象中包含了reducedDims
接口,其中存儲了細胞降維后的坐標,可以用reducedDim
、reducedDims
函數獲取
關于這兩個函數的不同:使用
?reducedDim
就能獲得
ForreducedDim
, a numeric matrix is returned containing coordinates for cells (rows) and dimensions (columns).For
reducedDims
, a named SimpleList of matrices is returned, with one matrix for each type of dimensionality reduction method.
降維首先利用PCA方法:
# runPCA結果保存在sce對象的PCA中。默認情況下,runPCA會根據500個變化差異最顯著的feature的log-count值進行計算,當然這個數量可以通過ntop參數修改。
example_sce <- runPCA(example_sce)
> reducedDimNames(example_sce)
[1] "PCA"
> example_sce
class: SingleCellExperiment
dim: 2000 40
metadata(1): log.exprs.offset
assays(2): counts logcounts
rownames(2000): Gene_0001 Gene_0002 ... Gene_1999 Gene_2000
rowData names(0):
colnames(40): Cell_001 Cell_002 ... Cell_039 Cell_040
colData names(4): Cell Mutation_Status Cell_Cycle Treatment
reducedDimNames(1): PCA
spikeNames(0):
注:runPCA源代碼在此:https://rdrr.io/bioc/scater/src/R/runPCA.R
任何的降維結果,都能用plotReducedDim
函數作圖
plotReducedDim(example_sce, use_dimred = "PCA",
colour_by = "Treatment", shape_by = "Mutation_Status")
然后可以利用表達量添加顏色、大小分組
# 看特定基因在PCA過程中起到的作用
plotReducedDim(example_sce, use_dimred = "PCA",
colour_by = "Gene_1000", size_by = "Gene_0500")
除了使用
plotReducedDim
,還能使用plotPCA
自己去生成,但前提還是要使用PCA的計算結果;如果檢測不到PCA的計算坐標,這個函數會自己runPCA
計算一遍。盡管如此,還是推薦先進行計算,再作圖。因為有時候我們需要利用一個數據集做出多張不同的圖(就像上面??一樣),但是每做一張圖這個函數都要運行一遍太費時間,如果已經計算好,那么它就能直接調用,十分方便
# 最簡單的plotPCA
plotPCA(example_sce)
它也可以像plotReducedDim
一樣,定義顏色、大小
plotPCA(example_sce, colour_by = "Gene_0001", size_by = "Gene_1000")
另外我們可以自己選擇進行PCA的數據,例如使用自己的feature_control
(例如使用的ERCC spike-in ),來看看數據中是否存在技術誤差而導致差異
# 默認情況下,runPCA會根據500個變化差異最顯著的feature。這里定義 feature_set可以覆蓋默認設置
# 看官方描述:eature_set Character vector of row names, a logical vector or a numeric vector of indices indicating a set of features to use for PCA. This will override any \code{ntop} argument if specified.
example_sce2 <- runPCA(example_sce,
feature_set = rowData(example_sce)$is_feature_control)
plotPCA(example_sce2)
還可以繪制多個主成分:
example_sce <- runPCA(example_sce, ncomponents=20)
# 繪制4個成分
plotPCA(example_sce, ncomponents = 4, colour_by = "Treatment",
shape_by = "Mutation_Status")
接著使用t-SNE(t-distributed stochastic neighbour embedding)降維:**
關于tsne這個流行的算法,有必要了解一下:
- tsne的作者Laurens強調,可以通過
t-SNE
的可視化圖提出一些假設,但是不要用t-SNE
來得出一些結論,想要驗證你的想法,最好用一些其他的辦法。- t-SNE中集群之間的距離并不表示相似度 ,同一個數據上運行
t-SNE
算法多次,很有可能得到多個不同“形態”的集群。但話說回來,真正有差異的群體之間,不管怎么變換形態,它們還是有差別- 關于perplexity的使用:(默認值是30) 如果忽視了perplexity帶來的影響,有的時候遇到
t-SNE
可視化效果不好時,對于問題無從下手。perplexity表示了近鄰的數量,例如設perplexity為2,那么就很有可能得到很多兩個一對的小集群。
- 有的時候會出現同一集群被分為兩半的情況,但群間的距離并不能說明什么,解決這個問題,只需要跑多次找出效果最好的就可以了
引用自: https://bindog.github.io/blog/2018/07/31/t-sne-tips/
很好的tsne可視化:https://distill.pub/2016/misread-tsne/
和PCA類似,先runTSNE
,再plotTSNE
。另外注意,為了重復結果要設置隨機種子,因為tsne每次映射的坐標結果都不同。官方強烈建議,使用不同的隨機種子和perplexity數值出圖
# Perplexity of 10 just chosen here arbitrarily.
set.seed(1000)
example_sce <- runTSNE(example_sce, perplexity=10)
plotTSNE(example_sce, colour_by = "Gene_0001", size_by = "Gene_1000")
還可以使用diffusion maps降維:
example_sce <- runDiffusionMap(example_sce)
plotDiffusionMap(example_sce, colour_by = "Gene_0001", size_by = "Gene_1000")
第四步 質控(官網 24 May 2019)
作為關鍵的一步,值得關注!
質控主要包含以下三步:
- 質控并過濾細胞
- 質控并過濾feature(基因)
- 對實驗的一些變量進行質控
首先登場的是calculateQCMetrics
函數
它對每個細胞和feature信息計算了大量的統計指標,分別存在colData
和rowData
中,這個函數默認對count值進行計算,但是也可以通過參數exprs_values
進行修改
example_sce <- calculateQCMetrics(example_sce)
> colnames(colData(example_sce)) # 樣本質控
[1] "Cell" "Mutation_Status"
[3] "Cell_Cycle" "Treatment"
[5] "is_cell_control" "total_features_by_counts"
[7] "log10_total_features_by_counts" "total_counts"
[9] "log10_total_counts" "pct_counts_in_top_50_features"
[11] "pct_counts_in_top_100_features" "pct_counts_in_top_200_features"
[13] "pct_counts_in_top_500_features"
> colnames(rowData(example_sce)) # feature質控
[1] "is_feature_control" "mean_counts" "log10_mean_counts" "n_cells_by_counts"
[5] "pct_dropout_by_counts" "total_counts" "log10_total_counts"
另外可以此時設置對照:對feature(基因)信息來講,可以添加ERCC、線粒體基因等信息,對細胞來講,可以添加empty wells、 visually damaged cells等信息,然后接下來計算的QC指標就會包含這些信息
example_sce <- calculateQCMetrics(example_sce,
feature_controls = list(ERCC = 1:20, mito = 500:1000),
cell_controls = list(empty = 1:5, damaged = 31:40))
all_col_qc <- colnames(colData(example_sce))
all_col_qc <- all_col_qc[grep("ERCC", all_col_qc)]
# 取出的就是ERCC的指標
> all_col_qc
[1] "total_features_by_counts_ERCC" "log10_total_features_by_counts_ERCC"
[3] "total_counts_ERCC" "log10_total_counts_ERCC"
[5] "pct_counts_ERCC" "pct_counts_in_top_50_features_ERCC"
[7] "pct_counts_in_top_100_features_ERCC" "pct_counts_in_top_200_features_ERCC"
[9] "pct_counts_in_top_500_features_ERCC"
如果定義了control組,那么計算的結果還會有一類:就是將control匯總在一起計算的
feature_control
和cell_control
;非control的匯總在一起得到endogenous
和non_control
(這幾個名稱在我們命名數據集時應該避開)
關于細胞質控的幾個重點關注結果
total_counts:每個細胞中總表達量(文庫大小)
total_features_by_counts:細胞中超過規定閾值(默認是0)的feature數量
-
pct_counts_X:屬于feature control組(也就是這里的X)的表達量占比
如果使用的不是counts值而是其他矩陣,比如tpm,那么結果中也會將counts替換為tpm
關于feature質控的幾個重點關注結果
- mean_counts:基因/feature的平均表達量
- pct_dropout_by_counts:基因在細胞中表達量為0的細胞數占比(該基因丟失率)
- pct_counts_Y:屬于cell control組的表達量占比
- log10_mean_counts:歸一化 log10 scale
- n_cells_by_counts:多少個細胞表達了該基因
繪圖函數--檢測高表達基因(plotHighestExprs
)
默認顯示前50個基因。圖中每一行表示一個基因,每個線條(bar)表示這個基因在不同細胞的表達量(可以想象成把基因表達量的箱線圖轉了一下)。圓圈是每個基因表達量的中位數,并且在圖中經過了排序。
plotHighestExprs(example_sce, exprs_values = "counts")
我們期待這個圖會給出符合常理的結果,比如:線粒體基因、actin、ribosomal protein、MALAT1,另外或許有少量的ERCC spike-in在這里有顯示。ERCC數量少還可以,但是如果在top50基因中,ERCC占比過多,就表示加入了太高濃度的外源RNA,高ERCC含量與低質量數據相關,通常是排除的標準。除此以外,還有可能會見到一些假基因或預測的基因名,這表明可能比對過程出現了問題
繪圖函數—表達頻率比均值(plotExprsFreqVsMean
)
表達頻率指的是非0表達量的細胞數量(當然這個表達閾值也可以自己定義);理論上,對于大多數基因來說,它應該和平均表達量正相關
plotExprsFreqVsMean(example_sce)
但其實圖中也能看出一些異常:
-
例如表達量均值很低,但覆蓋的細胞數量由非常高(圖中左上部),可能的原因是:比對到一些假基因(pseudo-genes )(假基因是原來的能翻譯成蛋白的基因經過各種突變導致喪失功能的基因),然后造成了一個假象
一般來說,結尾是P1等字眼的都是假基因(如:KRAS-->KRASP1);根據https://www.genenames.org/download/statistics-and-files/數據,目前存在13311個假基因
又如,表達量均值很高,但細胞數量卻很少(圖中右下部),可能因為PCR擴增偏好性(或者存在罕見的細胞群)
繪圖函數—總feature表達量 vs feature control占比(plotColData
)
這個函數是對細胞進行質控的,原理很簡單,就是看看細胞中實際表達量高還是feature control(例如ERCC)的占比高。如果實際表達量高,feature control占比小的話,就說明細胞質量不錯;相反,就說明存在blank and failed cells的情況。我們最后就是看散點主要集中在哪邊(右下部效果較好)
plotColData(example_sce, x = "total_features_by_counts",
y = "pct_counts_feature_control", colour = "Mutation_Status") +
theme(legend.position = "top") +
stat_smooth(method = "lm", se = FALSE, size = 2, fullrange = TRUE)
繪圖函數—表達量累計貢獻圖(plotScater
)
這個函數先在表達量最高的基因中選一部分(默認是500個),然后從高到低累加,看看它們對每個細胞文庫的貢獻值如何。它將不同細胞的不同基因表達分布繪制出來,就像芯片數據或bulk轉錄組數據每個樣本做一個箱線圖,來看基因表達量分布。但是由于單細胞數據樣本太多,沒辦法全畫出箱線圖。
為了看不同細胞的表達量差異,可以利用colData
中的數據將細胞分類;
默認使用counts值,但是只要在assays
存在的表達矩陣,就可以在exprs_values
參數中自定義
plotScater(example_sce, block1 = "Mutation_Status", block2 = "Treatment",
colour_by = "Cell_Cycle", nfeatures = 300, exprs_values = "counts")
這個圖在處理不同批次細胞時就可以很清楚地看到它們之間的差異
繪圖函數—QC結果兩兩比較
# 比較feature的屬性
plotRowData(example_sce, x = "n_cells_by_counts", y = "mean_counts")
# 比較樣本的屬性
p1 <- plotColData(example_sce, x = "total_counts",
y = "total_features_by_counts")
p2 <- plotColData(example_sce, x = "pct_counts_feature_control",
y = "total_features_by_counts")
p3 <- plotColData(example_sce, x = "pct_counts_feature_control",
y = "pct_counts_in_top_50_features")
# 最后可以組合
multiplot(p1, p2, p3, cols = 3)
第五步-1 對細胞過濾(官網 24 May 2019)
對列取子集
列就是細胞樣本,最簡單的方法就是直接按照類似數據框的操作:
example_sce <- example_sce[,1:40]
另外,還提供了filter
函數(受到dplyr
包的同名函數啟發)
filter(example_sce, Treatment == "treat1")
設置條件來過濾
例如設置細胞的總表達量不能低于100,000,總表達基因數不能少于500
keep.total <- example_sce$total_counts > 1e5
keep.n <- example_sce$total_features_by_counts > 500
filtered <- example_sce[,keep.total & keep.n]
dim(filtered)
## [1] 2000 37
除此以外,還有一種更靈活的方式:isOutlier
函數,它設置的是距離中位數差幾個MAD值(絕對中位差 median absolute deviations),超過設定值的被認為是離群點(outlier),它們就會被舍去。例如設置過小的離群點為:log count值低于中位數的3個MAD值。
可以看到,這個函數沒有“一刀切”,可以根據測序深度、spike-in的影響、細胞類型等進行調整。
如何設置閾值是一門學問,官方也推薦看看:https://bioconductor.org/packages/release/workflows/html/simpleSingleCell.html
keep.total <- isOutlier(example_sce$total_counts, nmads=3,
type="lower", log=TRUE)
filtered <- example_sce[,keep.total]
根據QC結果來過濾
比如用一個PCA圖:
example_sce <- runPCA(example_sce, use_coldata = TRUE,
detect_outliers = TRUE)
plotReducedDim(example_sce, use_dimred="PCA_coldata")
結果就會在example_sce
對象中增加一個outlier
的接口,我們可以這樣看:
summary(example_sce$outlier)
## Mode FALSE
## logical 40
第五步-2 對feature過濾(官網 24 May 2019)
最簡單的方法是用自帶的函數(當然,也可以在構建對象前就過濾好):
keep_feature <- nexprs(example_sce, byrow=TRUE) >= 4
example_sce <- example_sce[keep_feature,]
dim(example_sce)
## [1] 1753 40
第六步 探索不同實驗因素對表達量的影響
# 一般是要先標準化
example_sce <- normalize(example_sce)
plotExplanatoryVariables(example_sce)
結果中的每條線都表示一個影響因子,當然我們也可以選擇一部分
plotExplanatoryVariables(example_sce,
variables = c("total_features_by_counts", "total_counts",
"Mutation_Status", "Treatment", "Cell_Cycle"))
結果看到:因為是測試小數據的緣故,total_counts
和 total_features_by_counts
對基因表達變化差異貢獻很高(接近10%),真實數據中這兩個占比應該在1-5%之間
第七步 去除技術誤差
Scaling normalization
可選的有normalize
函數,官方還強烈推薦了 友包scran
的computeSumFactors
、computeSpikeFactors
函數
Batch correction
Unlike scaling biases, these are usually constant across all cells in a given batch but different for each gene.
可以用limma的removeBatchEffect
函數
library(limma)
batch <- rep(1:2, each=20)
corrected <- removeBatchEffect(logcounts(example_sce), block=batch)
assay(example_sce, "corrected_logcounts") <- corrected
另外還推薦了:scran
的mnnCorrect
函數(之前也介紹過:http://www.lxweimin.com/p/b7f6a5efed85)
好,上面的官網教程結束,下面繼續對scRNAseq這個包中的四組細胞類型進行scater操作
回到scRNA數據
首先載入數據
library(scRNAseq)
## ----- Load Example Data -----
data(fluidigm)
# 得到RSEM矩陣
assay(fluidigm) <- assays(fluidigm)$rsem_counts
ct <- floor(assays(fluidigm)$rsem_counts)
> ct[1:4,1:4]
SRR1275356 SRR1274090 SRR1275251 SRR1275287
A1BG 0 0 0 0
A1BG-AS1 0 0 0 0
A1CF 0 0 0 0
A2M 0 0 0 33
> table(rowSums(ct)==0)
FALSE TRUE
17096 9159
# 樣本注釋信息
pheno_data <- as.data.frame(colData(fluidigm))
# 然后做scater的數據
sce <- SingleCellExperiment(
assays = list(counts = ct),
colData = pheno_data
)
> sce
class: SingleCellExperiment
dim: 26255 130
metadata(0):
assays(1): counts
rownames(26255): A1BG A1BG-AS1 ... ZZEF1 ZZZ3
rowData names(0):
colnames(130): SRR1275356 SRR1274090 ... SRR1275366 SRR1275261
colData names(28): NREADS NALIGNED ... Cluster1 Cluster2
reducedDimNames(0):
spikeNames(0):
簡單質控
sce <- calculateQCMetrics(sce)
然后是過濾
基因層面
# 進行一個標準化
exprs(sce) <- log2(calculateCPM(sce) + 1)
genes <- rownames(rowData(sce))
genes[grepl('^MT-',genes)] # 檢測線粒體基因
genes[grepl('^ERCC-',genes)] # 檢測ERCC
# 假入有線粒體基因或ERCC,就可以加入feature control組中
sce <- calculateQCMetrics(sce,
feature_controls = list(ERCC = grep('^ERCC',genes)))
colnames(rowData(sce)) # 查看信息
# 只過濾那些在所有細胞都沒有表達的基因
keep_feature <- rowSums(exprs(sce) > 0) > 0
# table(keep_feature)
sce <- sce[keep_feature,]
# sce
細胞層面
# 細胞質控屬性非常多
colnames(colData(sce)) # 查看信息
可視化同上
學習SC3包
library(SC3) # BiocManager::install('SC3')
sce <- sc3_estimate_k(sce) # 預估亞群(24個)
metadata(sce)$sc3$k_estimation
rowData(sce)$feature_symbol <- rownames(rowData(sce))
# 接下來正式運行,kn參數表示的預估聚類數
# 我們這里自定義為4組(因為已知真正就是4組,實際上需要探索)
kn <- 4 # 還可以設置3、5看看結果
sc3_cluster <- "sc3_4_clusters"
Sys.time()
sce <- sc3(sce, ks = kn, biology = TRUE) # 運行會很慢
Sys.time()
# 最后進行可視化--比較先驗分類和SC3的聚類的一致性
sc3_plot_consensus(sce, k = kn, show_pdata = c("Biological_Condition",sc3_cluster))
# 最后進行可視化--表達量信息
sc3_plot_expression(sce, k = kn, show_pdata = c("Biological_Condition",sc3_cluster))
# 最后進行可視化--可能的marker基因
sc3_plot_markers(sce, k = kn, show_pdata = c("Biological_Condition",sc3_cluster))
# PCA上展示SC3的聚類結果
plotPCA(sce, colour_by = sc3_cluster )