單細(xì)胞轉(zhuǎn)錄組數(shù)據(jù)分析|| 隱藏在PC軸中的秘密

正常情況下婆芦,按照目前主流的單細(xì)胞數(shù)據(jù)分析教程蜂怎,是可以分析我們的數(shù)據(jù)的穆刻。但是,如果在分析過程中發(fā)現(xiàn)了不正常的現(xiàn)象杠步,比如氢伟,batch這個(gè)幽靈真的在腦海里盤旋不去,我們就要檢查batch的來源了幽歼。

Long long ago朵锣,在一個(gè)夜深人靜的夜晚,看著手里的單細(xì)胞數(shù)據(jù)甸私,幾度分析都沒有找到很好的落腳點(diǎn)诚些,還慘雜著若有若無的批次(batch)。到底該如何處理批次皇型,網(wǎng)上給出的方法幾乎都是參考bulk的方法來的诬烹,天知道這樣做是不是合適。我們必須找到batch的藏身之處弃鸦。本著if you can't see it , you can't stop it 的理念绞吁,所有看不到的效應(yīng)都不應(yīng)以莫須有的罪名給予去除。

論單細(xì)胞數(shù)據(jù)分析我們還是比較信任Seurat的唬格,這個(gè)2014就被開發(fā)來分析單細(xì)胞數(shù)據(jù)的R包家破。于是颜说,我們開始遍歷Rahul Satija(Seurat的主要作者之一)的文章,看看他是如何查看和處理單細(xì)胞batch的员舵。不僅遍歷他的文章摘要脑沿,還要讀文章的源碼。經(jīng)過一番努力马僻,我們找到一篇2017年預(yù)印2019年見刊NCB的文章:

文章摘要:

在脊椎動(dòng)物中,位于咽部中胚層心肌細(xì)胞和鰓狀頭部肌肉的多能祖細(xì)胞注服,心肺多能和頭部肌肉的命運(yùn)選擇仍然不清楚韭邓。在這里,我們使用單細(xì)胞基因組學(xué)在簡單的脊索動(dòng)物模型Ciona重建形成第一和第二心臟譜系和咽部肌肉前體的發(fā)育軌跡溶弟,并表征了心肺命運(yùn)選擇的分子基礎(chǔ)女淑。我們表明,F(xiàn)GF-MAPK信號維持多潛能并促進(jìn)咽部肌肉的命運(yùn)辜御,而信號終止允許部署一個(gè)泛心臟計(jì)劃鸭你,由第一和第二心臟譜系共享用以定義心臟同一性。在第二種心臟譜系中擒权,Tbx1/10-Dach通路積極地抑制第一種心臟譜系程序袱巨,調(diào)節(jié)以后跳動(dòng)心臟中的細(xì)胞多樣性。最后碳抄,Ciona和小鼠的跨物種比較揭示了脊索動(dòng)物的心咽網(wǎng)絡(luò)的深層進(jìn)化起源愉老。

文章設(shè)計(jì)與思路:

Early cardiopharyngeal development in Ciona, and sampling stages and established lineage tree. Cardiopharyngeal lineage cells are shown for only one side and known cell-type-specific marker genes are indicated. st., FABA stage55; hpf, hours post-fertilization; TVC, trunk ventral cell; STVC, second trunk ventral cell; FHP, first heart precursor; ASMF, atrial siphon muscle founder cells; SHP, second heart precursor; iASMP, inner atrial siphon muscle precursor; oASMP, outer atrial siphon muscle precursor; LoM, longitudinal muscles; QC, quality control. Dotted line: midline.

這篇文章用的是Seurat v1.2,代碼作者為Xiang Niu May 11, 2016 剖效,我們先來看一段去除batch的源碼嫉入。

