生信-記一次NCBI-R語言-淋巴癌突變與未突變基因的差異分析

關鍵詞:基因芯片、R、篩選、預處理、差異分析

NCBI-淋巴癌突變與未突變基因的差異分析
PS:好久沒分享生信了,這是一年前做的一次生信task(準確來說是2018年11月了),這裏分享一下給大家,有助於一些小夥伴們想通過常規的,使用NCBI科研數據庫+R編程語言方式,進行對某種癌的差異分析。最近用心做了一些更棒的生信task,相信不久會分享出來~
PS2:如果這篇筆記有什麼不足,或者疑惑不解的地方,可以提出來,看到會回答(留個TODO給大家

簡單介紹

通過使用計算機對NCBI下載的基因數據,進行篩選,其中包括質量控制、質量分析,聚類分析,對數據進行預處理,並使用差異分析,獲取突變與未突變基因的差異表達基因,進行註釋,最後生成研究結果。
本次研究主要以R作爲數據處理的語言,多次對38組細胞進行篩選、其中編寫了5個版本的實驗腳本,研究結果主要有:基因的差異分析,需要對海量的數據進行十分嚴謹的篩選與預處理,突變與未突變基因在組間差異較爲明顯。

一、研究對象

淋巴癌突變與未突變基因的差異分析

二、研究工具

1. NCBI

NCBI, The National Center for Biotechnology Information biomedical genomic,美國國家生物技術旨在通過提供生物醫學和基因組信息提供給熱愛科學與健康事業的人們。NCBI功能強大,提供了海量豐富的基因數據庫、計算機分析工具、文獻等,研究者可以根據自己的研究方向,選擇自己所需要的數據與處理方式,推動我們對基因遺傳的理解,從而推進健康和疾病的理解。

2. R

R語言是用於統計分析,圖形表示和報告的編程語言和軟件環境。 R語言由Ross Ihaka和Robert Gentleman在新西蘭奧克蘭大學創建,目前由R語言開發核心團隊開發。 R語言在GNU通用公共許可證下免費提供,併爲各種操作系統(如Linux,Windows和Mac)提供預編譯的二進制版本。 這種編程語言被命名爲R語言,基於兩個R語言作者的名字的第一個字母(Robert Gentleman和Ross Ihaka),並且部分是貝爾實驗室語言S的名稱。

三、研究流程

1、 數據源載入

1) 針對參考的文獻,通過基因芯片研究突變/未突變的套細胞淋巴瘤患者的關係
2) 對應的數據下載源:https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE36000
3) 數據下載源:
數據源下載
數據源下載到本地

4) 參考數據集:
參考數據集

2、 使用R讀取下載的數據

在使用R進行前期準備的過程中,需要先將應用到的一些常用的lib包加載到本機(如果看不懂,那可以先跳過,繼續往下看),不同的庫會依賴到其他庫,那麼也需要提前下載好。
併爲了增加可讀性,我們需要將基因芯片重命名,並根據已有原本數據的分類進行簡單的分類與命名(例如,本次研究的是未突變與突變淋巴細胞)

PS:下載package的時候,更新了Bioconductor version 3.8,更新到了R的Version 3.5.1(2018-07-02),所以需要使用到BiocManager::install的方式,bioCLite已經提示廢棄。

具體流程

  1. 設置工作目錄
  2. 先下載並加載必要的package,已安裝並加載的,可以不用重複這些步驟
  3. 可以通過GEOquery直接讀取基因芯片的編號(例如本次差異分析中使用到的是“GSE36000”);也可以直接在官網下載raw包,並通過ReadAffy的方式,這裏會有AffyBatch特定的格式(本差異分析採取的是這種方式)。
  4. 查看數據類型、基本信息,並重命名芯片名稱
    (溫馨提示:R代碼部分後面會提供)

代碼參考:

# 本文字符格式基於UTF-8編碼
# 【廢棄的前數據-不合適】:1.下載數據:https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE47811
# 1.下載數據:https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE36000
# 2.讀取下載的數據
# 2.1 先下載並加載必要的package,已安裝並加載的,可以不用重複這些步驟
# Bioconductor用於生物芯片數據分析和基因組數據分析的軟件包
source("https://bioconductor.org/biocLite.R")
# 2.1.1 Bioconductor version 3.7版本以前,使用bioCLite下載
biocLite("affy")
biocLite("simpleaffy")
biocLite("pheatmap")
biocLite("RColorBrewer")
biocLite("affyPLM")
biocLite("GOstats")

# 2.1.2 Bioconductor version 3.8 其中biocLite已在3.8廢棄,改用BiocManager::install
BiocManager::install("affy")
BiocManager::install("simpleaffy")
BiocManager::install("pheatmap")
BiocManager::install("RColorBrewer")
BiocManager::install("affyPLM")
BiocManager::install("GOstats")
BiocManager::install("survival")

# 2.2 設置工作目錄——放置源文件
setwd("C:/libtobrain/R/R_Package/GSE36000_RAW")

# 2.3 將GSE36000_RAW.tar解壓到GSE36000_RAW目錄下
# 2.4 讀取基因數據
dir.files <- list.files(path = "C:/libtobrain/R/R_Package/GSE36000_RAW/", pattern = "*.CEL.gz")
dir.files
library(parallel)
library(BiocGenerics)
library(Biobase)
library(affy)
affy.data <- ReadAffy(filenames = dir.files)

# 2.4.1 查看數據類型
data.class(affy.data)
class(affy.data)
# 2.4.2 查看芯片的基本信息
show(affy.data)
# 2.4.3 查看芯片的樣本名
sampleNames(affy.data)

