轉(zhuǎn)錄組分析進(jìn)階

這是我聽孟浩巍知乎LiveB站鯪魚不會(huì)飛視頻(轉(zhuǎn)錄組分析進(jìn)階課程)里的筆記哦~

本次知乎Live解決的問(wèn)題:

轉(zhuǎn)錄組的建庫(kù)與質(zhì)量控制

  • 人類基因組與轉(zhuǎn)錄組組成
  • 轉(zhuǎn)錄組的2種建庫(kù)策略
  • 轉(zhuǎn)錄組的分鏈建庫(kù)策略
  • 轉(zhuǎn)錄組測(cè)序應(yīng)用 single end 還是 pair end?
  • 建庫(kù)結(jié)果與測(cè)序結(jié)果的質(zhì)控策略

轉(zhuǎn)錄組的比對(duì)與定量策略

  • 常用比對(duì)策略介紹:bowtie, Tophat, STAR, HISAT
  • 選擇合適的參考基因組(hg19 / hg38)
  • 確定基因表達(dá)量的若干策略:Raw Count, RSEM, FPKM, RPKM, TPM
  • 基于FPKM的差異表達(dá)分析流程
  • 基于 Raw Count 的差異表達(dá)分析流程

上機(jī)操作部分

使用 Python 與 R 搭建基于 Raw Count 的分析流程

導(dǎo)言

轉(zhuǎn)錄組分析的核心是找差異
找不同實(shí)驗(yàn)條件下、不同處理下、不同情況下基因表達(dá)量的差異、可變剪切的差異、基因融合的差異......

  • 基因表達(dá)定量 ---> 差異表達(dá)基因(想要找差異表達(dá)基因那首先要確定基因的表達(dá)量)
  • 可變剪切定量 ---> 可變剪切差異

所以說(shuō)高通量分析轉(zhuǎn)錄組的核心就是選擇一種更準(zhǔn)確更快的方法對(duì)基因表達(dá)量進(jìn)行定量從而找出差異基因。

測(cè)序之前要先建庫(kù),所以后續(xù)我們會(huì)討論建庫(kù)的方案。

拿到測(cè)序數(shù)據(jù)后,第一步先做質(zhì)控;第二步把質(zhì)控后的序列回帖到參考基因組,這步就需要考慮回帖的時(shí)候用什么軟件什么策略更準(zhǔn)確;第三步,回帖到參考基因組后怎樣衡量基因表達(dá)量是高還是低;第四步,找可變剪切找差異表達(dá)基因。


中心法則

在細(xì)胞運(yùn)行過(guò)程當(dāng)中RNA起到非常重要的作用,當(dāng)然最主要的研究最多的是RNA的信息傳遞的作用。

我們的轉(zhuǎn)錄組分析其實(shí)就是分析這些RNA,其中最主要的是分析mRNA,但是除了mRNA之外的少量的其他種類RNA還有很多未知,更加值得進(jìn)行進(jìn)一步的挖掘。當(dāng)然在眾多種類的RNA中我們的mRNA是一個(gè)典型的代表,所以在進(jìn)行轉(zhuǎn)錄組分析進(jìn)階的時(shí)候我們以mRNA為例。

人類基因組與轉(zhuǎn)錄組組成

在認(rèn)識(shí)轉(zhuǎn)錄組之前首先要認(rèn)識(shí)一下基因組,因?yàn)橹行姆▌t告訴我們RNA是來(lái)自于DNA的:

  • 人類有46條染色體:22 * 2 + X + Y
  • 人類基因組有兩部分組成:細(xì)胞核基因組 和 線粒體基因組
  • 我們常說(shuō)的基因組是細(xì)胞核基因組大概有3.1Gb,線粒體基因組有16.6Kb
    Human genome :3.1 Gb
    chrM : 16.6Kb
  • 常用的基因有27000左右個(gè)(兩萬(wàn)七千個(gè)常用的基因)
    其中編碼蛋白質(zhì)的有兩萬(wàn)個(gè)左右;能轉(zhuǎn)錄成有功能的RNA的基因有七千個(gè)左右
    20000個(gè)左右蛋白基因
    7000個(gè)左右RNA gene
  • 人類線粒體基因組中總共有37個(gè)基因,其中 22個(gè)tRNA基因;2個(gè)rRNA基因;13個(gè)編碼蛋白的基因

RNA的種類與目前注釋情況

RNA的種類與目前注釋情況

左邊這個(gè)餅圖基本上就覆蓋了所有注釋好的RNA,只要做小RNA的分析基本上是不可能逃過(guò)這些數(shù)量的,這要超過(guò)這些數(shù)量就有預(yù)測(cè)的成分了。

我們知道RNA有很多種類,每種RNA的含量大概是多少呢?下圖的文獻(xiàn)給我們做了非常好的總結(jié)。

rRNA也就是核糖體RNA占80%-90%,剩下的10%-20%絕大多數(shù)是tRNA,真正的我們所專注的 mRNA 只占5%左右。

RNA在細(xì)胞中的絕對(duì)數(shù)量

我們提取出的RNA絕大部分是rRNA但我們真正關(guān)注的卻是mRNA,此時(shí)我們應(yīng)該富集,所以說(shuō)轉(zhuǎn)錄組建庫(kù)的核心就是將目標(biāo)RNA比例提高。(常見的就是富集mRNA)

轉(zhuǎn)錄組建庫(kù)的核心

  • 轉(zhuǎn)錄組建庫(kù)的核心是把目標(biāo)RNA(最常見的是mRNA)的比例提高,然后進(jìn)行擴(kuò)增,使其濃度達(dá)到可以建庫(kù)測(cè)序的要求。
  • 單細(xì)胞轉(zhuǎn)錄組測(cè)序的核心,就是通過(guò)特殊的擴(kuò)增方法,只擴(kuò)增mRNA而不擴(kuò)增其它種類的RNA,然后進(jìn)行測(cè)序。

轉(zhuǎn)錄組的2種建庫(kù)策略

  • 第一種是正選擇 —— polyA positive
  • 第二種是負(fù)選擇 —— rRNA minus

RNA-Seq的建庫(kù)方法—怎樣富集mRNA

  • polyA positive 建庫(kù)方法
    人的成熟的mRNA含有polyA尾巴,用Oligo dT(帶有一段T序列的磁珠)標(biāo)簽去拉polyA尾巴,就會(huì)把mRNA從眾多種類的RNA中拉出來(lái),這種富集mRNA的方法就是polyA positive 建庫(kù)方法。

  • rRNA minus 建庫(kù)方法
    我們知道細(xì)胞中rRNA的含量最多(占到 80%-90%),那我們就想辦法去除掉建庫(kù)中最大的干擾因素rRNA,這種富集mRNA的方法就是 rRNA minus 建庫(kù)方法。

接下來(lái)我們分別對(duì)這兩種建庫(kù)方法做詳細(xì)介紹:

polyA positive 建庫(kù)方法


成熟的mRNA都有polyA尾巴,我們先用Oligo dT(帶有一段T序列的磁珠)標(biāo)簽去識(shí)別polyA尾巴從而將mRNA富集出來(lái),然后用 random 的 primer 對(duì)它進(jìn)行擴(kuò)增,此時(shí)我們就拿到了第一條鏈 是一條RNA、DNA雜合體,我們?cè)儆?random 的 primer 對(duì)第二條鏈進(jìn)行擴(kuò)增這時(shí)我們得到一個(gè)DNA和DNA的結(jié)構(gòu),這時(shí)我們?cè)儆媚┒诵迯?fù)酶把它補(bǔ)平為平末端然后在它 3' 末端加一個(gè)A,加完A后相當(dāng)于把平末端變成一個(gè)黏性末端,之后加上adapter,就可以上機(jī)進(jìn)行測(cè)序了。

rRNA minus 建庫(kù)方法


第一步還是提出 total 的 RNA,我們有18S、28S、5.8S等這些不同種類的 rRNA 的標(biāo)簽,它特異性的結(jié)合 rRNA 的序列,這些標(biāo)簽上都有抗體方便我們特異性的識(shí)別并把它們?nèi)〕觯藭r(shí)我們就去除了細(xì)胞中含量最多的RNA種類 — rRNA,一般為了保險(xiǎn)起見,需要進(jìn)行兩次rRNA minus的去除,然后對(duì)剩下的RNA進(jìn)行打斷和建庫(kù)。