4. Remove Contamination and Batch Effect
```{r,warning=FALSE,message=FALSE,tidy=TRUE}
# PCA on all the genes
hpfall=pca(hpfall,pc.genes = rownames(hpfall@data),do.print = F)
pcScree(hpfall,rownames(hpfall@data),10)
abline(h=0.5)
# Top 7 PCs are selected (PVE>0.5%)
# PC1
# Population of potential contaminated cell type
doHeatMap(hpfall,remove.key = T,slim.col.label = T,genes.use = pcTopGenes(hpfall,1) ,cells.use = pcTopCells(hpfall,1),col.use = col)
pca.plot(hpfall,1,2)
# PC2
# Batch effect due to library preparation, it separates hpf12/14/16 with hpf18/20
doHeatMap(hpfall,remove.key = T,slim.col.label = T,genes.use = pcTopGenes(hpfall,2),cells.use = pcTopCells(hpfall,2),col.use = col)
pca.plot(hpfall,1,2)
# PC3
# Mesenchymal contamination
doHeatMap(hpfall,remove.key = T,slim.col.label = T,genes.use = pcTopGenes(hpfall,3),cells.use = pcTopCells(hpfall,3),col.use = col)
pca.plot(hpfall,1,3)
feature.plot(hpfall,c("RTP4","TWIST1"),reduction.use = "pca",dim.2 = 3)

# PC4
# Heart vs Muscle split
doHeatMap(hpfall,remove.key = T,slim.col.label = T,genes.use = pcTopGenes(hpfall,4),cells.use = pcTopCells(hpfall,4),col.use = col)  
feature.plot(hpfall,c("NKX2-3","EBF1/2/3/4","TBX1/10","GATA4/5/6"),reduction.use = "pca",dim.2 = 4)
# PC5
# Another batch effect
doHeatMap(hpfall,remove.key = T,slim.col.label = T,genes.use = pcTopGenes(hpfall,5),cells.use = pcTopCells(hpfall,5),col.use = col) 
pca.plot(hpfall,1,5)
# PC6
# Saperation by heart vs muscle
doHeatMap(hpfall,remove.key = T,slim.col.label = T,genes.use = pcTopGenes(hpfall,6),cells.use = pcTopCells(hpfall,6),col.use = col) 
pca.plot(hpfall,1,6)
feature.plot(hpfall,c("NKX2-3","EBF1/2/3/4","TBX1/10","GATA4/5/6"),reduction.use = "pca",dim.2 = 6)

 PC7
# Batch effect marked hpf14
doHeatMap(hpfall,remove.key = T,slim.col.label = T,genes.use = pcTopGenes(hpfall,7),cells.use = pcTopCells(hpfall,7),col.use = col) 
pca.plot(hpfall,1,7)

我們看到作者在這里用doHeatMappca.plot查看了PVE>0.5%的七個(gè)PC軸的基因,并判斷出每個(gè)PC軸潛在的生物學(xué)意義璧尸,如PC5 作者寫道:Another batch effect咒林。然后,有batch的PCs用RegressOut回歸掉(這個(gè)函數(shù)在V3中放到了 ScaleData的參數(shù)vars.to.regress 中爷光,在R中?Seurat::ScaleData)垫竞。

# Remove batch effect
hpfall.remv1=RegressOut(hpfall,c("PC2","PC5","PC7"),do.scale = T)

這一波操作啟示我們,在去批次之前需要判斷批次的有無以及在哪里瞎颗。重要的是:

批次的直接反映是特定基因的表達(dá)件甥。

舉個(gè)例子,有八個(gè)單細(xì)胞小鼠數(shù)據(jù)雌雄各四例哼拔,而我們想看的不是雌雄之間的區(qū)別而是他們的共性引有,這時(shí)候數(shù)據(jù)表現(xiàn)為按雌雄分開了。檢查我們的PCs所表征的基因倦逐,發(fā)現(xiàn)某PC的基因都是和性別相關(guān)的譬正,這時(shí)候就可以回歸掉(或者去掉)這個(gè)PCs宫补。

這需要我們認(rèn)識這些基因,不認(rèn)識就需要做富集來看通路曾我。

下面我們用Seurat V3+ 來做一個(gè)發(fā)現(xiàn)PC軸秘密的演示粉怕,首先我們還是清出我們的R包和老朋友pbmc3k的數(shù)據(jù)集。

library(Seurat)
library(SeuratData)
pbmc3k.final 

An object of class Seurat 
13714 features across 2638 samples within 1 assay 
Active assay: RNA (13714 features, 2000 variable features)
 2 dimensional reductions calculated: pca, umap

在標(biāo)準(zhǔn)流程中抒巢,我們均一化之后就可以執(zhí)行ScaleData贫贝,但是一開始我們并不知道哪些變量需要vars.to.regress,所以我們使用默認(rèn)參數(shù)蛉谜。

# Seurat 標(biāo)準(zhǔn)流程稚晚,這里不需要運(yùn)行,因?yàn)閜bmc3k.final 已經(jīng)做過這些計(jì)算了型诚。
pbmc.counts <- Read10X(data.dir = "D:\\Users\\Administrator\\Desktop\\RStudio\\single_cell\\filtered_gene_bc_matrices\\hg19")
pbmc <- CreateSeuratObject(counts = pbmc.counts)
pbmc <- NormalizeData(object = pbmc)
pbmc <- FindVariableFeatures(object = pbmc)
pbmc <- ScaleData(object = pbmc)
pbmc <- RunPCA(object = pbmc)
pbmc <- FindNeighbors(object = pbmc)
pbmc <- FindClusters(object = pbmc)
pbmc <- RunUMAP(object = pbmc)

我們主要管關(guān)心PCs 的Loading值客燕。

 t(Loadings(object = pbmc3k.final[["pca"]])[1:5,1:5])
             PPBP         LYZ      S100A9        IGLL5        GNLY
PC_1  0.010990202  0.11623171  0.11541436 -0.007987473 -0.01523876
PC_2  0.011484260  0.01472515  0.01895146  0.054542385 -0.13375626
PC_3 -0.151760919 -0.01280613 -0.02368853  0.049015330  0.04101340
PC_4  0.104037367 -0.04414540 -0.05787777  0.066947217  0.06912322
PC_5  0.003299077  0.04990688  0.08538231  0.004603231  0.10455861
 # Set the feature loadings for a given DimReduc
 new.loadings <- Loadings(object = pbmc3k.final[["pca"]])
 new.loadings <- new.loadings + 0.01
 Loadings(object = pbmc3k.final[["pca"]]) <- new.loadings
 VizDimLoadings(pbmc3k.final,dims = 1:4)

早些時(shí)候,我們看到這個(gè)圖沒有什么感覺狰贯,就是一堆字母也搓,現(xiàn)在我們知道如果每個(gè)PC的基因大多是細(xì)胞類型的makergene,那么該P(yáng)C就是細(xì)胞類型特異的涵紊,肯定是要保留的了傍妒。比如這里的PC2,PC3 栖袋,PC4基本斷定是和B細(xì)胞相關(guān)的拍顷。

# Examine and visualize PCA results a few different ways
 print(pbmc3k.final[["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 

 DimPlot(pbmc3k.final, reduction = "pca",group.by = 'seurat_annotations') # group.by可以換成樣本分組

我們也看看PC熱圖的情況

#DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
DimHeatmap(pbmc3k.final, dims = 1:15, cells = 500, balanced = TRUE)

結(jié)合碎石圖,判斷納入多少PC(這里并沒有看基因)

 ElbowPlot(pbmc3k.final)

按照示例文章的做法塘幅,這里我們選擇了PCs1:10昔案,結(jié)合上面的基因情況,判斷這10個(gè)PCs哪些留下哪些去掉电媳。即可踏揣。

這里我們科普下pve的概念,PVE(有一種翻譯是:percent variance explained )按照這個(gè)概念我們在Seurat里面可以這樣計(jì)算:

(pbmc3k.final[["pca"]]@stdev^2/sum(pbmc3k.final[["pca"]]@stdev^2)) *100
 [1] 20.468928  8.209683  6.092213  5.709129  4.086683  2.631764  1.737523  1.536987  1.386379  1.367403  1.346245  1.299317  1.285963  1.254616  1.246295  1.238943
[17]  1.218781  1.215172  1.205959  1.202547  1.198533  1.195067  1.188333  1.181939  1.181202  1.177457  1.174989  1.168232  1.167059  1.161573  1.158020  1.148486
[33]  1.145992  1.144709  1.139288  1.139030  1.133048  1.129764  1.128323  1.124985  1.119834  1.116586  1.115314  1.111942  1.111581  1.105309  1.102191  1.100031
[49]  1.096533  1.094121

sum((pbmc3k.final[["pca"]]@stdev^2/sum(pbmc3k.final[["pca"]]@stdev^2)) *100 )
[1] 100

計(jì)算累計(jì)貢獻(xiàn)度

(cumsum((pbmc3k.final[["pca"]]@stdev^2/sum(pbmc3k.final[["pca"]]@stdev^2)) *100))

最后匾乓,我們可以在umap空間中可視化PC信息捞稿;

# Defining the information in the seurat object of interest
columns <- c(paste0("PC_", 1:16),
             "seurat_annotations",
             "UMAP_1", "UMAP_2")

# Extracting this data from the seurat object
pc_data <- FetchData(pbmc3k.final, 
                     vars = columns)


# Adding cluster label to center of cluster on UMAP
umap_label <- FetchData(pbmc3k.final, 
                        vars = c("seurat_annotations", "UMAP_1", "UMAP_2"))  %>%
  group_by(seurat_annotations) %>%
  summarise(x=mean(UMAP_1), y=mean(UMAP_2))

# Plotting a UMAP plot for each of the PCs
map(paste0("PC_", 1:16), function(pc){
  ggplot(pc_data, 
         aes(UMAP_1, UMAP_2)) +
    geom_point(aes_string(color=pc), 
               alpha = 0.7) +
    scale_color_gradient(guide = FALSE, 
                         low = "grey90", 
                         high = "blue")  +
    geom_text(data=umap_label, 
              aes(label=seurat_annotations, x, y)) +
    ggtitle(pc)+ theme_bw()
}) %>% 
  plot_grid(plotlist = .)

如果有樣本分組信息,自然是可以把這里的細(xì)胞類型換成分組信息了拼缝,開看哪些樣本在哪個(gè)PC中高亮娱局,進(jìn)而推斷其是不是特殊的batch,對應(yīng)的PC以及基因是否需要去掉(或回歸掉)咧七。

在節(jié)目的最后我們再次強(qiáng)調(diào)單細(xì)胞數(shù)據(jù)分析的非線性過程衰齐,許多時(shí)候,如果看不到就不能判斷是否需要做某個(gè)處理继阻,所以需要一個(gè)反饋的過程耻涛。在單細(xì)胞數(shù)據(jù)科學(xué)中PCA分析是屬于特征選擇的過程废酷,即,哪些特征哪來分析抹缕,這當(dāng)然是值得謹(jǐn)慎處理的澈蟆。單細(xì)胞數(shù)據(jù)分析的默認(rèn)參數(shù)(default parameters)時(shí)代已經(jīng)一去不復(fù)返了。


A single-cell transcriptional roadmap for cardiopharyngeal fate diversification
https://satijalab.org/people/
https://as.nyu.edu/content/nyu-as/as/faculty/rahul-satija.html
https://tem11010.github.io/Plotting-PCAs/
https://cmdlinetips.com/2019/04/introduction-to-pca-with-r-using-prcomp/
https://eranraviv.com/understanding-variance-explained-in-pca/
https://hbctraining.github.io/scRNA-seq/lessons/08_SC_clustering_quality_control.html
https://github.com/stevexniu/single-cell-ciona/blob/master/Preprocess.Rmd

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末卓研,一起剝皮案震驚了整個(gè)濱河市趴俘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鉴分,老刑警劉巖哮幢,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異志珍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)垛叨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進(jìn)店門伦糯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嗽元,你說我怎么就攤上這事敛纲。” “怎么了剂癌?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵淤翔,是天一觀的道長。 經(jīng)常有香客問我佩谷,道長旁壮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任谐檀,我火速辦了婚禮抡谐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘桐猬。我一直安慰自己麦撵,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布溃肪。 她就那樣靜靜地躺著免胃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪惫撰。 梳的紋絲不亂的頭發(fā)上羔沙,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天,我揣著相機(jī)與錄音润绎,去河邊找鬼撬碟。 笑死诞挨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的呢蛤。 我是一名探鬼主播惶傻,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼其障!你這毒婦竟也來了银室?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤励翼,失蹤者是張志新(化名)和其女友劉穎蜈敢,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汽抚,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抓狭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了造烁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片否过。...
    茶點(diǎn)故事閱讀 37,989評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖惭蟋,靈堂內(nèi)的尸體忽然破棺而出苗桂,到底是詐尸還是另有隱情,我是刑警寧澤告组,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布煤伟,位于F島的核電站,受9級特大地震影響木缝,放射性物質(zhì)發(fā)生泄漏便锨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一氨肌、第九天 我趴在偏房一處隱蔽的房頂上張望鸿秆。 院中可真熱鬧,春花似錦怎囚、人聲如沸卿叽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽考婴。三九已至,卻和暖如春催烘,著一層夾襖步出監(jiān)牢的瞬間沥阱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工伊群, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留考杉,地道東北人策精。 一個(gè)月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像崇棠,于是被迫代替她去往敵國和親咽袜。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評論 2 345