# 2.4.4 重命名樣品名
# GSM879118	MCL_IGHV_UNMUT(R1394)       mcl.ighv.unmut.1
# GSM879119	MCL_IGHV_UNMUT(R1328)       mcl.ighv.unmut.2
# GSM879120	MCL_IGHV_UNMUT(R1329)       mcl.ighv.unmut.3
# GSM879121	MCL_IGHV_UNMUT(R1306)       mcl.ighv.unmut.4
# GSM879122	MCL_IGHV_UNMUT(R1332)       mcl.ighv.unmut.5
# GSM879123	MCL_IGHV_MUT(R1399_M)       mcl.ighv.mut.1
# GSM879124	MCL_IGHV_MUT(R1400)         mcl.ighv.mut.2
# GSM879125	MCL_IGHV_UNMUT(R1587)       mcl.ighv.unmut.6
# GSM879126	MCL_IGHV_UNMUT(R1680)       mcl.ighv.unmut.7
# GSM879127	MCL_IGHV_UNMUT(268-01-5TR)  mcl.ighv.unmut.8
# GSM879128	MCL_IGHV_MUT(269-01-5TR)    mcl.ighv.mut.3
# GSM879129	MCL_IGHV_UNMUT(043-01-4TR)  mcl.ighv.unmut.9
# GSM879130	MCL_IGHV_MUT(R1302)         mcl.ighv.mut.4
# GSM879131	MCL_IGHV_MUT(R1304)         mcl.ighv.mut.5
# GSM879132	MCL_IGHV_MUT(R1305)         mcl.ighv.mut.6
# GSM879133	MCL_IGHV_MUT(R1628)         mcl.ighv.mut.7
# GSM879134	MCL_IGHV_MUT(R1629)         mcl.ighv.mut.8
# GSM879135	MCL_IGHV_MUT(R1341)         mcl.ighv.mut.9
# GSM879136	MCL_IGHV_MUT(R1333)         mcl.ighv.mut.10
# GSM879137	MCL_IGHV_MUT(R1585)         mcl.ighv.mut.11
# GSM879138	MCL_IGHV_MUT(R1589)         mcl.ighv.mut.12
# GSM879139	MCL_IGHV_MUT(R1591)         mcl.ighv.mut.13
# GSM879140	MCL_IGHV_UNMUT(R1595)       mcl.ighv.unmut.10
# GSM879141	MCL_IGHV_MUT(R1640)         mcl.ighv.mut.14
# GSM879142	MCL_IGHV_MUT(R1626)         mcl.ighv.mut.15
# GSM879143	MCL_IGHV_MUT(R1610)         mcl.ighv.mut.16
# GSM879144	MCL_IGHV_MUT(02_201)        mcl.ighv.mut.17
# GSM879145	MCL_IGHV_MUT(R1339)         mcl.ighv.mut.18
# GSM879146	MCL_IGHV_MUT(R1301)         mcl.ighv.mut.19
# GSM879147	MCL_IGHV_UNMUT(R1338)       mcl.ighv.unmut.11
# GSM879148	MCL_IGHV_UNMUT(R1762)       mcl.ighv.unmut.12
# GSM879149	MCL_IGHV_MUT(R1938)         mcl.ighv.mut.20
# GSM879150	MCL_IGHV_MUT(R1940)         mcl.ighv.mut.21
# GSM879151	MCL_IGHV_MUT(R1942)         mcl.ighv.mut.22
# GSM879152	MCL_IGHV_MUT(R1941)         mcl.ighv.mut.23
# GSM879153	MCL_IGHV_MUT(R1970)         mcl.ighv.mut.24
# GSM879154	MCL_IGHV_UNMUT(R1897)       mcl.ighv.unmut.13
# GSM879155	MCL_IGHV_UNMUT(R1388)       mcl.ighv.unmut.14

c.all <- c("mcl.ighv.unmut.1","mcl.ighv.unmut.2","mcl.ighv.unmut.3","mcl.ighv.unmut.4","mcl.ighv.unmut.5",
           "mcl.ighv.mut.1","mcl.ighv.mut.2",
           "mcl.ighv.unmut.6","mcl.ighv.unmut.7","mcl.ighv.unmut.8",
           "mcl.ighv.mut.3",
           "mcl.ighv.unmut.9",
           "mcl.ighv.mut.4","mcl.ighv.mut.5", "mcl.ighv.mut.6","mcl.ighv.mut.7", "mcl.ighv.mut.8","mcl.ighv.mut.9", "mcl.ighv.mut.10","mcl.ighv.mut.11", "mcl.ighv.mut.12","mcl.ighv.mut.13",
           "mcl.ighv.unmut.10",
           "mcl.ighv.mut.14","mcl.ighv.mut.15", "mcl.ighv.mut.16","mcl.ighv.mut.17","mcl.ighv.mut.18", "mcl.ighv.mut.19",
           "mcl.ighv.unmut.11","mcl.ighv.unmut.12",
           "mcl.ighv.mut.20","mcl.ighv.mut.21", "mcl.ighv.mut.22","mcl.ighv.mut.23","mcl.ighv.mut.24",
           "mcl.ighv.unmut.13","mcl.ighv.unmut.14")

c.all.status <- c("unmut","unmut","unmut","unmut","unmut",
                  "mut","mut",
                  "unmut","unmut","unmut",
                  "mut",
                  "unmut",
                  "mut","mut", "mut","mut", "mut","mut", "mut","mut", "mut","mut",
                  "unmut",
                  "mut","mut", "mut","mut","mut", "mut",
                  "unmut","unmut",
                  "mut","mut", "mut","mut","mut",
                  "unmut","unmut")
sampleNames(affy.data) <- c.all
sampleNames(affy.data)

3、 質量分析

3.1 芯片灰度圖

Affymetrix芯片在印刷時,會在在左上角印製芯片的名稱,在四個角印製實心的花紋,我們可以通過這個特徵來了解芯片數據是否可靠。比如說,圖像特別黑,說明信號強度低;圖像特別亮,說明信號可能過飽和,圖像亮度適中,說明信號比較可靠。

從GSE36000芯片組中,38個芯片,以其中的一個樣本GSM879118爲例構造芯片灰度圖,可以看出,四角實心的花紋名下,並且也有芯片名稱,圖像亮度適中,我們可以認爲:該樣本信號比較可靠。