兩種建庫(kù)方法的比較

第一種方法 — polyA positive 只拿成熟的mRNA進(jìn)行建庫(kù),第二種方法 — rRNA minus 除了有不成熟的 mRNA 還有一些 tRNA、microRNA 等等

如果你只想研究成熟的mRNA那肯定選第一種建庫(kù)策略,如果想研究一些其他種類的RNA或者RNA降解的一些問(wèn)題,那必須選擇第二種建庫(kù)策略。

從兩種建庫(kù)策略我們可以看出,第二種建庫(kù)策略涵蓋的信息多,那為什么我們不都選擇第二種呢?因?yàn)椋旱谝唬诙N策略需要更多的測(cè)序量;第二,第二種建庫(kù)策略更貴,貴大概兩倍左右。


比較兩種建庫(kù)策略測(cè)出的基因表達(dá)量

這篇paper對(duì)比了兩種建庫(kù)方法的基因表達(dá)量差異,發(fā)現(xiàn)了 rRNA minus 建庫(kù)方法其原始數(shù)據(jù)更高一些,這也好理解,因?yàn)閞RNA minus 建庫(kù)時(shí)除了成熟的mRNA之外還有不成熟的mRNA(mRNA前體)和少量其他種類的RNA,所以最后測(cè)出的基因表達(dá)量整體比例會(huì)相對(duì)高一些。

兩種建庫(kù)策略比對(duì)到基因組后的差異

比對(duì)到參考基因組上,這兩種比對(duì)策略會(huì)有什么不同呢?看這篇文章里面的圖:



第一列和第三列是來(lái)自不同數(shù)據(jù)集,但用同一種建庫(kù)策略(polyA positive)的結(jié)果,差別不大;第二列和第四列使用的是 rRNA minus 建庫(kù)策略。
淺藍(lán)色:Coding+UTR 表示能翻譯成蛋白的 region
淺黃色:Intronic 內(nèi)含子區(qū)
淺粉色:Intergenic 基因間 region
淺紫色:Unaligned 不確定的 region

第一種建庫(kù)策略 (polyA positive) 即第一列和第三列中大部分的reads( 62.3%/75.7%)落在了Coding region,即能翻譯成蛋白的區(qū)域;
第二種建庫(kù)策略 (rRNA minus)即第二列和第四列中占比較多的是 Intergenic region以及 Intronic region,而在第一種建庫(kù)策略中落在這兩個(gè)區(qū)域的reads占比都很少,這是為什么呢?因?yàn)閞RNA minus建庫(kù)方法可以獲得比較多的沒有被剪切掉的Introne(內(nèi)含子)的信息,用它來(lái)非常好的衡量 alternative splicing (可變剪切)。

整個(gè)基因組中能翻譯成蛋白或有特定功能的序列我們叫做基因,基因在整個(gè)基因組中占比不超過(guò)5%,但是有一點(diǎn)我們必須清楚的知道,基因組絕大部分是可以被轉(zhuǎn)錄的只是除了那5%以外大部分序列并不行使功能,這就是為什么在使用rRNA minus建庫(kù)的時(shí)候會(huì)有大部分的reads回帖到了 Intergenic region 即基因間區(qū)。

鏈特異性的轉(zhuǎn)錄組分析

在講鏈特異性轉(zhuǎn)錄組分析之前回憶一下,之前是怎么建的庫(kù),以 polyA positive 為例。首先把帶有polyA尾巴的mRNA富集出來(lái),然后直接打斷,再用random primer將mRNA進(jìn)行反轉(zhuǎn)錄得到RNA、DNA雜合體,我們?cè)儆?random 的 primer 對(duì)第二條鏈進(jìn)行擴(kuò)增這時(shí)我們得到DNA和DNA的結(jié)構(gòu),當(dāng)形成雙鏈DNA的時(shí)候就丟失要傳遞的信息是來(lái)自于正鏈還是來(lái)自于反鏈?也就是在進(jìn)行反轉(zhuǎn)錄的時(shí)候沒有方向性使用的都是random primer,這就是我們平時(shí)所使用的鏈非特異性的測(cè)序,我們平時(shí)所測(cè)序的99%都是鏈非特異性的。

鏈非特異性測(cè)序會(huì)存在哪些問(wèn)題呢?

我們?cè)诨蚪M分析的時(shí)候,特別是人類基因組,有一些基因是有overlap的,而且絕大多數(shù)的基因在轉(zhuǎn)錄的時(shí)候會(huì)出現(xiàn)偏差:比如有一段基因在正鏈在轉(zhuǎn)錄的時(shí)候不一定就老老實(shí)實(shí)的按照正鏈去轉(zhuǎn)錄,也會(huì)往反鏈轉(zhuǎn)錄一定的距離,這就會(huì)形成一些干擾。

解決這些干擾我們要使用鏈特異性的建庫(kù)方法,鏈特異性建庫(kù)方法最常用的是如圖這三種,這三種中最常用的是中間那一種:


分鏈建庫(kù)策略

中間這種建庫(kù)方法是基于dUTP的方法,首先不管用哪種方法進(jìn)行富集,我們先得到了目標(biāo)RNA(通常是mRNA),拿到RNA之后我們先用 random primer 進(jìn)行反轉(zhuǎn),我們?cè)诤铣傻诙l鏈的時(shí)候插入了U,我們知道DNA上是沒有U的,這里我們?nèi)藶榈慕o它插入U(xiǎn),所以說(shuō)我們合成的第二條鏈肯定帶有U。它肯定來(lái)自于random primer 的轉(zhuǎn)錄而不是來(lái)自于最原始的那一條鏈,然后用專門能去掉U的酶,這種酶可以把含U的那條鏈全部切碎,這樣的話就只剩下第一條鏈了,也就是反轉(zhuǎn)錄時(shí)的第一條最原始的鏈,我們用這些鏈進(jìn)行建庫(kù)。這時(shí)候左邊的 adapter 和右邊的 adapter 是有方向性的了,我們把這個(gè)信息保留下來(lái),這樣的話在進(jìn)行建庫(kù)測(cè)序的時(shí)候我們就可以知道它到底是來(lái)自于基因組的正鏈還是來(lái)自于基因組的負(fù)鏈。我們就通過(guò)這種方法解決了鏈的特異性的問(wèn)題。當(dāng)一個(gè)基因組正鏈也有基因反鏈也有基因的時(shí)候,某條序列只帖到反鏈沒帖到正鏈,我們就可以說(shuō)正鏈基因沒有轉(zhuǎn)錄或者是轉(zhuǎn)錄水平非常低以至于檢測(cè)不到。

我們舉個(gè)例子:


分鏈建庫(kù)策略的優(yōu)勢(shì)

ICAM4基因有001/002/003這三種transcript(轉(zhuǎn)錄本),它們是分布在正鏈的,它的反鏈還有一個(gè)基因叫做CTD,它在負(fù)鏈,如果不分鏈的情況下比對(duì)到正鏈的reads我們用藍(lán)色表示,比對(duì)到負(fù)鏈的reads我們用綠色表示。不分鏈時(shí)(Nonstranded)就會(huì)發(fā)現(xiàn)結(jié)果既有藍(lán)色又有綠色,這時(shí)我們不能說(shuō)CTD基因不表達(dá)。

同樣的樣本我們用分鏈建庫(kù)方法(Stranded)進(jìn)行測(cè)序時(shí)就會(huì)發(fā)現(xiàn),所有的序列全部回帖到了負(fù)鏈上,證明ICAM基因不表達(dá)。

單端測(cè)序(SE) VS 雙端測(cè)序(PE)

測(cè)序的時(shí)候是選擇單端測(cè)序還是雙端測(cè)序?

答:能選擇雙端測(cè)序的時(shí)候一定選雙端測(cè)序。

SE or PE

