基因芯片(Affymetrix)分析2:芯片數據預處理

(本文於2013.09.04更新)

基因芯片技術的特點是使用寡聚核苷酸探針檢測基因。前一節使用ReadAffy函數讀取CEL文件獲得的數據是探針水平的(probe level),即雜交信號,而芯片數據預處理的目的是將雜交信號轉成表達數據(即表達水平數據,expression level data)。存儲探針水平數據的是AffyBatch類對象,而表達水平數據爲ExpressionSet類對象。基因芯片探針水平數據處理的R軟件包有affy, affyPLM, affycomp, gcrma等,這些軟件包都很有用。如果沒有安裝可以通過運行下面R語句安裝:

library(BiocInstaller)
biocLite(c("affy","gcrma", "affyPLM", "affycomp"))

Affy芯片數據的預處理一般有三個步驟:

  • 背景處理(background adjustment)
  • 歸一化處理(normalization,或稱爲“標準化處理”)
  • 彙總(summarization)。

最後一步獲取表達水平數據。需要說明的是,每個步驟都有很多不同的處理方法(算法),選擇不同的處理方法對最終結果有非常大的影響。選擇哪種方法是仁者見仁智者見智,不同檔次的雜誌或編輯可能有不同的偏好。

1 需要了解的一點Affy芯片基礎知識

Affy基因芯片的探針長度爲25個鹼基,每個mRNA用11~20個探針去檢測,檢測同一個mRNA的一組探針稱爲probe sets。由於探針長度較短,爲保證雜交的特異性,affy公司爲每個基因設計了兩類探針,一類探針的序列與基因完全匹配,稱爲perfect match(PM)probes,另一類爲不匹配的探針,稱爲mismatch (MM)probes。PM和MM探針序列除第13個鹼基外完全一樣,在MM中把PM的第13個鹼基換成了互補鹼基。PM和MM探針成對出現。

我們先使用前一節的方法載入數據並修改芯片名稱:

library(affy)
library(tcltk)
filters <- matrix(c("CEL file", ".[Cc][Ee][Ll]", "All", ".*"), ncol = 2, byrow = T)
cel.files <- tk_choose.files(caption = "Select CELs", multi = TRUE,
                             filters = filters, index = 1)
# 最好查看一下文件名稱
basename(cel.files)
## [1] "NRID9780_Zarka_2-1_MT-0HCA(SOIL)_Rep1_ATH1.CEL" 
## [2] "NRID9781_Zarka_2-2_MT-0HCB(SOIL)_Rep2_ATH1.CEL" 
## [3] "NRID9782_Zarka_2-3_MT-1HCA(SOIL)_Rep1_ATH1.CEL" 
## [4] "NRID9783_Zarka_2-4_MT-1HCB(SOIL)_Rep2_ATH1.CEL" 
## [5] "NRID9784_Zarka_2-5_MT-24HCA(SOIL)_Rep1_ATH1.CEL"
## [6] "NRID9785_Zarka_2-6_MT-24HCB(SOIL)_Rep2_ATH1.CEL"
## [7] "NRID9786_Zarka_2-7_MT-7DCA(SOIL)_Rep1_ATH1.CEL" 
## [8] "NRID9787_Zarka_2-8_MT-7DCB(SOIL)_Rep2_ATH1.CEL"
data.raw <- ReadAffy(filenames = cel.files)
sampleNames(data.raw) <- paste("CHIP",1:length(cel.files),sep="")

用pm和mm函數可查看每個探針的檢測情況:

pm.data.raw <- pm(data.raw)
head(pm.data.raw, 2)
##        CHIP1 CHIP2 CHIP3 CHIP4 CHIP5 CHIP6 CHIP7 CHIP8
## 501131 127.0 166.3   112 139.8 111.3  85.5 126.3 102.8
## 251604 118.5 105.0    82 101.5  94.0  81.3 103.8 103.0
mm.data.raw <- mm(data.raw)
head(mm.data.raw, 2)
##        CHIP1 CHIP2 CHIP3 CHIP4 CHIP5 CHIP6 CHIP7 CHIP8
## 501843  89.0  88.0  80.5  91.0  77.0    75  79.0  72.0
## 252316 134.3  77.3  77.0 107.8  98.5    75  99.5  71.3

上面顯示的列名稱就是探針的名稱。而基因名稱用probeset名稱表示:

head(geneNames(data.raw))
## [1] "244901_at" "244902_at" "244903_at" "244904_at" "244905_at" "244906_at"