GSE36000芯片組-GSM879118芯片灰度圖
GSE36000芯片組-GSM879118芯片灰度圖2

代碼參考

# 2.5讀取芯片灰度圖
# 2.5.1 設置工作目錄——放置結果
setwd("C:/libtobrain/R/R_Package/workSpaces/Version5/result2/")
# 2.5.2 將基因芯片進行解析讀取,存放爲result目錄下的pdf文件,即芯片灰度圖
pdf(file = "芯片灰度圖.pdf")
image(affy.data[,1])
dev.off()
3.2 質量控制

採取了以上兩種方式,來評估一個芯片是否質量可靠,還是不夠,那麼我們就需要採用更加綜合的方式來採取分析。

首先我們採取了對數據進行線性擬合,並將權重圖、殘差圖、殘差符號圖保存到pdf上(也可以直接在RStudio上觀察,通過筆記本來跑較大數據的分析,例如本次下載的數據就高到165MB,還是相對比較喫力的,個人建議,爲了減少資源的佔用,直接將圖片輸出會高效一些)

以本次實驗GSE36000爲例,可以看出權重圖、殘差圖、殘差符號圖,色彩平均,那麼我們可以認定該芯片質量均勻,不會因爲位置的不同而出現色彩過輕過重。如果圖片中出現明顯的色差變化,那麼就認定這組數據質量不達標。

1、 權重圖
GSE36000-權重圖
2、 殘差圖
GSE36000-殘差圖
3、 殘差符號圖
GSE36000-殘差符號圖

參考代碼:

# 2.6 質量分析與控制
# 2.6.1 質量控制,化權重圖、殘差圖等
library(preprocessCore)
library(gcrma)
library(affyPLM)

# 對探針數據集做線性擬合
Pset <- fitPLM(affy.data)
# 根據計算結果,畫權重圖
pdf(file = "權重圖.pdf")
image(Pset, type="weights", which=1, main="Weights")
dev.off()
# 根據計算結果,畫殘差圖
pdf(file = "殘差圖.pdf")
image(Pset,  type="resids", which=1, main="Residuals")
dev.off()
# 根據計算結果,畫殘差符號圖
pdf(file = "殘差符號圖.pdf")
image(Pset, type="sign.resids", which=1, main="Residuals.sign")
dev.off()
3.3 質量分析報告

在獲取到了基因芯片的數據,那麼爲了保證數據質量達標,我們還需要使用到Bioconductor的simpleaffy包,使用qc的方法,對Affy芯片的數據,進行質量評估,如果質量評估太差,那麼我們也需要放棄這一組數據。
例如,本次實驗使用到的數據(GSE36000),我們進行質量評估,可以發現,第一列,是我們在"讀取下載部分的數據"章節,進行重命名的樣本名稱,第二列的數據是檢出率與平均背景噪音,第三列(QC Stats),由actin(空心三角形)、(空心圓形)gapdh、(實心圓形)尺度因子組成。
從質量評估圖中,我們可以看出,這一芯片質量整體良好。指標出現藍色表示正常,指標紅色表示存在質量問題,比如unmut.8芯片相對來說actin遠離尺度因子指標,那麼也可以考慮棄用這類數據,如果標識有紅色bioB表示該樣品未檢測到,那麼這類數據建議不採用。
另外,在採用GSE36000之前,本次實驗原本是想通過基因芯片,GSE47811(已廢棄),來研究健康小鼠與患癌小鼠的唾液間的關係。但是因爲採用質量評估,發現大量數據不可用,所以棄用了GSE47811這組芯片。
實驗的芯片:這裏我們可以剔除數據:mut3/unmut3,unmut8
質量分析報告

這裏有個反例,是前實驗棄用的芯片(已廢棄——研究健康小鼠與患癌小鼠的唾液間,GSE47811)
PS:這也是一個篩選數據的過程,如果不合適那麼最好就拋棄,重新找更加合適的數據。
反例-質量分析報告

參考代碼:

 2.6.2 將基因芯片進行解析讀取,獲取質量分析報告
library(genefilter)
library(gcrma)
library(simpleaffy)
affy.qc <- qc(affy.data)
pdf(file = "質量分析報告.pdf", width = 10, height =20)
# 圖形化顯示分析報告
plot(affy.qc)
# 剔除這些質量不合格的數據:mut3/unmut3,unmut8
dev.off()
3.4 RLE和NUSE箱線圖

RLE和NUSE,是質量檢測的兩種手段。
RLE表達的是一個探針組在某個樣品在探針組所有樣品表達值的中位數取對數,而所有芯片如果都趨近於0值,那麼表示這個芯片質量比較可靠;
NUSE表達的是一個探針組在某個樣品表達值的PM值標準差除以這個探針組所有樣品表達值的PM值標準差的中位數,而所有芯片如果都趨近於1值,那麼表示這個芯片質量比較可靠。
以本次實驗實驗對象(GSE36000)爲例,RLE趨向於0,NUSE趨向於1,芯片質量達標。但是如果芯片質量有問題,那麼會嚴重偏離0值(RLE)、1值(NUSE),這個時候就需要進行捨棄了。
RLE箱線圖

NUSE箱線圖

參考代碼:

# 2.6.3質量控制,繪製RLE和NUSE箱線圖
# 載入一組顏色
library(RColorBrewer)
library(graph)
colors <- brewer.pal(12,"Set3")
# 繪製RLE箱線圖,如果數據有部分數據遠離0值,那麼就需要剔除這些質量不合格的數據,這裏無須剔除
Mbox(Pset,ylim=c(-1,1),col=colors,main="RLE",las=2)
# 繪製NUSE箱線圖,如果數據有部分數據遠離1值,那麼就需要剔除這些質量不合格的數據,這裏無須剔除
boxplot(Pset,ylim=c(0.95,1.2),col=colors,main="NUSE",las=2)
3.5 質量分析(RNA降解)