思考這樣一個(gè)問(wèn)題:人的基因組大概有3G,如果用 4^n 來(lái)覆蓋大概有多長(zhǎng)的序列能夠unique map到基因組上呢?

大概是28-29bp,所有說(shuō)那些短于28/29bp的序列,比對(duì)到參考基因組時(shí)會(huì)有好幾個(gè)結(jié)果,也就是說(shuō)這些短序列在基因組上找位置的時(shí)候能找到好多個(gè)。mapping到這么多位置上以至于我們不知道到底應(yīng)該是哪個(gè),這時(shí)候就應(yīng)該延長(zhǎng)測(cè)序長(zhǎng)度。

illumina二代測(cè)序已經(jīng)可以測(cè)到150bp,但是150bp map到一端還是不夠的,所以我們?cè)诮◣?kù)的時(shí)候打斷成的片段盡量長(zhǎng)一些,打斷到500bp進(jìn)行雙端測(cè)序,上游也就是5' 端可以測(cè)到150bp,下游也就是reads2也可以測(cè)150bp,這樣的話中間還空了200bp(500-150*2=200),在回帖到參考基因組上時(shí),我們的reads1回帖到一個(gè)位置,reads2也回帖到一個(gè)位置,當(dāng)這兩個(gè)位置離的特別近大概在100/200bp的時(shí)候,我們就可以確定這是一個(gè)合理的回帖。這樣我們就用了500bp的信息確定了這對(duì)reads 回帖到參考基因組的具體位置,也就是說(shuō)用500bp的信息基本上實(shí)現(xiàn)了unique map。

所以說(shuō)建議用雙端測(cè)序(PE),這樣可以使序列能夠更好更準(zhǔn)確的回帖到參考基因組上,基本上能夠保證80%都是unique map。

但在測(cè)小RNA時(shí)是例外,比如microRNA,成熟的microRNA只有21-22bp,雙端測(cè)150bp純屬浪費(fèi),單端測(cè)50bp就可以實(shí)現(xiàn)unique map。再比如最長(zhǎng)的snoRNA也就300-400bp左右;成熟的tRNA 只有70bp; 成熟的snRNA也就70-80bp,所以說(shuō)測(cè)這些小RNA(miRNA)的時(shí)候都不用雙端150bp。

總結(jié)一下,針對(duì)mRNA建庫(kù)無(wú)論是 polyA positive 還是 rRNA minus 也不管分不分鏈,一定要使用雙端測(cè)序,小RNA建庫(kù)的話要根據(jù)分析的內(nèi)容確定是雙端測(cè)序還是單端測(cè)序。

衡量提取RNA和建庫(kù)的質(zhì)量

人體中絕大部分的RNA都是rRNA(核糖體RNA)占90%左右,人體的核糖體RNA主要分成兩類,第一類,主要來(lái)源于細(xì)胞核,是根據(jù)細(xì)胞核里面染色體的序列轉(zhuǎn)錄并加工的;第二類,來(lái)自于線粒體中的兩個(gè)rRNA基因轉(zhuǎn)錄而來(lái)的。針對(duì)第一類的rRNA主要分成:5.8S、5S、28S和18S。5.8S、28S和18S它們的量基本上是一致的,5S的量跟它們不太一樣,因?yàn)?S會(huì)在整個(gè)基因組上散落分布。另外一種來(lái)自于線粒體上的有5S、23S和16S,整個(gè)rRNA最主要的、占比最多的是來(lái)源于細(xì)胞核的那四種(5.8S、5S、28S和18S)。

rRNA的種類

提取完 total RNA 要做一個(gè)電泳圖,來(lái)判斷提取的是否成功。
total RNA 提取的電泳圖

這個(gè)儀器在做出total RNA電泳圖的同時(shí)還會(huì)計(jì)算出一個(gè)值來(lái),通過(guò)這個(gè)值也能確定RNA提取的好不好。空氣當(dāng)中到處都是RNA酶,所以在提取RNA的時(shí)候,RNA特別容易降解,如果RNA講解特別嚴(yán)重的話后面的流程就不用走了,測(cè)序結(jié)果也不準(zhǔn)確。
跑膠的儀器可以測(cè)出total RNA提取的質(zhì)控標(biāo)準(zhǔn) RIN(RNA Integrity Number)
RIN這個(gè)值就用來(lái)衡量total RNA提取的質(zhì)量。RIN 10就代表完全沒有降級(jí),0就代表全部降解了。

total RNA提取的質(zhì)控標(biāo)準(zhǔn) RIN(RNA Integrity Number)

如上圖所示,我們可以看到RIN 分別為 10、6、3、2 的圖經(jīng)驗(yàn)值告訴我們RIN 在7.5以上時(shí),說(shuō)明RNA提取的質(zhì)量已經(jīng)很好了。如果使用 rRNA minus這種建庫(kù)策略RIN 值會(huì)稍微低一些,但是不能低于6.5;如果想做基因表達(dá)的分析的話RIN 值最低不能低于6,因?yàn)橛幸恍┎∪说臉颖竞苷滟F,只能提一次,無(wú)法做平行那沒辦法只能硬著頭皮往下做;如果是細(xì)胞類的實(shí)驗(yàn),比如做植物類的這種可以多次重復(fù)的實(shí)驗(yàn),盡量把RIN 值提高到7.5以上。RIN 值在7.5及以上是可以做可變剪切分析的,如果達(dá)不到7.5是沒辦法做可變剪切的。

下面我們學(xué)習(xí)一下如何看這張電泳儀輸出的total RNA提取的質(zhì)量圖。


學(xué)會(huì)看RIN(RNA Integrity Number)圖

我們可以從上圖中看到5S region 、18S region 、28S region 的peak,這些峰如果像marker的峰一樣shark的話就比較好。

轉(zhuǎn)錄組的比對(duì)與定量策略

主要講解拿到序列后怎樣比對(duì)、怎樣選擇合適的參考基因組、用哪種參數(shù)定表達(dá)量?

怎樣將提取來(lái)的RNA序列回帖到參考基因組,也就是怎樣確定該RNA來(lái)源于哪個(gè)基因,也就是怎樣進(jìn)行轉(zhuǎn)錄組的mapping。
只討論mRNA的情況下,一般來(lái)說(shuō)有兩種思路:

  • 把測(cè)序的結(jié)果mapping到成熟的mRNA參考序列上;
    優(yōu)點(diǎn):不用處理可變剪切的問(wèn)題;
    缺點(diǎn):不能發(fā)現(xiàn)新的轉(zhuǎn)錄本
  • 把測(cè)序結(jié)果mapping到參考基因組序列上;
    優(yōu)點(diǎn):可以發(fā)現(xiàn)新的轉(zhuǎn)錄本,可以進(jìn)行isoform層次的定量;
    缺點(diǎn):不能使用之前DNA mapping軟件

一個(gè)基因有不同的isoform,不同的isoform的量是可以定下來(lái)的。
DNA mapping軟件在mapping的時(shí)候沒有 junction 的問(wèn)題,只有indel、insertion、deletion,所以選擇第二種比對(duì)策略需要新的mapping軟件。

二代測(cè)序最實(shí)用的mapping算法是BWT算法,基于BWT算法的mapping軟件:BWA、BWA-MEM、Bowtie、Bowtie2 ... ...
但是上述軟件最大的問(wèn)題是:針對(duì)DNA比對(duì)設(shè)計(jì);完全沒有考慮可變剪切的問(wèn)題。
不能直接用于RNA的mapping

什么是可變剪切?

RNA需要面臨的可變剪切問(wèn)題

中心法則是從DNA到RNA,RNA到蛋白質(zhì),真實(shí)情況是在真核細(xì)胞里面,DNA轉(zhuǎn)錄成RNA時(shí)并不能全部轉(zhuǎn)錄成有用的mRNA,就會(huì)分成Exon(外顯子)和 intron(內(nèi)含子),成熟的mRNA都是由Exon(外顯子)組成的,如圖Exon1/2/3/4/5可以拼出一個(gè)成熟的mRNA;Exon1/2/4/5也可以拼出一個(gè)成熟的mRNA;Exon1/2/3/5也可以拼出一個(gè)成熟的mRNA,這三個(gè)成熟的mRNA分別可以翻譯成對(duì)應(yīng)的proteinA、proteinB、proteinC,但它們都是來(lái)自于同一個(gè)基因,對(duì)于這種來(lái)自同一個(gè)區(qū)域經(jīng)過(guò)不同的剪切形成不同的mRNA最后翻譯成不同的蛋白質(zhì)這種就叫做不同的isoform,這種來(lái)自于同一個(gè)基因形成的三種不同的mRNA,我們叫做三種不同的轉(zhuǎn)錄本但是它們都是來(lái)自同一種基因。

