在使用Bioconductor 分析芯片數據(一)中我們使用的是芯片的原始數據(即*.cel文件)進行分析,但在大部分情況下我們是可以利用GEO數據庫中已有的表達矩陣來進行數據分析的。
本次我們選用GSE17975數據,這是一個雙通道芯片數據,研究Kawasaki disease的致病源頭。但是奇怪的是作者沒有上傳芯片源文件(*.cel文件),因此我們直接使用 表達矩陣數據進行分析。除了芯片外,我們還選擇了一個Kawasaki disease研究相關轉錄組數據,利用這兩種方法得到的差異基因的交集進行后續分析。
1、下載數據
這里依舊使用GEOquery包來下載數據:
> setwd('D:/TCGA/microarray_analysis/GSE17975/data/')
# 直接下載表達矩陣
> gmat <- getGEO('GSE17975',destdir = '.')
# 查看下里面是什么
> gmat
$GSE17975_series_matrix.txt.gz
ExpressionSet (storageMode: lockedEnvironment)
assayData: 22839 features, 3 samples
element names: exprs
protocolData: none
phenoData
sampleNames: GSM450153 GSM450154 GSM450155
varLabels: title geo_accession ... disease state:ch2 (48 total)
varMetadata: labelDescription
featureData
featureNames: AGhsA010102 AGhsA010103 ... AGhsS010824 (22839 total)
fvarLabels: ID Description ... SPOT_ID (13 total)
fvarMetadata: Column Description labelDescription
experimentData: use 'experimentData(object)'
Annotation: GPL1291
> class(gmat)
[1] "list"
> class(gmat[[1]])
[1] "ExpressionSet"
attr(,"package")
[1] "Biobase"
# 得到表達矩陣
> exprset <- exprs(gmat[[1]]); dim(exprset)
[1] 22839 3 # 可以看到表達矩陣中共有22839個基因(features),3個樣本
# 使用pData還可以查看更詳細的實驗相關信息
> pdata <- pData(exprset); dim(pdata)
[1] 3 48 # 有3行48列實驗數據信息
### 最后查看一下表達矩陣信息
> head(exprset)
GSM450153 GSM450154 GSM450155
AGhsA010102 0.8335 0.0257 0.0841
AGhsA010103 0.0649 -0.3715 -0.2740
AGhsA010105 -0.3237 -0.7539 -0.2793
AGhsA010106 0.4844 -0.6897 -0.4521
AGhsA010108 -1.7418 -0.8783 -3.5804
AGhsA010109 -0.3401 -1.2311 -0.5332
> class(exprset)
[1] "matrix"
# 轉換成data.frame數據結構方便后面使用
> exprset <- as.data.frame(exprset)
從上面可以發現,第一,雖然我們是直接下載的表達矩陣,但是其中也含有許多的實驗數據信息以及芯片平臺信息;第二通過直接查看表達矩陣他已經經過了標準化。
GEO Platform (GPL) 芯片平臺
GEO Sample (GSM) 樣本ID號
GEO Series (GSE) study的ID號
GEO Dataset (GDS) 數據集的ID號
2、篩選差異基因
limma進行差異表達分析需要準備好3個數據:表達矩陣,分組矩陣,差異比較矩陣。表達矩陣我們上面已經從GEO下載得到,只需要將芯片ID注釋為基因ID即可(也可在差異分析后進行注釋ID),但這里的芯片平臺比較罕見,找了半個小時沒找到對應的注釋包,因此直接下載其對應的注釋包寫代碼進行注釋。
> gpl1291 <- getGEO(filename='GPL1291.soft')
> colnames(Table(gpl1291))
[1] "ID" "Description" "CDS_ID"
[4] "GB_ACC" "Entrez Gene ID" "Symbol"
[7] "GeneName" "IPI ID" "GO Molecular Function"
[10] "GO Biological Process" "GO Cellular Component" "ORF"
[13] "SPOT_ID"
# 從上面可以看到GPL1291.soft文件中第一列為芯片ID,第5列和第6列為我們常用的ID,這里使用第6列Gene Symbol進行注釋
> symbol <- Table(gpl1291)[c('ID','Symbol')]; head(symbol)
ID Symbol
1 AGhsA010101 IFNA8
2 AGhsA010102 OGG1
3 AGhsA010103 KIR2DL2
4 AGhsA010104 FGFR2
5 AGhsA010105 GAGE1
6 AGhsA010106 VCX
### 最后我們只需要將兩個數據框merge一下就可以了
> exprset1 <- merge(x=exprset,y=symbol,by='ID',all.x=T);head(exprset1)
ID GSM450153 GSM450154 GSM450155 Symbol
1 AGhsA010102 0.8335 0.0257 0.0841 OGG1
2 AGhsA010103 0.0649 -0.3715 -0.2740 KIR2DL2
3 AGhsA010105 -0.3237 -0.7539 -0.2793 GAGE1
4 AGhsA010106 0.4844 -0.6897 -0.4521 VCX
5 AGhsA010108 -1.7418 -0.8783 -3.5804 EEF1A1
6 AGhsA010109 -0.3401 -1.2311 -0.5332 DAZ1
### 查看一下注釋有沒有一對多或者未注釋上的情況
> dim(exprset);dim(exprset1)
[1] 22839 4
[1] 22839 5
> exprset1.na <- exprset1[is.na(exprset1$Symbol)]; dim(exprset1.na)
[1] 22839 0
### 最后刪除ID列,并把symbol列調到第一列
> exprset2 <- exprset1[,-1]
> exprset3 <- exprset2[c(4,1,2,3)]; head(exprset3)
Symbol GSM450153 GSM450154 GSM450155
1 OGG1 0.8335 0.0257 0.0841
2 KIR2DL2 0.0649 -0.3715 -0.2740
3 GAGE1 -0.3237 -0.7539 -0.2793
4 VCX 0.4844 -0.6897 -0.4521
5 EEF1A1 -1.7418 -0.8783 -3.5804
6 DAZ1 -0.3401 -1.2311 -0.5332
從上面可以看到芯片ID注釋的結果很好,全部注釋上了而且沒有一對多的情況。
但是真的沒有問題嗎?會不會不是NA而是別的錯誤沒有被我們發現?讓我們再來做一次檢查。
### 查看一下有沒有空白字符
> failed <- exprset3[exprset3$Symbol=='',]
> head(failed)
Symbol GSM450153 GSM450154 GSM450155
16 -0.6712 -0.9269 -1.8417
50 -1.2345 0.1686 -0.5564
56 -0.5735 -1.0439 -1.5821
100 2.1925 -0.2059 0.4510
102 -2.1779 -0.6038 -0.3111
120 -0.4600 0.3663 -0.5886
> dim(failed)
[1] 7025 4 # (?Д?≡?Д?) 驚呆了有沒有,竟然有這么多沒有注釋上
### 難道是merge出錯了?不應該呀,查看一下官方給的注釋文件
> official.failed <- symbol[symbol$Symbol=='',]
> dim(official.failed)
[1] 10985 2 # 再次驚呆,官方給的注釋文件竟然有這么多空白。。。
### 最后,去除這些未注釋的ID
> exprset4 <- exprset3[exprset3$Symbol!='',]; dim(exprset4)
[1] 15814 4
最后我們得到了15814個注釋到的基因,相比之前少了7025個空的。所以,看起來簡簡單單的一步注釋,也到處都是坑啊。
由于數據比較老,這里各列的數據其實都是表示logFC,原文作者也是直接根據logFC選擇的差異基因進行后續分析的,因此這里我們也是直接使用3組平行試驗均值的|logFC|>1篩選差異基因進行后續分析。
> exprset4$mean <- (exprset4$GSM450153+exprset4$GSM450154+exprset4$GSM450155)/3
# 設定閾值|mean| >1 來篩選差異基因
> microexprgenes.differ <- exprset4[abs(exprset4$mean)>1,]
> microexprgenes.differ <- microexprgenes.differ[c(1,2,3,4)]
> dim(microexprgenes.differ)
[1] 938 4
這里我們篩選得了938個差異基因。然后去一下重復的gene symbol:
> microexprgenes.differ.dup <- microexprgenes.differ[duplicated(microexprgenes.differ$Symbol),]
> dim(microexprgenes.differ.dup)
[1] 99 4
> head(microexprgenes.differ.dup)
Symbol GSM450153 GSM450154 GSM450155
28 EEF1A1 -1.5649 -1.5187 -4.8573
677 FCGR1A 2.7853 2.5568 2.1375
1304 MATR3 -0.6394 -1.8890 -1.5522
2662 CCNB1IP1 -1.3921 -1.7959 -1.0923
3349 DHX9 -0.6461 -1.2042 -3.1203
4523 PSMB3 1.4895 1.1023 1.1603
> microexprgenes.differ <- microexprgenes.differ[!duplicated(microexprgenes.differ$Symbol),]
> dim(microexprgenes.differ)
[1] 839 4
最后我們得到了839個差異基因。
3、轉錄組差異基因篩選
這里直接使用的數據同樣也是關于Kawasaki disease研究的,GEO數據集為GSE64486,我們這里直接采用已經處理好的表達矩陣,但是我們這里使用的表達矩陣數據為GSE64486_untreated_vs_control_foldgenes_broad.txt.gz,即未治療的與對照組。
由于這里的數據是處理好的,我們可以直接設置logFC和P-value閾值來篩選差異基因。這里設置的閾值為P-value<0.05, |logFC|>1。
# 先讀取數據
> exprgenes <- read.table('GSE64486_untreated_vs_control_foldgenes_broad.txt',header = T, stringsAsFactors = F,sep='\t');head(exprgenes)
ID P.Value Q.Value adj.P.Val Gene.Symbol RefSeq.ID Entrez.ID Fold.Change
1 ENSG00000211896 7.601798e-25 1.645219e-20 1.645219e-20 IGHG1 NA 3500 101.77408
2 ENSG00000138755 3.384964e-09 1.495083e-06 1.495083e-06 CXCL9 NA 4283 45.22891
3 ENSG00000211897 3.600406e-16 8.657976e-13 8.657976e-13 IGHG3 NA 3502 45.06493
4 ENSG00000211899 9.557181e-17 2.711637e-13 2.711637e-13 IGHM NA 3507 41.89091
5 ENSG00000132465 1.444665e-14 2.233298e-11 2.233298e-11 IGJ NA 3512 36.47332
6 ENSG00000196735 3.890287e-21 2.806518e-17 2.806518e-17 HLA-DQA1 NA 3117 35.58685
# 篩選差異基因
> exprgenes.differ <- exprgenes[exprgenes$P.Value<0.05 & abs(exprgenes$Fold.Change)>1,]
> dim(exprgenes);dim(exprgenes.differ)
[1] 43285 8
[1] 7099 8
可以看到,這里一共篩選得到了7099個,得到的基因比較多,可能閾值太寬了,暫且先這樣接著做吧。
最后,還是檢查一下作者提供的數據注釋的gene symbol有沒有空的或者重復的:
> failed.symbol <- exprgenes.differ[duplicated(exprgenes.differ$Gene.Symbol),]
> head(failed.symbol)
ID P.Value Q.Value adj.P.Val Gene.Symbol RefSeq.ID Entrez.ID Fold.Change
120 ENSG00000252493 1.048966e-09 5.470419e-07 5.470419e-07 NA NA 7.509095
124 ENSG00000235300 3.582412e-09 1.566310e-06 1.566310e-06 NA NA 7.389821
132 ENSG00000251320 4.767764e-13 5.291607e-10 5.291607e-10 NA NA 7.135815
160 ENSG00000252862 7.716183e-16 1.757868e-12 1.757868e-12 NA NA 6.585053
167 ENSG00000251301 1.863953e-05 1.750134e-03 1.750134e-03 NA NA 6.419032
202 ENSG00000262151 4.473742e-05 3.500927e-03 3.500927e-03
> dim(failed.symbol)
[1] 2281 8
### 去除那些沒有gene symbol 信息的
> exprgenes.differ <- exprgenes.differ[!duplicated(exprgenes.differ$Gene.Symbol),]
> dim(exprgenes.differ)
[1] 4818 8
可以看到,一共2281個沒有注釋到gene symbol,去除后一共得到了4818個有gene symbol信息的差異基因。
我們可以發現,無論是芯片數據還是轉錄組數據,ID注釋的空白或者重復都是一個容易忽略的問題。有機會再進行較為深入的研究一下。
4、共有差異基因選取
前面我們分別得到了關于川崎病研究的芯片和轉錄組的差異基因,現在我們將這兩種數據合并取交集,以期得到與川崎病相關更為密切的基因。這里操作也比較簡單,直接使用R的merge函數即可。
> intersectgenes <- merge(x=microexprgenes.differ, y=exprgenes.differ, all=F,by.x='Symbol',by.y = 'Gene.Symbol')
> dim(intersectgenes)
[1] 128 11
> head(intersectgenes)
Symbol GSM450153 GSM450154 GSM450155 ID P.Value Q.Value adj.P.Val RefSeq.ID Entrez.ID Fold.Change
1 AIM1 -0.7155 -0.8391 -2.3808 ENSG00000112297 4.518321e-02 0.287315306 0.287315306 NA 202 2.555354
2 AK5 -1.9269 -0.6967 -0.5628 ENSG00000154027 7.907520e-05 0.005415775 0.005415775 NA 26289 1.350051
3 ANXA3 4.2110 0.8687 -0.1016 ENSG00000138772 3.122002e-02 0.229588586 0.229588586 NA 306 -2.328736
4 ARHGAP15 -0.0725 -1.5821 -2.0469 ENSG00000075884 6.321948e-05 0.004553170 0.004553170 NA 55843 5.064183
5 ASGR2 1.5563 1.4054 1.2066 ENSG00000161944 1.474010e-02 0.146976591 0.146976591 NA 433 2.061535
6 ATM -1.4344 -0.4961 -1.9324 ENSG00000149311 1.403235e-02 0.142613364 0.142613364 NA 472 2.313447
可以看到,這里我們一共得到了128個共有基因,我們將使用這128個共有基因進行后續分析。講這些基因寫入文件保存方便后面使用。
> write.table(intersectgenes,'../intersectgenes_logFC_broad.txt',row.names = F,sep='\t')
> write.table(intersectgenes$Symbol,'../intersectgenes.txt',row.names = F,sep='\t')
做個韋恩圖可視化看看:
vn <- venn.diagram(list(tissu=exprgenes.differ$Gene.Symbol, peripheral.blood=microexprgenes.differ$Symbol),filename='../intersectgenes.png',fill=c('red','green'),alpha=c(0.5,0.5),lty=2,cat.fontface=2,col='black',cat.col=c('red','green'))
總結
在這一部分,我們利用了兩份GEO數據庫中的內容,其中一份是芯片數據,另一個是轉錄組數據,對這兩個實驗數據線選定閾值篩選出差異基因,然后綜合兩個數據尋找共同的差異基因。
這部分操作比較簡單,都是直接用的原作者給出的表達矩陣,然后進行merge取交集即可。但是在操作過程中仍然有兩點是值得注意的:第一是各種基因ID之間的相互轉換關系,這里可以利用各個數據庫提供的ID對應文件進行轉換即可;第二點,在本次實踐中我們發現了大量的未成功注釋的、空白的或重復的gene symbol,這可以利用R中的duplicated
函數在每次進行數據分析時進行一次檢查。