芯片質量分析,還有一種方式,那就是根據RNA降解,如果從左到右,保持一定的斜率(不與X值水平),那麼表示RNA降解不嚴重,芯片質量可靠。以本次實驗(GSE36000)爲例,RNA降解曲線斜率高,沒有呈現下降趨勢,那麼就表示芯片質量可靠。不需剔除數據。
芯片質量分析-RNA降解

參考代碼:

# 2.6.4 RNA降解,質量分析,如果圖形中5'趨向3'斜率較低,那麼就需要把這些不夠明顯區別的剔除,這裏看出都明顯有斜率,這裏無須剔除
affy.deg <- AffyRNAdeg(affy.data)
plotAffyRNAdeg(affy.deg, col = colors)
legend("topleft", rownames(pData(affy.data)), col = colors, lwd = 1, inset = 0.05, cex = 0.5)
3.6 初步聚類分析

從聚類分析的角度來看,未突變與突變組基本上能夠比較好的分開,但這也不能判定這個實驗是成立的。只能說明我們的研究對象,從未突變到突變有一些因素產生了作用,但是其中具體問題還是需要我們去具體分析。這裏我們可以簡單得出一個小結論,未突變到突變的基因,組間差異大於組內差異,基因差異較爲明顯。但這裏我們不考慮去除不歸類的樣品。
初步聚類分析

4、 數據預處理

數據的預處理,將質量分析篩選下來合格的數據,進行背景校正、標準化、彙總三個部分的處理,獲取用來做實驗分析的矩陣
可以通過bgcorrect.methods()、normalize.methods(affy.data)、express.summary.stat.methods()的方式,獲取能用於進行預處理的方法,如下圖:
數據預處理

具體流程

affy包提供了通過expresso方法來實現背景校正、標準化、彙總的預處理,這裏需要設定不同的參數進行具體方法實現。
另外,如果想更快的實現同樣的功能,我們也可以直接通過採取mas5,gcrma,rma方法來進行一體化的預處理。這裏mas5需要進行對數的轉換,獲取數字化的表達譜矩陣。

經過上面那麼多步驟,這裏需要停下來,對數據進行一次處理(篩選時刻),參考代碼:

# 2.6.5 將以上的篩選重新組成實驗組
# GSM879118	MCL_IGHV_UNMUT(R1394)       mcl.ighv.unmut.1 
# GSM879119	MCL_IGHV_UNMUT(R1328)       mcl.ighv.unmut.2
# GSM879120	MCL_IGHV_UNMUT(R1329)       mcl.ighv.unmut.3    x
# GSM879121	MCL_IGHV_UNMUT(R1306)       mcl.ighv.unmut.4
# GSM879122	MCL_IGHV_UNMUT(R1332)       mcl.ighv.unmut.5
# GSM879123	MCL_IGHV_MUT(R1399_M)       mcl.ighv.mut.1
# GSM879124	MCL_IGHV_MUT(R1400)         mcl.ighv.mut.2
# GSM879125	MCL_IGHV_UNMUT(R1587)       mcl.ighv.unmut.6
# GSM879126	MCL_IGHV_UNMUT(R1680)       mcl.ighv.unmut.7 
# GSM879127	MCL_IGHV_UNMUT(268-01-5TR)  mcl.ighv.unmut.8    x
# GSM879128	MCL_IGHV_MUT(269-01-5TR)    mcl.ighv.mut.3      x
# GSM879129	MCL_IGHV_UNMUT(043-01-4TR)  mcl.ighv.unmut.9
# GSM879130	MCL_IGHV_MUT(R1302)         mcl.ighv.mut.4 
# GSM879131	MCL_IGHV_MUT(R1304)         mcl.ighv.mut.5
# GSM879132	MCL_IGHV_MUT(R1305)         mcl.ighv.mut.6
# GSM879133	MCL_IGHV_MUT(R1628)         mcl.ighv.mut.7
# GSM879134	MCL_IGHV_MUT(R1629)         mcl.ighv.mut.8
# GSM879135	MCL_IGHV_MUT(R1341)         mcl.ighv.mut.9
# GSM879136	MCL_IGHV_MUT(R1333)         mcl.ighv.mut.10
# GSM879137	MCL_IGHV_MUT(R1585)         mcl.ighv.mut.11
# GSM879138	MCL_IGHV_MUT(R1589)         mcl.ighv.mut.12
# GSM879139	MCL_IGHV_MUT(R1591)         mcl.ighv.mut.13
# GSM879140	MCL_IGHV_UNMUT(R1595)       mcl.ighv.unmut.10
# GSM879141	MCL_IGHV_MUT(R1640)         mcl.ighv.mut.14
# GSM879142	MCL_IGHV_MUT(R1626)         mcl.ighv.mut.15
# GSM879143	MCL_IGHV_MUT(R1610)         mcl.ighv.mut.16
# GSM879144	MCL_IGHV_MUT(02_201)        mcl.ighv.mut.17
# GSM879145	MCL_IGHV_MUT(R1339)         mcl.ighv.mut.18
# GSM879146	MCL_IGHV_MUT(R1301)         mcl.ighv.mut.19
# GSM879147	MCL_IGHV_UNMUT(R1338)       mcl.ighv.unmut.11
# GSM879148	MCL_IGHV_UNMUT(R1762)       mcl.ighv.unmut.12
# GSM879149	MCL_IGHV_MUT(R1938)         mcl.ighv.mut.20
# GSM879150	MCL_IGHV_MUT(R1940)         mcl.ighv.mut.21
# GSM879151	MCL_IGHV_MUT(R1942)         mcl.ighv.mut.22
# GSM879152	MCL_IGHV_MUT(R1941)         mcl.ighv.mut.23
# GSM879153	MCL_IGHV_MUT(R1970)         mcl.ighv.mut.24
# GSM879154	MCL_IGHV_UNMUT(R1897)       mcl.ighv.unmut.13
# GSM879155	MCL_IGHV_UNMUT(R1388)       mcl.ighv.unmut.14