常見的5種可變剪切形式

在RNA比對(duì)的時(shí)候如果需要考慮可變剪切的問(wèn)題,也就是說(shuō)一條reads有可能來(lái)自于緊挨著的 Exon1、Exon2, 但是在回帖到基因組的時(shí)候 Exon1 和 Exon2 可能離的特別遠(yuǎn)中間會(huì)跨一個(gè)很大的junction,這種情況下怎么辦呢?這個(gè)時(shí)候就需要這3種比對(duì)策略:


RNA的3種比對(duì)策略

第一種比對(duì)策略是:Exon-first approach
基因組上哪些地方是Exon(外顯子)哪些地方是 intron(內(nèi)含子)我們是知道的。
把RNA序列完整的回帖到參考基因組上,能回帖上的就先回帖上,回帖不上的就按照一定的規(guī)則拆開,拆開后再分別去回帖,比如我們拆成兩個(gè)部分一個(gè)回帖到了A位置,一個(gè)回帖到了B位置,A、B只要離的不太遠(yuǎn)且中間正好是一個(gè)intron(內(nèi)含子)我們就認(rèn)為這是一個(gè)合理的mapping。這種RNA比對(duì)方法就叫做Exon-first approach。

第二種比對(duì)策略是:Seed-extend approach
先把序列切的特別碎,這樣每一段序列都相當(dāng)于一個(gè)小種子(Seed),這種小種子在回帖在基因組時(shí)會(huì)map到非常非常多的位置,把小種子能map到的所有位置都找出來(lái),對(duì)比Exon的樣子把這些小序列能連在一起的連在一起,連不到一起的就認(rèn)為是intron(內(nèi)含子),這種RNA比對(duì)方法就叫做Seed-extend approach。

第三種比對(duì)策略是:Potential Limitation of exon-first approach
有點(diǎn)像第一種比對(duì)策略的改進(jìn)版,在比對(duì)的時(shí)候一條序列如果它既能直接比對(duì)到基因組上,又能拆開之后比對(duì)到基因組上,比如,有一條reads正好能完全匹配到基因組的A位置,但是把如果把這條序列中間拆開一下,在中間有一個(gè)intron(內(nèi)含子)的情況下卻比對(duì)到了B位置,這種比對(duì)方法可以根據(jù)具體的需求選擇是同時(shí)保留這兩種情況,還是保留第一種或者保留第二種。

目前RNA-Seq的比對(duì)軟件都是這三種比對(duì)策略當(dāng)中的一種。

Tophat使用了第一種比對(duì)策略:

  • 比對(duì)過(guò)程調(diào)用了Bowtie;
  • 先比對(duì)能比對(duì)上的reads;
  • 比對(duì)不上的reads根據(jù)可變剪切的方式拆開再比對(duì);
  • 最大的問(wèn)題是,處理不好假基因(pseudogene)的問(wèn)題


    Tophat使用了第一種比對(duì)策略

假基因(pseudogene)怎么來(lái)的呢?
正常情況下是DNA轉(zhuǎn)錄成RNA,RNA的Exon(外顯子)再連到一起,intron(內(nèi)含子)去掉,但是細(xì)胞里存在這樣一個(gè)通路,可以把mRNA再插入到基因組上的一個(gè)位置,形成一個(gè)假基因(pseudogene),假基因(pseudogene)一般來(lái)說(shuō)是不表達(dá)的,當(dāng)A基因有一個(gè)假基因的時(shí)候我們叫 A' ,它的序列相當(dāng)于A基因把所有Exon(外顯子)都拼到一起了,這時(shí)候我有一條序列正好跨Exon(外顯子)的junction,那么比對(duì)軟件就會(huì)選在 A' 位置可以不用打開一個(gè)junction,直接就能比對(duì)到這兒,在基因A這個(gè)位置必須開一個(gè)intron(內(nèi)含子)的junction才能比對(duì)到這兒,這個(gè)時(shí)候比對(duì)軟件就可以很自然的把這條序列比對(duì)到A' 這個(gè)位置而不是A這個(gè)位置,這就是假基因所帶來(lái)的問(wèn)題。

Tophat2 主要改進(jìn)的2個(gè)問(wèn)題:

Tophat2 主要改進(jìn)的2個(gè)問(wèn)題

Tophat2比對(duì)介紹

(1)是比對(duì)到轉(zhuǎn)錄組,這不重點(diǎn)介紹,因?yàn)檗D(zhuǎn)錄組不是一個(gè)很復(fù)雜的問(wèn)題,直接用bowtie比對(duì)也可以。
假如說(shuō)有一條序列應(yīng)該map到基因組,這該怎么實(shí)現(xiàn)的呢?
我們先看spliced alignment(拼接比對(duì)),首先根據(jù)Alternative splicing(可變剪切)的 site 進(jìn)行切分,切分完后再去比對(duì)這個(gè)過(guò)程分成了3-1、3-2、3-3、3-4、3-5這幾種情況;
當(dāng)遇到假基因(pseudogene)時(shí)會(huì)自動(dòng)判斷,然后根據(jù)權(quán)重分析是開一個(gè)junction,還是直接比對(duì)到參基因組,這樣就通過(guò)權(quán)重考慮解決了假基因的問(wèn)題;
另一個(gè)問(wèn)題是,當(dāng)intron(內(nèi)含子)有一小段和序列延伸出來(lái)那部分完全匹配上的話怎么辦?
這種時(shí)候能開junction就盡量開junction,這樣比對(duì)的整體效果會(huì)好很多。

整體來(lái)說(shuō),Tophat2比對(duì)的效果還是不錯(cuò)的,但是有一個(gè)最大得到問(wèn)題就是占用資源太多,而且比對(duì)的速度太慢,因?yàn)樗诒葘?duì)的時(shí)候存在一個(gè)調(diào)用的過(guò)程 —— Tophat調(diào)用的是bowtie;Tophat2調(diào)用的是bowtie2

所以說(shuō),同一伙兒人又搞了一個(gè)HISAT軟件,它主要是一個(gè)Tophat2升級(jí)的版本提高了index的構(gòu)建方式,從而達(dá)到占用資源小,比對(duì)速度快的目的。在進(jìn)行轉(zhuǎn)錄組分析時(shí)推薦使用HISAT軟件進(jìn)行比對(duì)

還有一個(gè)常用的比對(duì)軟件是STAR,它的優(yōu)勢(shì)是快,缺點(diǎn)是占用內(nèi)存比較大,我們知道人類基因組一共才有3G,但STAR在mapping的時(shí)候需要28-32G的內(nèi)存。

STAR軟件的比對(duì)策略

使用的是上面介紹的第二種比對(duì)策略

  • STAR的優(yōu)勢(shì)在于快,能夠快速mapping;
  • 缺點(diǎn)在于占用內(nèi)存巨大,human的mapping需要28-32G的內(nèi)存


    STAR軟件的比對(duì)策略

    為了能夠快速mapping,STAR軟件把全部的seed提前做好了,index會(huì)提前讀進(jìn)去,所以說(shuō)內(nèi)存占用非常大。

許多比對(duì)軟件,比如:Tophat、Tophat2、HISAT 它們的核心算法都是BWT算法

BWT的算法推導(dǎo)與核心原理:孟浩巍知乎文章鏈接

RPKM VS FPKM