probeset不一定和實際基因一一對應,這些後面對探針進行基因名稱映射時會看到。

2 背景處理(background adjustment)

雖然說是背景處理,但是這一步既處理背景值,又處理噪聲信號。注意背景和噪聲是兩個概念,比如說鄉間夜晚的蛙叫聲雖嘈雜但很穩定,算是背景,如果突然來一聲狗叫,那就是噪聲。這兩者在統計上可以區分。

芯片的背景處理理論上很簡單,因爲Affy公司設計MM的目的就是檢測非特異雜交信號,PM -MM 不就結了?但是研究發現居然有多達30%的MM探針獲得的信號強度比相應PM探針的還強(嘿嘿),所以啊,研究者的飯碗就出來了,整些看起來還合理的方法吧。

R軟件包affy用於芯片背景噪聲消減的函數是bg.correct(),而MAS和RMA方法是最常用的兩種方法。

MAS方法將芯片分爲k(默認值爲16)個網格區域,用每個區域使用信號強度最低的2%探針去計算背景值和噪聲。RMA方法的原理比較複雜,可以參看文獻:

R. A. Irizarry, B. Hobbs, F. Collin, et al. Exploration, normalization, and summaries of high density oligonucleotide array probe level data. Biostatistics, 4:249–64, 2003b. 11, 18, 27, 232, 241, 432, 443。

data.rma <- bg.correct(data.raw, method="rma")
data.mas <- bg.correct(data.raw, method="mas")
class(data.rma)
## [1] "AffyBatch"
## attr(,"package")
## [1] "affy"
class(data.mas)
## [1] "AffyBatch"
## attr(,"package")
## [1] "affy"
class(data.raw)
## [1] "AffyBatch"
## attr(,"package")
## [1] "affy"

可以看到:ReadAffy()讀入的CEL芯片數據以AffyBatch類數據形式存儲,而背景消減後得到的依然是AffyBatch類數據。

MAS方法應用後PM和MM的信號強度都被重新計算。RMA方法僅使用PM探針數據,背景調整後MM的信號值不變。

head(pm(data.raw)-pm(data.mas),2)
##        CHIP1 CHIP2 CHIP3 CHIP4 CHIP5 CHIP6 CHIP7 CHIP8
## 501131 79.34 62.93 63.23 72.87 62.48 64.43 62.97 60.86
## 251604 77.57 63.06 63.73 80.69 63.07 66.53 63.33 60.34
head(pm(data.raw)-pm(data.rma),2)
##        CHIP1  CHIP2 CHIP3  CHIP4 CHIP5 CHIP6  CHIP7 CHIP8
## 501131 111.2 102.21 93.23 116.36 93.75 76.15 102.82 85.21
## 251604 103.9  88.69 72.57  90.75 82.23 72.64  87.75 85.32
head(mm(data.raw)-mm(data.mas),2)
##        CHIP1 CHIP2 CHIP3 CHIP4 CHIP5 CHIP6 CHIP7 CHIP8
## 501843 79.34 62.93 63.24 72.90 62.48 64.44 62.97 60.85
## 252316 77.56 63.06 63.73 80.66 63.07 66.51 63.33 60.34
#差值爲全部爲0,說明rma方法沒有對mm數值進行處理
head(mm(data.raw)-mm(data.rma),2)
##        CHIP1 CHIP2 CHIP3 CHIP4 CHIP5 CHIP6 CHIP7 CHIP8
## 501843     0     0     0     0     0     0     0     0
## 252316     0     0     0     0     0     0     0     0
identical(mm(data.raw), mm(data.rma))
## [1] TRUE

3 歸一化處理(normalization)

同一個RNA樣品用相同類型的幾塊芯片進行雜交,獲得的結果(信號強度等)都不可能完全相同,甚至差別很大。爲了使不同芯片獲得的結果具有可比性,必需進行歸一化處理。這一步的方法也很多。歸一化處理的affy函數爲normalize(),以Affybatch對象和處理方法爲參數。

3.1 線性縮放方法

這是Affy公司在其軟件(4.0和5.0版本)中使用的方法。這種方法先選擇一個芯片作爲參考,將其他芯片和參考芯片逐一做線性迴歸分析,用迴歸直線(沒有截距)對其他芯片的信號值做縮放。Affy公司的軟件做迴歸分析前去除了2%最強和最弱信號。使用很簡單,mas方法做背景消減後做歸一化分析的R語句是:

data.mas.ln <- normalize(data.mas, method = "constant")
head(pm(data.mas.ln)/pm(data.mas), 5)
##        CHIP1  CHIP2 CHIP3 CHIP4  CHIP5 CHIP6  CHIP7  CHIP8
## 501131     1 0.8788 1.002 1.141 0.9929 1.029 0.7578 0.8834
## 251604     1 0.8788 1.002 1.141 0.9929 1.029 0.7578 0.8834
## 261891     1 0.8788 1.002 1.141 0.9929 1.029 0.7578 0.8834
## 230387     1 0.8788 1.002 1.141 0.9929 1.029 0.7578 0.8834
## 217334     1 0.8788 1.002 1.141 0.9929 1.029 0.7578 0.8834
head(mm(data.mas.ln)/mm(data.mas), 5)
##        CHIP1  CHIP2 CHIP3 CHIP4  CHIP5 CHIP6  CHIP7  CHIP8
## 501843     1 0.8788 1.002 1.141 0.9929 1.029 0.7578 0.8834
## 252316     1 0.8788 1.002 1.141 0.9929 1.029 0.7578 0.8834
## 262603     1 0.8788 1.002 1.141 0.9929 1.029 0.7578 0.8834
## 231099     1 0.8788 1.002 1.141 0.9929 1.029 0.7578 0.8834
## 218046     1 0.8788 1.002 1.141 0.9929 1.029 0.7578 0.8834

可以看出,線性縮放方法以第一塊芯片爲參考,它的數值沒有被處理,而其他芯片都被縮放了。對同一塊芯片,不同探針的縮放倍數是一個常數。PM和MM的縮放方法完全一樣。

3.2 非線性縮放方法

此方法獲得的結果比線性方法要好,做非線性擬合時不是取整張芯片而僅取部分(一列)作爲基線。

data.mas.nl <- normalize(data.mas, method = "invariantset")
head(pm(data.mas.nl)/pm(data.mas), 5)
##        CHIP1 CHIP2 CHIP3 CHIP4 CHIP5 CHIP6  CHIP7  CHIP8
## 501131     1 1.050 1.417 1.359 1.399 2.023 1.0086 1.3124
## 251604     1 1.348 2.279 1.838 1.587 2.431 1.1126 1.3059
## 261891     1 1.564 1.397 1.675 1.497 1.556 1.3167 1.5509
## 230387     1 1.259 1.683 1.390 1.360 1.504 1.0145 1.2239
## 217334     1 1.009 1.127 1.241 1.229 1.263 0.8417 0.9934

可以看到,同一芯片不同探針的信號值的縮放倍數是不一樣的。

3.3 分位數(quantile)方法

這種方法認爲(或假設)每張芯片探針信號的經驗分佈函數應完全一樣,使用任兩張芯片的數據做QQ圖應該得到一條斜率爲1截距爲0的直線。

data.mas.qt <- normalize(data.mas, method = "quantiles")
head(pm(data.mas.qt)/pm(data.mas), 5)
##         CHIP1  CHIP2 CHIP3 CHIP4 CHIP5 CHIP6  CHIP7  CHIP8
## 501131 0.7176 0.9602 1.140 1.181 1.112 1.187 0.8145 1.0156
## 251604 0.6984 0.9814 1.199 1.209 1.112 1.172 0.8287 1.0143
## 261891 0.6939 0.9956 1.137 1.205 1.111 1.186 0.8389 1.0579
## 230387 0.7653 0.9777 1.171 1.183 1.115 1.185 0.8153 0.9921
## 217334 0.9508 0.9547 1.063 1.162 1.130 1.173 0.7945 0.9266

3.4 其他

如循環局部加權迴歸法(Cyclic loess)和 Contrasts方法。