c.experiment  <- c("mcl.ighv.unmut.1","mcl.ighv.unmut.2","mcl.ighv.unmut.4","mcl.ighv.unmut.5","mcl.ighv.unmut.6","mcl.ighv.unmut.7","mcl.ighv.unmut.9","mcl.ighv.unmut.10",
                   "mcl.ighv.unmut.11","mcl.ighv.unmut.12", "mcl.ighv.unmut.13","mcl.ighv.unmut.14",
                   "mcl.ighv.mut.1","mcl.ighv.mut.2","mcl.ighv.mut.4","mcl.ighv.mut.5", "mcl.ighv.mut.6","mcl.ighv.mut.7", "mcl.ighv.mut.8","mcl.ighv.mut.9", "mcl.ighv.mut.10",
                   "mcl.ighv.mut.11", "mcl.ighv.mut.12","mcl.ighv.mut.13","mcl.ighv.mut.14","mcl.ighv.mut.15", "mcl.ighv.mut.16","mcl.ighv.mut.17","mcl.ighv.mut.18", "mcl.ighv.mut.19",
                   "mcl.ighv.mut.20","mcl.ighv.mut.21", "mcl.ighv.mut.22","mcl.ighv.mut.23","mcl.ighv.mut.24"
                   )

c.experiment.status <- c("unmut","unmut","unmut","unmut","unmut","unmut",
                  "unmut","unmut","unmut","unmut","unmut","unmut",
                  "mut","mut", "mut","mut", "mut","mut", "mut","mut", "mut","mut",
                  "mut","mut", "mut","mut", "mut","mut", "mut","mut", "mut","mut",
                  "mut","mut", "mut"
                  )
length(c.experiment)
length(c.experiment.status)
affy.experiment <- affy.data[,c.experiment]
colnames(affy.experiment)

# 2.7 將原始數據組成數據框,對數據進行一個分類的整理(爲差異分析做準備)
affy.experiment.frame <- data.frame(SampleID = c.experiment, Disease = c.experiment.status)

sampleNames(affy.experiment)

c.unmut <- c("mcl.ighv.unmut.1","mcl.ighv.unmut.2","mcl.ighv.unmut.4","mcl.ighv.unmut.5","mcl.ighv.unmut.6","mcl.ighv.unmut.7","mcl.ighv.unmut.9","mcl.ighv.unmut.10",
             "mcl.ighv.unmut.11","mcl.ighv.unmut.12", "mcl.ighv.unmut.13","mcl.ighv.unmut.14")
c.mut <- c("mcl.ighv.mut.1","mcl.ighv.mut.2","mcl.ighv.mut.4","mcl.ighv.mut.5", "mcl.ighv.mut.6","mcl.ighv.mut.7", "mcl.ighv.mut.8","mcl.ighv.mut.9", "mcl.ighv.mut.10",
           "mcl.ighv.mut.11", "mcl.ighv.mut.12","mcl.ighv.mut.13","mcl.ighv.mut.14","mcl.ighv.mut.15", "mcl.ighv.mut.16","mcl.ighv.mut.17","mcl.ighv.mut.18", "mcl.ighv.mut.19",
           "mcl.ighv.mut.20","mcl.ighv.mut.21", "mcl.ighv.mut.22","mcl.ighv.mut.23","mcl.ighv.mut.24")
length(c.unmut)
length(c.mut)


affy.experiment.unmut <- affy.experiment[,c.unmut]
affy.experiment.mut <- affy.experiment[,c.mut]

# 2.8 預處理,(預處理)背景校正、標準化、彙總
# 預處理的方式有ms、expresso、gcrma
bgcorrect.methods()
normalize.methods(affy.experiment)
express.summary.stat.methods()

# 2.8.1 通過聚類分析,查看數據質量,預處理
# 使用gcrma算法來預處理數據,也可以通過mas5、rma算法
affy.experiment.gcrma <- gcrma(affy.experiment)
affy.experiment.gcrma.exprs <- exprs(affy.experiment.gcrma)

# 計算樣品兩兩之間的Pearson相關係數
pearson_cor <- cor(affy.experiment.gcrma.exprs)
# 得到Pearson距離的下三角矩陣
dist.lower <- as.dist(1 - pearson_cor)
# 聚類分析、畫圖
hc <- hclust(dist.lower,"ave")

pdf(file = "聚類分析.pdf", width = 10, height =10)
plot(hc)
dev.off()

# PCA
# samplenames <- sub(pattern = "\\.CEL", replacement = "", colnames(affy.data.gcrma.eset))
groups <- factor(affy.experiment.frame[,2])
# BiocManager::install("affycoretools")
# BiocManager::install("affycoretools")
library("affycoretools")
affycoretools::plotPCA(affy.experiment.gcrma.exprs, addtext=c.experiment, groups=groups, groupnames=levels(c.experiment.status))

# 2.8.2 使用expresso,進行背景校正、標準化處理和彙總
affy.experiment.expresso.eset <- expresso(affy.experiment, bgcorrect.method = "mas", normalize.method = "constant", pmcorrect.method = "mas",
                                          summary.method = "mas")
affy.experiment.expresso.exprs = exprs(affy.experiment.expresso.eset) 

# 2.8.3 直接採用MAS5算法進行數據預處理
affy.experiment.mas5.eset = mas5(affy.experiment)  
# 用exprs()從eset中獲取數字化的表達譜矩陣
affy.experiment.mas5.exprs = exprs(affy.experiment.mas5.eset) 

5、 基因芯片差異分析

5.1 limma處理差異分析

limma是一個比較全面的,通過用於芯片、RNA-Seq、PCR進行線性模型和差異表達函數的工具包,它通過貝葉斯方法提供穩定的分析結果,limma支持多重複雜的設計實驗,我們可以進行多個差異條件進行分析,差異條件越多,就越複雜。除了limma進行差異分析,也可以通過DESeq來集成處理。

例如,本次實驗(GES36000)主要是對未突變和突變兩種差異條件進行差異分析,是比較簡單的情況。