先理解一下所謂的 raw count 是什么?就是樣本中比對(duì)到某個(gè)基因的 reads count
比如某個(gè)測(cè)序的序列比對(duì)到基因的Exon(外顯子)上,
樣本一中 a基因比對(duì)上了1000條reads,b基因比對(duì)上了2000條reads
樣本二中 a基因比對(duì)到了2000條reads,b基因比對(duì)到了4000條reads
這時(shí),是否就可以認(rèn)為:
1、樣本內(nèi)比較,b基因的表達(dá)量就比 a 基因高
2、樣本間比較,a/b兩個(gè)基因的表達(dá)量樣本二比樣本一高出兩倍
答案肯定是不行的

我們看下面這張圖,有四個(gè)基因分別是1/2/3/4:


如果我們只單單看 reads count,那很明顯,1/3基因表達(dá)量較低,2/4基因表達(dá)量較高。4號(hào)基因和2號(hào)基因有同樣的基因map到,但是轉(zhuǎn)錄本的長(zhǎng)度不一樣,所以需要先矯正轉(zhuǎn)錄本長(zhǎng)度;樣本間比較的話也是需要矯正的,樣本一 測(cè)了1兆reads,樣本二 測(cè)了10兆reads ,那樣本二的基因表達(dá)量就會(huì)比樣本一的高,綜上,我們需要對(duì)我們的 raw count 進(jìn)行 normalizanormaliza 最重要的兩個(gè)因素,一個(gè)是轉(zhuǎn)錄本的長(zhǎng)度(或者叫Exon(外顯子)的長(zhǎng)度);另一個(gè)就是測(cè)序量

RPKM / FPKM 是一對(duì)兒概念


RPKM翻譯成人話就是說(shuō),每測(cè)1兆reads,在基因a上平均每1k的Exon(外顯子)有幾條reads map到這里。
FPKM里的F是指 Fragment ,只有雙端測(cè)序才有Fragment ,雙端測(cè)序中一對(duì)叫一個(gè)Fragment ,F(xiàn)PKM翻譯成人話就是每測(cè)1兆reads pair 基因a的位置上,平均1k的Exon(外顯子)上map回來(lái)多少個(gè)Fragment

所以說(shuō)針對(duì)illumina二代測(cè)序 pair-end(雙末端) 的數(shù)據(jù),F(xiàn)PKM是該基因RPKM數(shù)值的二分之一,換句話說(shuō)就是,RPKM = FPKM * 2

RPKM / FPKM就相當(dāng)于對(duì)測(cè)序量和基因Exon(外顯子)的長(zhǎng)度進(jìn)行了矯正。

TPM

TPM中T指的是transcript(轉(zhuǎn)錄本),翻譯成人話就是每測(cè)1兆reads,每一條轉(zhuǎn)錄本上有多上條reads map上,相當(dāng)于FPKM的小修小改。

在計(jì)算FPKM的時(shí),比如有兩個(gè)樣本測(cè)序量不一樣那不同基因的表達(dá)量有可以一樣也有可能不一樣,但FPKM的總體加和往往是不一樣的,這就會(huì)讓我們覺著在比對(duì)的時(shí)候會(huì)出現(xiàn)問(wèn)題,TPM就是為了應(yīng)對(duì)這樣的問(wèn)題而出現(xiàn)的,比如說(shuō)我們算基因 i 的TPM,根據(jù)公式我們首先必須算它的FPKM,它的FPKM占整個(gè)基因組的FPKM的百分之多少再乘以 10^6 就是TPM了,所以說(shuō)TPM的本質(zhì)是一個(gè)百分?jǐn)?shù),一個(gè)RNA-Seq的TPM一定是10^6 ,TPM的優(yōu)勢(shì)在于它可以很好的衡量樣本之間表達(dá)量差異的情況,因?yàn)樗颜麄€(gè)樣本進(jìn)行normaliza 了,保證了各樣本TPM的加和是一致的是10^6,也就是這樣的原因TPM得到了越來(lái)越多的推崇。

RSEM

RSEM主要是用了機(jī)器學(xué)習(xí)的辦法來(lái)估基因的 reads count 有多少,RSEM數(shù)值上相當(dāng)于對(duì)測(cè)序量和基因Exon(外顯子)的長(zhǎng)度進(jìn)行了矯正,與傳統(tǒng)的FPKM不太一樣的是,傳統(tǒng)的FPKM也是進(jìn)行了矯正,但FPKM是直接除以了Exon的長(zhǎng)度,而RSEM認(rèn)為這樣并不能完全解決問(wèn)題,應(yīng)該把它看成一個(gè)概率模型估出來(lái)一個(gè)修正的值,這個(gè)處理流程是一個(gè)很復(fù)雜的流程:


RSEM主要是用了機(jī)器學(xué)習(xí)的辦法來(lái)估基因的 reads count 有多少,在估計(jì)的時(shí)候使用了EM算法,R是RNA,S是seek,E是expectation,M是maximization
EM的意思就是期望最大化,所以RSEM就是用了EM算法來(lái)估計(jì)基因真正的、合理的reads 數(shù)量。

總體來(lái)說(shuō),RPKM沒什么人用了,因?yàn)楝F(xiàn)在基本上都是 pair-end 測(cè)序,F(xiàn)PKM現(xiàn)在是主流,但是FPKM不如TPM方便,TCGA數(shù)據(jù)庫(kù)里面給了很多的表達(dá)量都是RSEM。
RSEM整個(gè)的評(píng)估號(hào)稱要比FPKM要穩(wěn)定和準(zhǔn)確,但是RSEM在理解上不是很直觀。
TPM是一個(gè)比較好的標(biāo)準(zhǔn),因?yàn)樗殖C正了長(zhǎng)度又矯正了測(cè)序量而且還能保證每個(gè)sample總數(shù)是固定的。


上機(jī)操作部分

  • RNA-Seq的本質(zhì)是什么?
  • RNA-Seq尋找差異基因是為了干什么?
  • Raw Count 是什么東西?怎么算?
  • FPKM/TPM 是什么東西?怎么算?
  • Cuffdiff的原理
  • DESeq2的原理

轉(zhuǎn)錄組在整個(gè)NGS 中是一個(gè)核心的位置,它啟到承上啟下的作用,承上它是對(duì)DNA進(jìn)行了轉(zhuǎn)錄,啟下就是必須有蛋白才能行使功能,沒有RNA是不可能有蛋白質(zhì)的

RNA-Seq的本質(zhì)是對(duì)RNA進(jìn)行定量!!!

思考:對(duì)RNA進(jìn)行定量了怎么就有意義了?RNA定量定的是絕對(duì)量還是相對(duì)量呢?

答:RNA-Seq定量定的是相對(duì)的量

為什么要去找差異基因?

  • DNA ---> RNA ---> 蛋白質(zhì) ---> 功能
  • 要實(shí)現(xiàn)一個(gè)具體的功能,蛋白的含量大概率需要變化,而蛋白含量的變化要形成一個(gè)穩(wěn)態(tài),RNA水平大概率會(huì)變
  • 綜上,尋找差異基因的本質(zhì)是通過(guò)RNA變化來(lái)推測(cè)蛋白的變化

Raw Count 是什么東西?

我們已經(jīng)知道了RNA-Seq是為了找差異表達(dá)基因也就是 DEG differencial expression genes
找差異那一定得有至少兩個(gè)來(lái)比較,也就是說(shuō)在尋找差異表達(dá)基因的時(shí)候一定得有一個(gè) input1 和 input2
GeneA:input1 - reads count --> 數(shù)一下在input1中有多少reads map到GeneA;
GeneA:input2 - reads count --> 數(shù)一下在input2中有多少reads map到GeneA

fold change = input2 - reads count / input1 - reads count
我們把得到的這兩個(gè)數(shù)一除,就得到 fold change(倍數(shù)變化)

FC = 1.5 ? p-value ?
FC = 1.1 ? p-value ?

然后進(jìn)行一個(gè)統(tǒng)計(jì)檢驗(yàn),告訴我們 fold change 等于1.5時(shí),差異是否顯著,p-value是多少;fold change 等于1.1時(shí),差異是否顯著,p-value是多少。

也就是說(shuō),對(duì)于GeneA我們想知道它的表達(dá)量是升高了還是降低了,我們只要數(shù)在對(duì)照組里面(input1)有多少條reads回帖到了GeneA,然后在實(shí)驗(yàn)組里面(input2)數(shù)有多少條reads回帖到了GeneA,然后算一個(gè)fold change ( input2 - reads count / input1 - reads count),等到的FC再進(jìn)行統(tǒng)計(jì)檢驗(yàn)。