data.rma.lo <- normalize(data.rma, method = "loess")
## Done with 1 vs 2 in iteration 1 
## Done with 1 vs 3 in iteration 1 
## Done with 1 vs 4 in iteration 1 
## Done with 1 vs 5 in iteration 1 
## Done with 1 vs 6 in iteration 1 
## Done with 1 vs 7 in iteration 1 
## Done with 1 vs 8 in iteration 1 
## Done with 2 vs 3 in iteration 1 
## Done with 2 vs 4 in iteration 1 
## Done with 2 vs 5 in iteration 1 
## Done with 2 vs 6 in iteration 1 
## Done with 2 vs 7 in iteration 1 
## Done with 2 vs 8 in iteration 1 
## Done with 3 vs 4 in iteration 1 
## Done with 3 vs 5 in iteration 1 
## Done with 3 vs 6 in iteration 1 
## Done with 3 vs 7 in iteration 1 
## Done with 3 vs 8 in iteration 1 
## Done with 4 vs 5 in iteration 1 
## Done with 4 vs 6 in iteration 1 
## Done with 4 vs 7 in iteration 1 
## Done with 4 vs 8 in iteration 1 
## Done with 5 vs 6 in iteration 1 
## Done with 5 vs 7 in iteration 1 
## Done with 5 vs 8 in iteration 1 
## Done with 6 vs 7 in iteration 1 
## Done with 6 vs 8 in iteration 1 
## Done with 7 vs 8 in iteration 1 
## 1 0.05775
data.rma.ct <- normalize(data.rma, method = "contrasts")
## Data size 502156 x 8 Desired subset size 5000 +- 50 
## Comuting ranks of old subset....Size of new subset:  109873 
## Comuting ranks of old subset....Size of new subset:  64185 
## Comuting ranks of old subset....Size of new subset:  27795 
## Comuting ranks of old subset....Size of new subset:  14886 
## Comuting ranks of old subset....Size of new subset:  12234 
## Comuting ranks of old subset....Size of new subset:  7835 
## Comuting ranks of old subset....Size of new subset:  7001 
## Comuting ranks of old subset....Size of new subset:  5289 
## Comuting ranks of old subset....Size of new subset:  5230 
## Comuting ranks of old subset....Size of new subset:  5164 
## Comuting ranks of old subset....Size of new subset:  5124 
## Comuting ranks of old subset....Size of new subset:  5065 
## Comuting ranks of old subset....Size of new subset:  5041 
## Fitting normalizing curve
## Normalizing chip  1 
## Normalizing chip  2 
## Normalizing chip  3 
## Normalizing chip  4 
## Normalizing chip  5 
## Normalizing chip  6 
## Normalizing chip  7 
## Normalizing chip  8

4 彙總(Summarization):

最後一步彙總是使用合適的統計方法通過probeset(包含多個探針)的雜交信號計算出計算表達量。affy包的函數爲computeExprSet。需要注意的是computeExprSet函數除需要指定統計方法外還需要指定PM校正的方式:computeExprSet(x, pmcorrect.method, summary.method, …)

兩個參數可以設定的值可以通過下面函數獲得:

pmcorrect.methods()
## [1] "mas"        "methods"    "pmonly"     "subtractmm"
generateExprSet.methods()
## [1] "avgdiff"      "liwong"       "mas"          "medianpolish"
## [5] "playerout"

常用的彙總方法是medianpolish, liwong和mas。liwong方法僅使用PM做背景校正(pmcorrect.method="pmonly")。例如:

eset.rma.liwong <- computeExprSet(data.rma.lo, pmcorrect.method="pmonly",
                                  summary.method="liwong")
## 22810 ids to be processed
## |                    |
## |####################|

計算過程需要一定的時間,耐心等候完成。最後的結果 ExpressionSet 類型數據:

class(eset.rma.liwong)
## [1] "ExpressionSet"
## attr(,"package")
## [1] "Biobase"
class(data.raw)
## [1] "AffyBatch"
## attr(,"package")
## [1] "affy"

5 三合一處理和“自動化”函數:

瞭解芯片預處理的原理和步驟後你完全可以用一個R函數完成三步處理。affy包提供的三合一處理函數爲 expresso(),用法爲:

# NOT RUN. 函數說明,不可運行。
expresso(
        afbatch,
        bg.correct = TRUE,
        bgcorrect.method = NULL,
        bgcorrect.param = list(),
        normalize = TRUE,
        normalize.method = NULL,
        normalize.param = list(),
        pmcorrect.method = NULL,
        pmcorrect.param = list(),
        summary.method = NULL,
        summary.param = list(),
        summary.subset = NULL,
        verbose = TRUE,
        widget = FALSE)

例如:

# NOT RUN:
eset.mas <- expresso(data.raw, bgcorrect.method="mas", normalize.method="constant",
                     pmcorrect.method="mas", summary.method="mas")

使用的各類方法可用bgcorrect.methods,pmcorrect.methods 和 express.summary.stat.methods函數了解。

expresso速度較慢,一些R軟件包提供速度較快的預編譯三合一函數,如affyPLM軟件包的threestep函數。affyPLM提供的處理方法很豐富,有興趣可以自學。

下面介紹介3個“自動化”函數,這些函數已經預定義了預處理各步驟所採用的方法和參數,不再需要設定。

5.1 mas5函數

由affy包提供:

eset.mas5 <- mas5(data.raw)
## background correction: mas 
## PM/MM correction : mas 
## expression values: mas 
## background correcting...done.
## 22810 ids to be processed
## |                    |
## |####################|

mas5據說是expresso函數和mas方法的封裝。但使用下面語句獲得的結果似乎與 mas5(data.raw)的結果不一樣(自己去驗證看看):

# NOT RUN:
expresso(data.raw, bgcorrect.method="mas", normalize=FALSE,
         pmcorrect.method="mas", summary.method="mas")

5.2 rma函數

也是由affy包提供,其背景處理方法爲rma法,歸一化處理使用分位數法,而彙總方法使用medianpolish:

eset.rma <- rma(data.raw)
## Background correcting
## Normalizing
## Calculating Expression

它等價於:

# NOT RUN:
eset.rma <- expresso(data.raw, bgcorrect.method="rma", normalize.method="quantiles",
                     pmcorrect.method="pmonly", summary.method="medianpolish")

但rma函數是預編譯好的C語言函數,速度非常快!

5.3 gcrma函數

由gcrma包提供。 Affy的軟件(比如mas方法)使用MM數據做背景處理,但由於MM出現的問題(上面提到過),這些方法可能高估了背景值。而rma方法在做背景處理時沒有使用MM數據,這可能又低估了背景值。MM序列公佈後有人對其特異性進行了評估,並使用這些評估結果建立了新方法。gcrma就是這樣的方法,也是封裝好的三合一方法。

library(gcrma)
eset.gcrma <- gcrma(data.raw)
## Adjusting for optical effect........Done.
## Computing affinities.Done.
## Adjusting for non-specific binding........Done.
## Normalizing
## Calculating Expression

6 芯片處理方法的優劣評估

芯片預處理的方法這麼多,哪個好?我選哪個?知道得越多越迷惑。幸好這些已經有人做了,牛人Rafael Irizarry 和 Leslie Cope專門寫了一個R軟件包affycomp用於方法評估。

評估方法的優劣必需有數據,而且是包含已知因素的數據。affycomp需要兩個系列的數據,一個是RNA稀釋系列芯片數據,稱爲Dilution data,另一個是使用了內參/外標RNA的芯片,稱爲Spike-in data。Spike-in RNA是在目標物種中不存在、但在芯片上含有相應檢測探針的RNA,比如Affy的擬南芥芯片上有幾個人或細菌的基因檢測探針。由於稀釋倍數已知,內參/外標的RNA量和雜交特異性也已知,所以結果可以預測,也就可以用做方法評估。對於嚴格的芯片實驗來說,這些實驗都是必須的。但是絕大多數人不做,因爲成本很高,尤其是隻做幾張芯片的時候,一般直接使用別人認可的方法如RMA或MAS。

基因芯片(Affymetrix)分析2:芯片數據預處理 - xxx - xxx的博客

7 Session Info

sessionInfo()
## R version 3.0.1 (2013-05-16)
## Platform: x86_64-pc-linux-gnu (64-bit)
## 
## locale:
##  [1] LC_CTYPE=zh_CN.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=zh_CN.UTF-8        LC_COLLATE=zh_CN.UTF-8    
##  [5] LC_MONETARY=zh_CN.UTF-8    LC_MESSAGES=zh_CN.UTF-8   
##  [7] LC_PAPER=C                 LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=zh_CN.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] parallel  tcltk     stats     graphics  grDevices utils     datasets 
## [8] methods   base     
## 
## other attached packages:
## [1] ath1121501probe_2.12.0 gcrma_2.33.1           ath1121501cdf_2.12.0  
## [4] AnnotationDbi_1.23.18  affy_1.39.2            Biobase_2.21.6        
## [7] BiocGenerics_0.7.4     zblog_0.0.1            knitr_1.4.1           
## 
## loaded via a namespace (and not attached):
##  [1] affyio_1.29.0         BiocInstaller_1.11.4  Biostrings_2.29.15   
##  [4] DBI_0.2-7             digest_0.6.3          evaluate_0.4.7       
##  [7] formatR_0.9           highr_0.2.1           IRanges_1.19.28      
## [10] preprocessCore_1.23.0 RSQLite_0.11.4        splines_3.0.1        
## [13] stats4_3.0.1          stringr_0.6.2         tools_3.0.1          
## [16] XVector_0.1.0         zlibbioc_1.7.0

Author: ZGUANG@LZU

Created: 2013-09-04 三 14:42

Emacs 24.3.1 (Org mode 8.0.5)

Validate XHTML 1.0


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