使用limma進行差異分析,主要需要準備好:分組矩陣,差異比較矩陣,表達矩陣,進行線性模擬擬合與差值計算、貝葉斯檢驗、生成檢驗結果。

具體流程
1)獲取實驗設計矩陣,即未突變、突變兩種情況
實驗設計矩陣-突變、未突變
實驗設計矩陣-突變、未突變2

2)構建對比模型,比較兩個實驗條件下表達數據,本次實驗只有兩種差異條件,如果需要讀個差異條件,通過makeContrasts進行多對多特徵交互比較,得到差異
構建對比模型
3)獲取表達矩陣,矩陣要求進行過預處理,併爲對數轉換的的表達譜矩陣
4)對錶達矩陣與實驗設計矩陣進行線性模擬擬合
5)根據對比模型進行差值計算
6)對差值計算的結果進行貝葉斯檢驗
7)生成檢驗結果的報告
8)對P.value進行篩選,得到比較理想的差異表達基因
未完全處理的差異表達基因

PS:當然也可以直接使用GEO2R做一些處理,後面再做分享吧。

參考代碼:

# 基因芯片差異分析
# 3.1 差異分析方法:limma
# 3.1.1 選取差異表達基因,使用Bioconductor中的limma包
# 將(未突變、突變)狀態數據框數據讀取爲因子
library(limma)
status <- factor(affy.experiment.frame[, "Disease"])
# 構建實驗設計矩陣(即未突變、突變兩種差異對比)
design <- model.matrix(~-1+status)
head(design)
# 構建對比模型,比較兩個實驗條件下表達數據,其中contrasts可以參考design的列名
contrast.matrix <- makeContrasts(contrasts = "statusmut - statusunmut", levels=design)

# 3.1.2 線性模型擬合
fit <- lmFit(affy.experiment.gcrma.exprs , design)
colnames(affy.experiment.gcrma.exprs)
# 根據對比模型進行差值計算 
fit1 <- contrasts.fit(fit, contrast.matrix)
# 3.1.3 貝葉斯檢驗
fit2 <- eBayes(fit1)
View(fit2)

# 3.1.4 生成所有基因的檢驗結果報告
result <- topTable(fit2, coef="statusmut - statusunmut", n=nrow(fit2), lfc=log2(2))
nrow(result)  # 1446
# 用P.Value進行篩選,得到全部差異表達基因
result <- result[result[, "P.Value"]<0.01,]
result2 <- result[result[, "P.Value"]<0.001,]
# 顯示一部分報告結果
head(result)
head(result2)
# 分析不同p.value值下,解析出來匹配的數據行數
nrow(result)  # 909
nrow(result2) # 701
write.table(result, file="statusmut_statusunmut+0.01.txt", quote=F, sep="\t")
write.table(result2, file="statusmut_statusunmut+0.001.txt", quote=F, sep="\t")
5.2 尋找在不同條件下的差異表達

另外我們可以採用倍數法、t-test方法來進行基因的差異表達。
affy芯片中對探針雜交質量評定有三個值P/M/A(有/臨界值/沒有),分別是Present/Marginal/Absent。如果探針集被標記位P或者A,表示一個芯片中,基因有表達,PM數值與MM相比,沒有顯著差異。

具體流程
1)對錶達譜矩陣進行對數化處理(針對mas5進行預處理的情況)
2)計算樣品組與實驗組的平均表達值,計算差異的相對錶達量
3)使用倍數法,篩選出2倍以上差異的基因
4)使用t-test檢驗差異基因(注意:根據 ?test方式,讀取文檔中提及,兩個實驗組需要保證,相同對比組,即樣品組與實驗組需要同數量)
5)計算p值
6)檢驗每張芯片中的三個值P/M/A(Present/Marginal/Absent),篩選出至少一個有表達的部分
7)設置FDR(False Discovery Rate)方法,來校正P值
8)篩選出2倍以上差異,P值小於0.05的,至少一個有表達的基因
9)構造差異表達基因的熱圖
差異表達基因的熱圖

參考代碼

# 3.2 尋找在不同條件下存在差異表達的基因
# 3.2.1 對錶達譜矩陣進行對數化處理
affy.experiment.mas5.exprs.log <- log(affy.experiment.mas5.exprs, 2)
probeset.id <- row.names(affy.experiment.mas5.exprs.log)
# 保存數據
write.table(affy.experiment.mas5.exprs.log, file="affy.experiment.mas5.exprs.log.txt", quote=F, sep="\t")

# 3.2.2 計算每個基因在樣本中的平均表達值
unmut.mean <- apply(affy.experiment.mas5.exprs.log[, c.unmut], 1, mean)
mut.mean <- apply(affy.experiment.mas5.exprs.log[, c.mut], 1, mean)
# 計算差異基因的相對錶達量 (log(fold change))
unmut.to.mut.mean <- unmut.mean - mut.mean

# 使用cbind,將數據表拼接在一起
unmut.to.mut.mean.data <- cbind(affy.experiment.mas5.exprs.log, unmut.mean, mut.mean, unmut.to.mut.mean)
head(unmut.to.mut.mean.data)
# 保存數據
write.table(unmut.to.mut.mean.data, file="unmut.to.mut.mean.data.txt", quote=F, sep="\t")

# 3.2.3 倍數法,尋找在不同條件下表達量存在2倍以上差異的基因(探針組) (log(fold change)>1 or <-1)
unmut.to.mut.mean.fc.probesets <- names(unmut.to.mut.mean[unmut.to.mut.mean >1 | unmut.to.mut.mean<(-1)])

# 3.2.4 用t test檢驗某個基因在突變與未突變基因中的表達是否存在差異
dataset.unmut <- affy.experiment.mas5.exprs.log[1, c.unmut]
dataset.mut <- affy.experiment.mas5.exprs.log[1, c.mut]
test.gene <- t.test(dataset.unmut, dataset.mut, "two.sided")
test.gene
test.gene$p.value
length(dataset.mut)
length(dataset.unmut)
?t.test