在這個(gè)過(guò)程中,值得注意的兩個(gè)問(wèn)題是:

  • 一、測(cè)序量是否一致
  • 二、2000 --> 2500 VS 200 --> 250 這兩個(gè)變化到底哪個(gè)更顯著?

這兩個(gè)問(wèn)題在RNA-Seq中屬于比較棘手的問(wèn)題。

問(wèn)題1,測(cè)序量的問(wèn)題其實(shí)是很好解決的,直接矯正測(cè)序量就可以了,也就是我們常說(shuō)的 normalization 常用的有這三種矯正方法:

  1. quantile
  2. genometry
  3. traditional

問(wèn)題2,怎樣去衡量,哪個(gè)才是真正顯著的?
基本假設(shè)!!!!:

  1. 大部分的基因表達(dá)量不變;
  2. 高表達(dá)的基因表達(dá)量不變

Why?回答這個(gè)問(wèn)題我們一定要明白 p-value 是怎么算出來(lái)的?
我們首先得有一個(gè)0假設(shè)-->兩者沒有差異,再來(lái)一個(gè)1假設(shè)-->兩者有差異,然后算出一個(gè)統(tǒng)計(jì)量x ,給出一個(gè)置信區(qū)間阿爾法α,這種條件下肯定H0或者否定H1
H0:兩者沒有差異
H1:兩者有差異
統(tǒng)計(jì)量x,α = 0.05,肯定H0或者否定H1

input1(對(duì)照組)和input2(實(shí)驗(yàn)組)在進(jìn)行統(tǒng)計(jì)檢驗(yàn)的時(shí)候,認(rèn)為GeneA在兩組條件下表達(dá)沒有差異,兩個(gè)分布應(yīng)該是同一個(gè)整體分布,在同一個(gè)整體分布的時(shí)候觀察到在input1總體中(對(duì)照組)reads count 為2000的情況下p-value為多少?同時(shí)觀察在input2總體中(實(shí)驗(yàn)組)reads count 為2500的情況下p-value為多少?
假如 p-value = 0.001 即單次試驗(yàn) p-value<0.05 ,說(shuō)明這是一個(gè)小概率事件,小概率事件在單次實(shí)驗(yàn)中認(rèn)為不發(fā)生,但它發(fā)生了,所以我們認(rèn)為我們的0假設(shè)不對(duì),所以兩者有差異。

知道了這個(gè),我們?cè)倩赝苹厝ィ瑸槭裁创蟛糠值幕虮磉_(dá)量不變?就是因?yàn)槲覀兊?假設(shè),大部分的基因表達(dá)量不能變?nèi)绻兊脑挘覀兯械慕y(tǒng)計(jì)沒有辦法操作。

在捋一下p-value的事兒:
H0是認(rèn)為兩者沒有差異;H1是認(rèn)為兩者有差異,構(gòu)造一個(gè)統(tǒng)計(jì)量在input1中觀察到reads count是2000,在input2中觀察到reads count 是2500,那么觀測(cè)2000和2500的概率是p-value=0.001
由于p-value<0.05,那么這就是一個(gè)小概率事件,小概率事件單次實(shí)驗(yàn)不發(fā)生,但這里卻發(fā)生了,因此否定H0,所以有差異。

解決第二個(gè)問(wèn)題:為什么高表達(dá)的基因不能變?

假如說(shuō)基因組就有 gene A ,B,C
總共測(cè)了200條reads,gene A有150條;geneB 和geneC 各25條 這是input1;在input2中同樣只有g(shù)ene A ,B,C,同樣測(cè)了200條reads,當(dāng)高表達(dá)量基因 geneA降低到100條,gene B C 沒有變化時(shí),
客觀條件下應(yīng)該是這種情況:
input1:200 = 150 + 25 + 25
input2:150 = 100 + 25 + 25

但,實(shí)際測(cè)的時(shí)候會(huì)出現(xiàn)這種情況:
input1:200 = 150 + 25 + 25
input2:200 = 130 + 35 + 35

實(shí)際上高表達(dá)基因 gene A 從150 變成了100 發(fā)生了顯著變化,gene B C 沒有發(fā)生顯著變化;但是實(shí)際測(cè)的情況確實(shí)基因 A 從150 變成了 130 并沒有發(fā)生顯著變化,而gene B C 從25 變到 35 發(fā)生了顯著變化

所以說(shuō),當(dāng)一個(gè)高表達(dá)基因發(fā)生顯著變化的時(shí)候,它會(huì)把其他基因拉跑偏,所以說(shuō)我們?cè)谶M(jìn)行統(tǒng)計(jì)檢驗(yàn)的時(shí)候一定要遵循基本假設(shè):大部分的基因表達(dá)量不變;高表達(dá)的基因表達(dá)量不變。

那么,問(wèn)題來(lái)了,如果高表達(dá)的基因表達(dá)量變了怎么辦?如果大部分的基因表達(dá)量發(fā)生了變化怎么辦?

解決方案:

  • 第一,摻入 spike-in (適用于解決1/2假設(shè)不成立時(shí))
    人工摻入一個(gè)我們已知量的東西,變成絕對(duì)定量
  • 第二,使用 house keeping gene 進(jìn)行校正 (適用于解決2假設(shè)不成立時(shí))
    house keeping gene是維持細(xì)胞基本代謝所需要的基因,而且細(xì)胞和細(xì)胞之間house keeping gene的表達(dá)量不太變。

FPKM的本質(zhì)是什么?
FPKM本質(zhì)是對(duì)測(cè)序深度,基因長(zhǎng)度做了矯正
FPKM =(reads count / exon length / total reads)* 10^9
最后乘以10^9 是為了單位好看一些

TPM類似
TPM = (FPKM / total FPKM)* 10^6

FPKM VS TPM

所以說(shuō),FPKMTPM都對(duì)測(cè)序深度和基因長(zhǎng)度做了矯正,而 Raw count 不對(duì)基因長(zhǎng)度做矯正只對(duì)測(cè)序量進(jìn)行矯正。
那么,FPKMRaw count到底哪個(gè)好哪個(gè)不好呢?這就公說(shuō)公有理婆說(shuō)婆有理了
FPKM or Raw count?

cuffdiff pipeline:

FASTQ-reads --> mapping (HISAT2,tophat2)--> BAM --> cuffdiff --> DEGs(FPKM)

cuffdiff 那一套

DESeq2 pipeline:

FASTQ-reads --> mapping (HISAT2,tophat2)--> BAM --> Gene Raw Count --> find DEGs in R (No FPKM)

DESeq2 那一套

泊松分布與負(fù)二項(xiàng)分布


泊松分布就一個(gè)參數(shù)叫 lambda,期望(E),和方差(Var)都是 lambda。用來(lái)衡量不太容易發(fā)生的事兒:
比如,小茗同學(xué)有一定概率會(huì)被雷劈,那么他這一生當(dāng)中被雷劈的次數(shù)基本上是符合泊松分布的。到我們的基因組上來(lái)說(shuō)就是,有多少條 reads 能夠 map 到Gene A上,在最早的時(shí)候我們認(rèn)為它是符合泊松分布的,后來(lái)我們就認(rèn)為它符合負(fù)二項(xiàng)分布。

什么是負(fù)二項(xiàng)分布?
有兩盒火柴分別有A根火柴和B根火柴,把A盒火柴放到左口袋里,把B盒火柴放到右口袋里,每次用火柴的時(shí)候隨機(jī)從左口袋或者右口袋取一根,直到有第一盒火柴用完的時(shí)候,那用火柴的次數(shù) x,一定滿足:sum(A, B) >= x >= min(A, B)

再次舉例說(shuō)明:
一袋小球里面有黑球和白球,黑球有a個(gè),白球有b個(gè),每次從袋子里隨機(jī)抽一個(gè)小球,需要抽多少次才能把其中一種顏色的球抽完?這個(gè)問(wèn)題就和我們基因組的問(wèn)題很接近了,我們基因組可以分成兩個(gè)部分:基因 和 非基因。對(duì)于任意一個(gè)基因 gene1,基因上就是:gene1non-gene1,測(cè)序比對(duì)后就會(huì)發(fā)現(xiàn)有一些reads會(huì)map到gene1的位置,那么能map到gene1位置的事件就近似服從負(fù)二項(xiàng)分布。因?yàn)榫拖喈?dāng)于從整體里面進(jìn)行抽樣,我認(rèn)為能map到gene1就是從整體里面去抽樣正好把gene1抽出來(lái)了,抽完之后reads再回帖回來(lái)。

負(fù)二項(xiàng)分布和泊松分布其實(shí)差不太多,在次數(shù)比較大的時(shí)候這兩個(gè)沒啥區(qū)別,次數(shù)比較小的時(shí)候負(fù)二項(xiàng)分布的離散性更低一些。基本上我們現(xiàn)在做的基因組的統(tǒng)計(jì)檢驗(yàn)都是用負(fù)二項(xiàng)分布。

學(xué)習(xí)DESeq2包進(jìn)行差異表達(dá)分析

使用DESeq2包進(jìn)行差異表達(dá)分析首先需要計(jì)算 Raw reads Count

計(jì)算geneRaw reads Count的方法

  • 方法1. 使用知乎Live主—孟浩巍的代碼,或者根據(jù)代碼修改自己的需求;
    優(yōu)點(diǎn):在R中完成操作,支持多線程;
    缺點(diǎn):內(nèi)存占用比較大;

  • 方法2. 使用htseq-count程序
    優(yōu)點(diǎn):節(jié)省內(nèi)存
    缺點(diǎn):不夠優(yōu)雅,需要對(duì)讀取進(jìn)來(lái)的內(nèi)容再做處理

方法1,2本質(zhì)沒有差別,我們以方法1為例子進(jìn)行演示

將孟浩巍寫的計(jì)算 Raw reads Count 的R代碼文件Count_RNASeq.R放到服務(wù)器上(R代碼解釋后面講)

我們?cè)诜?wù)器的命令行輸入 Rscript Count_RNASeq.R 就會(huì)告訴我們命令格式:

$ Rscript Count_RNASeq.R
Loading required package: magrittr
Count_RNASeq.R Usage like:
----------------------------------------------------------------------------------------------------
Rscript Count_RNASeq.R --input XXX --label XXX --type XXX --threads XXX --output XXX
----------------------------------------------------------------------------------------------------
    --input : input bam file list, format like bam1,bam2,bam3...
    --label : the same length as --input, format likt label1,label2,label3...
    --type : the sample type ,the same length as --input, format likt ctrl,ctrl,ko,ko...
    --threads : the CPU limit 
    --output : name of RData that contain SummarizedExperiment.obj
Error: Input parameters error!
Execution halted

單看不太容易看明白其實(shí)舉個(gè)例子就很簡(jiǎn)單,比如,我們有兩個(gè)分組 WT、KO,那么--input --label --type --threads --output 這些命令后面的文件格式按照上面給的要求寫好就是這個(gè)樣子:

--input ./wt.rep1.bam,./wt.rep2.bam,./wt.rep3.bam,./ko.rep1.bam,./ko.rep2.bam,./ko.rep3.bam,

--label  WT.rep1,WT.rep2,WT.rep3,KO.rep1,KO.rep2,KO.rep3

--type WT,WT,WT,KO,KO,KO

--threads 6

--output ./RNA_raw_count.RData

注意,--input--label后面的文件是一一對(duì)應(yīng)的; --threads是指定用多少個(gè)核,我們這里有6個(gè)文件,所以指定的是6個(gè)核,多了也沒用少了浪費(fèi)時(shí)間; --output 最后會(huì)保存成R語(yǔ)言能夠讀成的格式,自己起個(gè)名字后綴加上.RData就行。

各個(gè)參數(shù)寫好之后還要調(diào)整一下(中間可以有空格但不能換行):

Rscript Count_RNASeq.R --input ./wt.rep1.bam,./wt.rep2.bam,./wt.rep3.bam,./ko.rep1.bam,./ko.rep2.bam,./ko.rep3.bam, --label  WT.rep1,WT.rep2,WT.rep3,KO.rep1,KO.rep2,KO.rep3 --type WT,WT,WT,KO,KO,KO --threads 6 --output ./RNA_raw_count.RData

這樣我們就可以在服務(wù)器上運(yùn)行計(jì)算geneRaw reads Count的程序了,為什么不直接在RStudio上直接運(yùn)行,還要這么費(fèi)勁的將R代碼整到服務(wù)器上,因?yàn)閭€(gè)人電腦帶不起來(lái)呀!!!

我們把Count_RNASeq.R 文件(計(jì)算geneRaw reads Count的代碼文件)里的R代碼理解一下

打印剛剛的說(shuō)明文檔代碼:

# help function 
my_help <- function(){
  cat("Count_RNASeq.R Usage like:\n")
  cat("----------------------------------------------------------------------------------------------------\n")
  cat("Rscript Count_RNASeq.R --input XXX --label XXX --type XXX --threads XXX --output XXX\n")
  cat("----------------------------------------------------------------------------------------------------\n")
  cat("\t--input : input bam file list, format like bam1,bam2,bam3...\n")
  cat("\t--label : the same length as --input, format likt label1,label2,label3...\n")
  cat("\t--type : the sample type ,the same length as --input, format likt ctrl,ctrl,ko,ko...\n")
  cat("\t--threads : the CPU limit \n")
  cat("\t--output : name of RData that contain SummarizedExperiment.obj\n")
}

讀參數(shù),輸入的參數(shù)是通過(guò)下面這樣的方式讀進(jìn)來(lái)的:

# 1. check args length 
args = commandArgs()
args.length = length(args)

if(args.length != (5 + 5 * 2)){
  my_help()
  stop("Input parameters error!")
}

檢查是否有這些:--input --label --type --threads --output 指定的參數(shù),如果沒有就停止,然后打印說(shuō)明文檔(my_help())并報(bào)出錯(cuò)誤提示:Input parameters error!

# 3.check if all parameter in the list 
parameter_list = c("--input","--label","--type","--threads","--output")
if(! all(parameter_list %in% names(args.list))){
  my_help()
  stop("Input parameters keys error!")
}

如果輸入的都沒有問(wèn)題,就會(huì)把變量都定義好,告訴你INPUT_BAM INPUT_LABEL INPUT_TYPE CPU_THREADS OUTPUT_FILE 都是些啥:

# 4. reads parameters
INPUT_BAM = strsplit(args.list[["--input"]],split=",") %>% unlist()
INPUT_LABEL = strsplit(args.list[["--label"]],split=",") %>% unlist()
INPUT_TYPE = strsplit(args.list[["--type"]],split=",") %>% unlist()
CPU_THREADS = strsplit(args.list[["--threads"]],split=",") %>% unlist() %>% as.integer()
OUTPUT_FILE = strsplit(args.list[["--output"]],split=",") %>% unlist() %>% path.expand()

OUTPUT_DIR = dirname(OUTPUT_FILE)
OUTPUT_BASENAME = basename(OUTPUT_FILE)

然后檢查BAM文件是否存在:

# 5. check if BAM file exist 
if(all(file.exists(INPUT_BAM))){
  print("All file checked exsit!")
}else{
  stop(sprintf("File: '%s' Not Exist!",INPUT_BAM[!file.exists(INPUT_BAM)]))
}

BAM文件是比對(duì)的結(jié)果文件,里面存放了哪些reads比對(duì)到了基因組的哪些位置,我們就是要用BAM文件來(lái)計(jì)算Raw reads Count,所以必須檢查是否存在BAMwe文件。
如果BAM文件不存在會(huì)報(bào):.......Not Exist!,如果所有的文件都存在所有的設(shè)置沒有問(wèn)題,下面就開始正式的把這些包都載入:

######################################################################################
# required packages 
######################################################################################
require(BiocParallel)
require(GenomicFeatures)
require(GenomicAlignments)
require(Rsamtools)
require(TxDb.Hsapiens.UCSC.hg19.knownGene)