# 3.2.5 使用apply函數,對t test檢驗每個基因在未突變與突變基因中的表達是否存在差異,計算p值
dim(affy.experiment.mas5.exprs.log)
p.value.experiment.genes <- apply(affy.experiment.mas5.exprs.log, 1, function(x) { t.test(x[1:12], x[13:35]) $p.value } )

# 3.2.6 用mas5calls函數來檢測每張芯片中每個基因是否表達,P/M/A(有/臨界值/沒有)
affy.experiment.mas5calls <- mas5calls(affy.experiment)
affy.experiment.mas5calls.exprs = exprs(affy.experiment.mas5calls)
# 保存數據
write.table(affy.experiment.mas5calls.exprs, file="affy.experiment.mas5calls.exprs.txt", quote=F, sep="\t")
affy.experiment.PMA <- apply(affy.experiment.mas5calls.exprs, 1, paste, collapse="")
head(affy.experiment.PMA)

# 3.2.7 把至少在一個芯片中有表達的基因選出來
genes.present <- names(affy.experiment.PMA[affy.experiment.PMA != "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"])

# 54675
length(affy.experiment.PMA)
# 40673
length(genes.present)
affy.experiment.mas5.exprs.log.present <- affy.experiment.mas5.exprs.log[genes.present,]

# 3.2.8 設置FDR(False Discovery Rate)方法,來校正P值
p.adjust.methods
raw.pvals.present <- p.value.experiment.genes[genes.present]
fdr.pvals.present <- p.adjust(raw.pvals.present, method="fdr")

# 3.2.9 對FDR p值按從小到大排序
fdr.pvals.present.sorted <- fdr.pvals.present[order(fdr.pvals.present)]
length(fdr.pvals.present.sorted)
# 輸出FDR p值最小的10個基因
fdr.pvals.present.sorted[1:10]
fdr.pvals.present.sorted[40663:40673]
# 將結果整理成表格
expression.plus.pvals <- cbind(affy.experiment.mas5.exprs.log.present, raw.pvals.present, fdr.pvals.present)
write.table(expression.plus.pvals, "mas5_expression.plus.pvals.txt", sep="\t", quote=F)

# 3.2.10 找出那些至少在一個芯片中有表達,且在不同組織中表達有差異(FDR p值<0.23)的基因(探針組)
DE.fdr.probesets <- names(fdr.pvals.present[fdr.pvals.present < 0.05])
DE.fc.probesets <- names(unmut.to.mut.mean[unmut.to.mut.mean >1 | unmut.to.mut.mean<(-1)])
DE.probesets <- intersect(DE.fdr.probesets,DE.fc.probesets)

# 獲取那些至少在一個芯片中有表達且在不同組織中表達有差異的基因的表達量
unmut.to.mut.mean.mas5_DE <- unmut.to.mut.mean.data[DE.probesets, c.experiment]

# 3.2.11 構造熱圖
library(pheatmap)
pdf(file = "差異表達基因熱圖.pdf",width = 14,height = 35)
# pheatmap(unmut.to.mut.mean.mas5_DE,color=colorRampPalette(c("green","black","red"))(100),clustering_distance_rows = "correlation",clustering_distance_cols = "euclidean",clustering_method="complete")
pheatmap(unmut.to.mut.mean.mas5_DE,color=colorRampPalette(c("green","black","red"))(100),
         clustering_distance_rows = "correlation",clustering_distance_cols = "euclidean",clustering_method="complete")
dev.off()

rnames.mas5_DE <- as.matrix(rownames(unmut.to.mut.mean.mas5_DE))
colnames(rnames.mas5_DE) <- "probeset.id"

affy.experiment.mas5.DE.mat <- cbind(rnames.mas5_DE,unmut.to.mut.mean.mas5_DE)
#保存爲txt文件
write.table(affy.experiment.mas5.DE.mat, "unmut.to.mut.mean.mas5_DE.txt", sep="\t", quote=F,row.names=FALSE)
5.3 小結

本次實驗中,對P.value的一些感想:
P.value表示假設成立的條件下,重複n次試驗,獲得現有統計量以及極端情況下的概率。在樣本量較低,使用P.value值可靠性會比較低,因爲差異分爲組內差異與組間差異(樣品組與實驗組),如果樣本量少,那麼組內差異會比較大,那麼就會影響到我們需要關注的組間差異。
P.value代表着閾值,我們可以提高閾值的方式(即將P.value<0.05轉爲P.value<0.01),雖然這降低了假陽性的概率,不過通過這種方式設定標準,會讓原本可能真的存在表達差異的數據達不到我們設定的0.01的閾值標準,這就會提高了假陰性率。
芯片數據分析,熱圖,是直觀展示出基因表達變化的二維土層,其中數值以紅綠黑爲基本色調,能夠讓繁雜的數據一目瞭然,畢竟圖片比文字更能夠直觀的表達。
在本次差異分析中,GES36000樣本,右側文本爲基因編號,熱圖的每一行都是代表這一個基因,下方文本爲樣本編號,熱圖的每一列都是代表着一個樣本,左側爲樹狀結構,代表着基因之間的相似度聚落關係,頂部也爲樹狀結構,表示樣本之間的相似度聚落關係。其中,紅色表示上調,綠色表示下調
這裏我們可以看出,GES36000樣本,突變與未突變的樣本在一些基因上的差異表達還是比較明顯的。

6、 基因功能分析

6.1 註釋工具包

通過bioconductor收錄的芯片註釋包,將對應ID值進行映射,得到Gene symbol和Entrez ID兩種探針註釋信息,有了這些註釋,能夠直觀的瞭解每個ID值對應的是什麼術語?確定每個探針對應檢測哪個基因的表達。

在添加註釋工具包時,可以先通過show的方式來自動下載對應的註釋包,例如,本次實驗中是引用了hgu133plus2.db註釋包

參考代碼:

# 4.基因功能分析
# 4.1 註釋工具包
# 4.1.1 加載註釋工具包
# BiocManager::install(affydb)
library(XML)
library(annotate)
library(org.Hs.eg.db)