這個(gè)包BiocParallel是R里面并行的一個(gè)包;這個(gè)包GenomicFeatures是做GTF分析必須得用的用來(lái)真正數(shù) reads count 的;這個(gè)包Rsamtools是打開BAM文件用的;這個(gè)包TxDb.Hsapiens.UCSC.hg19.knownGene是人的參考基因組轉(zhuǎn)錄組信息。

input_bam信息讀進(jìn)來(lái):

input_bamfiles = Rsamtools::BamFileList(INPUT_BAM)

讀進(jìn)來(lái)之后把 bam 文件標(biāo)上 label 就是告訴你每個(gè) bam 是什么:

names(input_bamfiles) = INPUT_LABEL

這兩部整合起來(lái)就是:

######################################################################################
# read BAM file
######################################################################################
input_bamfiles = Rsamtools::BamFileList(INPUT_BAM)
names(input_bamfiles) = INPUT_LABEL

讀入人的GTF文件:

######################################################################################
# load GTF file
######################################################################################
print("Loading GTF file...")
gene_range = GenomicFeatures::exonsBy(TxDb.Hsapiens.UCSC.hg19.knownGene,by="gene")
print("Done!")

一切準(zhǔn)備就緒我們就開始counting了:

######################################################################################
# counting gene reads
######################################################################################
print("counting...")

# BiocParallel::register(SerialParam())
BiocParallel::register(MulticoreParam(workers=CPU_THREADS))

SummarizedExperiment.obj <- GenomicAlignments::summarizeOverlaps(features=gene_range, 
                                                                 reads=input_bamfiles,
                                                                 mode="Union",
                                                                 singleEnd=FALSE,
                                                                 ignore.strand=TRUE,
                                                                 fragments=TRUE )
print("counting...Done!")

其中 mode 這個(gè)參數(shù)有三個(gè)選項(xiàng),這里用的是mode="Union"默認(rèn)情況下都是Union模式,另外兩個(gè)分別是:IntersectionStrictIntersectionNotEmpty

此時(shí),count完成,保存有用的信息成為一個(gè)對(duì)象SummarizedExperiment.obj
并按照指定的輸出位置輸出文件:

######################################################################################
# save data
######################################################################################
# make sample table 
sample_table = DataFrame(case_label = INPUT_LABEL,
                         case_type = INPUT_TYPE,
                         bam_path = INPUT_BAM)

colData(SummarizedExperiment.obj) = sample_table

# save SummarizedExperiment.obj
save(file=OUTPUT_FILE,list="SummarizedExperiment.obj")
print("Save R image... Done!")

rm(list=ls())
print("Clear R env... Done!")

最后清空所有變量,操作完成~

DESeq2包進(jìn)行差異表達(dá)分析

計(jì)算完generaw reads count得到結(jié)果文件SummarizedExperiment.obj后我們就可以用DESeq2包進(jìn)行差異表達(dá)分析了。

讀入上一步計(jì)算raw reads count的結(jié)果文件 —SummarizedExperiment.obj

#### 讀取上一步的計(jì)算結(jié)果文件 — SummarizedExperiment.obj
load(file="./ReadsCount.RData")
SummarizedExperiment.obj
colData(SummarizedExperiment.obj)

我們看下上面代碼在R里的運(yùn)行結(jié)果:

> load(file="./ReadsCount.RData")
> SummarizedExperiment.obj
class: RangedSummarizedExperiment 
dim: 23459 4 
metadata(0):
assays(1): counts
rownames(23459): 1 10 ... 9994 9997
rowData names(0):
colnames: NULL
colData names(2): case_label case_type
> colData(SummarizedExperiment.obj)
DataFrame with 4 rows and 2 columns
   case_label   case_type
  <character> <character>
1     WT.rep1          WT
2     WT.rep2          WT
3     KO.rep1          KO
4     KO.rep2          KO
> 

colData(SummarizedExperiment.obj)運(yùn)行結(jié)果告訴了我們SummarizedExperiment.obj文件里的保存信息。我們可以看到case_type那一列是樣本信息分別是 WT 和 KO。

結(jié)果讀進(jìn)來(lái)后第一步就應(yīng)該構(gòu)建 DESeq 的 DataSet,因?yàn)槲覀冞@里只需要區(qū)分WT 和 KO,所以我們這里面的參數(shù)design只需要按照case_type去區(qū)分就可以了,即:design = ~case_type

#### 構(gòu)建DESeqDataSet
DES_set = DESeqDataSet(SummarizedExperiment.obj,design = ~case_type)

做差異表達(dá)分析就是將上一步構(gòu)建好的DESeq的DataSet — DES_set,扔到函數(shù)DESeq中即可:

#### 進(jìn)行差異表達(dá)分析
DEG_set.run = DESeq(DES_set)

#### 輸出結(jié)果
DEG_set.result = results(DEG_set.run)
DEG_set.result

#### 對(duì)結(jié)果進(jìn)行統(tǒng)計(jì)
summary(DEG_set.result)

#### 將結(jié)果保存成data.frame
DEG_set.result.df = as.data.frame(DEG_set.result)

DEG_set.result.df就是最終的結(jié)果文件了,我們打開看一下

DEG_set.result.df

我們可以看到列有log2FoldChange還有pvalue,我們一般用padj
最左邊那一列是基因ID編號(hào),下面我們把它改成gene_symbol(基因symbol):

library(org.Hs.eg.db)
columns(org.Hs.eg.db)

gene_symbol = mapIds(x=org.Hs.eg.db,
                     keys = rownames(DEG_set.result.df),
                     keytype = "ENTREZID",
                     column = "SYMBOL")

我們使用的是mapIds這個(gè)函數(shù)來(lái)準(zhǔn)換的,其中各參數(shù)解釋:

  • x是基因ID和基因symbol對(duì)應(yīng)的數(shù)據(jù)庫(kù),人的就是org.Hs.eg.db
  • keys來(lái)指定想要轉(zhuǎn)換的數(shù)據(jù),這里就是基因ID號(hào)即結(jié)果文件DEG_set.result.df的行名(rownames);
  • keytype是想要轉(zhuǎn)換的數(shù)據(jù)類型,這里是基因ID號(hào)學(xué)名就是ENTREZID
  • column來(lái)指定我們想把它準(zhǔn)換成的類型,這里是把基因ID準(zhǔn)換成對(duì)應(yīng)的基因名,學(xué)名的就是基因SYMBOL
DEG_set.result.df.fix = data.frame(gene_symbol,DEG_set.result.df)

這行代碼就是將轉(zhuǎn)換好的gene_symbol加到原來(lái)的結(jié)果文件DEG_set.result.df中,形成新的帶有基因symbol的結(jié)果文件 —— DEG_set.result.df.fix

新的結(jié)果文件

加餐:

house keeping gene矯正

先搞到house keeping gene list


這篇文章把當(dāng)時(shí)市面上所有的RNA-Seq數(shù)據(jù)全部都分析了一遍,找到了大概兩千多個(gè)他們認(rèn)為的house keeping gene,還推薦了一些適合用做qPCR 驗(yàn)證和當(dāng)內(nèi)參的house keeping gene,這個(gè)基因 list 從網(wǎng)上直接搜就可以了:
下載human housekeeping gene list


list搞到之后,使用RUVSeq包進(jìn)行驗(yàn)證,這個(gè)包的說(shuō)明書寫的非常非常詳細(xì),看包操作就行。


如果有多個(gè)input是不是兩兩比較?

如果input不是很多那我們就進(jìn)行兩兩比較,如果比較多有十幾個(gè)那就用cuffnorm,不做顯著性差異了,用cuffnorm把大家都normalization一下 看一下某一類的基因在這十幾個(gè)樣本里面表達(dá)量的升高和降低,這是第一個(gè)分析,第二個(gè)分析是用加權(quán)共表達(dá)網(wǎng)絡(luò)分析WGCNA,這也是比較常用的。
輸入的時(shí)候輸入 raw reads count 、FPKM、RSEM、TPM 都可以,但一定要保證輸入是一致的,個(gè)人建議TPM好一些。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容