# 4.1.2 獲得基因芯片註釋包名稱
affy.experiment@annotation
# 4.1.3 加載註釋包"hgu133plus2.db"
affy.experiment.affydb <- annPkgName(affy.experiment@annotation, type="db")
library(affy.experiment.affydb, character.only=TRUE)
# 根據每個探針組的ID,獲取那些至少在一個芯片中有表達且在不同組織中表達有差異的基因名、Entrez ID
unmut.to.mut.mean.symbols <- getSYMBOL(rownames(unmut.to.mut.mean.mas5_DE),affy.experiment.affydb)
unmut.to.mut.mean.EntrezID <- getEG(rownames(unmut.to.mut.mean.mas5_DE),affy.experiment.affydb)
unmut.to.mut.mean.mas5.DE.anno=cbind(unmut.to.mut.mean.EntrezID,unmut.to.mut.mean.symbols,unmut.to.mut.mean.mas5_DE)
# 保存爲txt文件
write.table(unmut.to.mut.mean.mas5.DE.anno, "unmut.to.mut.mean.mas5.DE.anno.txt", sep="\t", quote=F,row.names = FALSE)

根據挑選出來的差異基因,GO富集分析會對實驗結果有補充提示的作用,我們可以通過GO富集分析差異基因,找到富集差異基因的GO分類目錄,其中數據結果可以保存爲本文,同時也可以保存爲html的方式,這提供了較大的便利,我們可以通過這些方式,更加直觀的尋找不同樣品的差異基因可能和哪一些基因功能的改變有關係
GO富集分析

參考代碼:

# 5 GO富集分析
# 加載所需R包
library(Matrix)
library(Category)
library(graph)
library(GOstats)
library("GO.db")
# 5.1 獲取基因芯片所有探針組與差異表達基因的EntrezID
# 提取芯片中affy.data所有探針組對應的EntrezID,注意保證uniq
entrezUniverse <- unique(getEG(rownames(affy.experiment),affy.experiment.affydb));
# 提取所有差異表達基因及其對應的EntrezID,去除na值,注意保證uniq
entrezSelected <- unique(unmut.to.mut.mean.EntrezID[!is.na(unmut.to.mut.mean.EntrezID)]);
# 設置GO富集分析的所有參數
params <- new("GOHyperGParams", geneIds = entrezSelected, universeGeneIds = entrezUniverse, 
              annotation = affy.experiment.affydb, ontology = "BP", pvalueCutoff = 0.001, conditional = FALSE, testDirection = "over");
# 5.2 對所有的GO term根據params參數做超幾何檢驗,並進行彙總
hgOver <- hyperGTest(params);
bp <- summary(hgOver) ;

# 5.3 同時生成所有GO term的檢驗結果文件,每個GOterm都有指向官方網站的鏈接,可以獲得其詳細信息
htmlReport(hgOver,  file='unmut.to.mut.mean.mas5_DE_go.html') ;
head(bp)
# 保存數據
write.table(bp, "unmut.to.mut.mean.mas5_DE_go.txt", sep="\t", quote=F,row.names = FALSE)

# 根據每個探針組的ID獲取對應基因Gene Symbol,並作爲新的一列
result$symbols <- getSYMBOL(rownames(result), affy.experiment.affydb)
# 根據探針ID獲取對應基因Entrez ID
result$EntrezID <- getEG(rownames(result), affy.experiment.affydb)
# 顯示前幾行
head(result)
nrow(result)	

四、結論

通過在NCBI下載一套人類基因(未突變和突變淋巴),其中包含了38組樣品基因,其中未突變14組,突變24組,前前後後對這38組數據編輯了5套實驗腳本,進行數據的載入、讀取、質量控制、質量分析、聚類分析、預處理、差異分析、註解、生成結果分析報告等。

整一套流程走了幾遍,主要收穫如下:基因芯片的差異分析,主要分爲數據的處理與分析;大多數人會側重在分析上,也爲了得到研究想要獲得的結果;但是數據的篩選與質量分析也是一個很重要的部分。

在本次研究之前(已廢棄),是以研究健康小鼠與患癌小鼠的唾液間的關係,但因爲基因質量不達標,選擇放棄這組實驗,另外在基因篩選上發現,如果樣品組與實驗組(突變與未突變)統計量少(38組數據,只人工採用20組數據),亦或是在p值設置閾值偏低,那麼組內的差異很可能因爲我們實驗設計的不合理,而升高,導致實驗結果十分不理想(前後5組實驗,對比分析結果)。

所以,我們在處理數據,進行基因差異分析,需要保證我們的結果的可靠性,那麼就需要我們注重我們在分析時的嚴謹性,並反覆測試不同實驗變量,對比結果,得出合理的結論。

五、參考資料

[1] NCBI NCBI介紹[EB/OL]https://www.ncbi.nlm.nih.gov/home/about/
[2] W3Cschool R介紹[EB/OL]https://www.w3cschool.cn/r/
[3] 朱猛進.差異表達基因的分析[CP/OL]http://blog.sciencenet.cn/blog-295006-403640.html
[4] 顯著檢驗與多重檢驗校正[S/OL] http://www.omicshare.com/forum/thread-260-1-12.html
[5] tommyhechina芯片數據分析(探針註釋)[S/OL] https://blog.csdn.net/tommyhechina/article/details/80409983

六、本文源碼

github的repo地址:https://github.com/PinkSmallFan/Pbioinformation

對應本文的R源碼:https://github.com/PinkSmallFan/Pbioinformation/tree/master/source_code/differential_analysis/Human_unmut_mut

PS:本文產生的源數據(例如芯片灰度圖、箱線圖、差異分析、聚集分析、PCA等等的數據與對應的原圖這裏就不共享啦~ 需要的話可以留言,酌情考慮)
PS2:如果這篇筆記有什麼不足,或者疑惑不解的地方(可能對小白不太友好),可以提出來,看到會回答(留個TODO給大家~)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章