基因芯片技術的特點使用寡聚核苷酸探針檢測基因。前一節使用ReadAffy函數讀取CEL文件獲得的數據是探針水平的(probe level),即雜交信號,而芯片數據預處理的目的是將雜交信號轉成表達數據(即表達水平數據,expression level data)。存儲探針水平數據的是AffyBatch類對象,而表達水平數據為ExpressionSet類對象。基因芯片探針水平數據處理的R軟件包有affy, affyPLM, affycomp, gcrma等,這些軟件包都很有用。如果沒有安裝可以通過運行下面R語句安裝:
source("http://bioconductor.org/biocLite.R")
biocLite(c("affy","gcrma","affyPLM","affycomp"))
Affy芯片數據的預處理一般有三個步驟:背景處理(background adjustment),歸一化處理(normalization,或稱為“標準化處理”),匯總(summarization)。最后一步獲取表達水平數據。需要說明的是,每個步驟都有很多不同的處理方法(算法),選擇不同的處理方法對最終結果有非常大的影響。選擇哪種方法是仁者見仁智者見智,不同檔次的雜志或編輯可能有不同的偏好。
0、需要了解的一點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)
the.filter<-matrix(c("CEL file (*.cel)","*.cel","All (*.*)","*.*"),ncol=2,byrow=T)
cel.files<-choose.files(caption="Select CEL files",multi=TRUE,filters=the.filter,index=1)
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
501131127.0166.3112139.8111.385.5126.3102.8
251604118.5105.082101.594.081.3103.8103.0
>mm.data.raw<-mm(data.raw)
>head(mm.data.raw,2)
CHIP1 CHIP2 CHIP3 CHIP4 CHIP5 CHIP6 CHIP7 CHIP8
50184389.088.080.591.077.07579.072.0
252316134.377.377.0107.898.57599.571.3
上面顯示的列名稱就是探針的名稱。而基因名稱用probeset名稱表示:
>head(geneNames(data.raw))
[1]"244901_at""244902_at""244903_at""244904_at""244905_at""244906_at"
probeset不一定和實際基因一一對應,這些后面對探針進行基因名稱映射時會看到。
一、背景處理(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")
Loadingrequiredpackage:AnnotationDbi
>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(the.data)
[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
50113179.3434462.9287863.2347172.8700362.4808264.4335962.9744760.85734
25160477.5727463.0641563.7300180.6878463.0687366.5250963.3347760.33844
>head(pm(data.raw)-pm(data.rma),2)
CHIP1???? CHIP2??? CHIP3???? CHIP4??? CHIP5??? CHIP6???? CHIP7??? CHIP8
501131111.2499102.2057693.22705116.3628293.7457176.14978102.8209485.21383
251604103.879588.6881172.5728690.7481582.2269372.6360087.7493285.31779
>head(mm(data.raw)-mm(data.mas),2)
CHIP1??? CHIP2??? CHIP3??? CHIP4??? CHIP5??? CHIP6??? CHIP7??? CHIP8
50184379.3370862.9294263.2363172.8975462.4842064.4415862.9721660.85470
25231677.5618163.0636263.7313980.6620563.0707266.5130063.3311360.34233
>head(mm(data.raw)-mm(data.rma),2)#差值為全部為0,說明rma方法沒有對mm數值進行處理
CHIP1 CHIP2 CHIP3 CHIP4 CHIP5 CHIP6 CHIP7 CHIP8
50184300000000
25231600000000
二、歸一化處理(normalization)
同一個RNA樣品用相同類型的幾塊芯片進行雜交,獲得的結果(信號強度等)都不可能完全相同,甚至差別很大。為了使不同芯片獲得的結果具有可比性,必需進行歸一化處理。這一步的方法也很多。歸一化處理的affy函數為normalize( ),以Affybatch對象和處理方法為參數。
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
50113110.87876461.0021781.1405490.99288791.0294440.75775370.8833788
25160410.87876461.0021781.1405490.99288791.0294440.75775370.8833788
26189110.87876461.0021781.1405490.99288791.0294440.75775370.8833788
23038710.87876461.0021781.1405490.99288791.0294440.75775370.8833788
21733410.87876461.0021781.1405490.99288791.0294440.75775370.8833788
>head(mm(data.mas.ln)/mm(data.mas),5)
CHIP1? ? CHIP2? ? CHIP3? ? CHIP4? ? CHIP5? ? CHIP6? ? CHIP7? ? CHIP8
50184310.87876461.0021781.1405490.99288791.0294440.75775370.8833788
25231610.87876461.0021781.1405490.99288791.0294440.75775370.8833788
26260310.87876461.0021781.1405490.99288791.0294440.75775370.8833788
23109910.87876461.0021781.1405490.99288791.0294440.75775370.8833788
21804610.87876461.0021781.1405490.99288791.0294440.75775370.8833788
可以看出,線性縮放方法以第一塊芯片為參考,它的數值沒有被處理,而其他芯片都被縮放了。對同一塊芯片,不同探針的縮放倍數是一個常數。PM和MM的縮放方法完全一樣。
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
50113111.0496001.4169841.3592821.3991642.0231091.00857861.3123854
25160411.3483262.2789291.8378301.5866652.4305501.11258041.3059096
26189111.5640441.3973761.6751831.4966641.5564771.31673551.5508943
23038711.2587541.6829281.3898361.3601181.5038931.01445911.2238827
21733411.0093941.1265551.2414241.2294021.2629490.84172530.9933603
可以看到,同一芯片不同探針的信號值的縮放倍數是不一樣的。
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
5011310.71763740.96021341.1402331.1807011.1115931.1868050.81452381.0155723
2516040.69840190.98141221.1985101.2091941.1117261.1722720.82872131.0143434
2618910.69387050.99556101.1367341.2050781.1106201.1856080.83887291.0579171
2303870.76529230.97767551.1711231.1830991.1148641.1850520.81528250.9921032
2173340.95075450.95468441.0633201.1620731.1304111.1729860.79450020.9265588
4、其他:如循環局部加權回歸法(Cyclic loess)和 Contrasts方法。
data.rma.lo<-normalize(data.rma,method="loess")
data.rma.ct<-normalize(data.rma,method="contrasts")
三、匯總(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""playerout"
常用的匯總方法是medianpolish, liwong和mas。liwong方法僅使用PM做背景校正(pmcorrect.method="pmonly")。例如:
>eset.rma.liwong<-computeExprSet(data.rma.lo,pmcorrect.method="pmonly",summary.method="liwong")
22810ids to be processed
||
|####################|
共有29個警告(用warnings()來顯示)
計算過程需要一定的時間,耐心等候完成。最后的結果 ExpressionSet 類型數據:
>class(eset.rma.liwong)
[1]"ExpressionSet"
attr(,"package")
[1]"Biobase"
>class(data.raw)
[1]"AffyBatch"
attr(,"package")
[1]"affy"
四、三合一處理和“自動化”函數:
了解芯片預處理的原理和步驟后你完全可以用一個R函數完成三步處理。affy包提供的三合一處理函數為 expresso( ),用法為:
expresso(
afbatch,
# background correction
bg.correct = TRUE,
bgcorrect.method = NULL,
bgcorrect.param = list(),
# normalize
normalize = TRUE,
normalize.method = NULL,
normalize.param = list(),
# pm correction
pmcorrect.method = NULL,
pmcorrect.param = list(),
# expression values
summary.method = NULL,
summary.param = list(),
summary.subset = NULL,
# misc.
verbose = TRUE,
widget = FALSE)
例如:
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個“自動化”函數,這些函數已經預定義了預處理各步驟所采用的方法和參數,不再需要設定。
1、mas5函數,由affy包提供:
>eset.mas5<-mas5(data.raw)
background correction:mas
PM/MM correction:mas
expression values:mas
background correcting...done.
22810ids to be processed
||
|####################|
mas5據說是expresso函數和mas方法的封裝。但使用下面語句獲得的結果似乎與 mas5(data.raw)的結果不一樣(自己去驗證看看):
expresso(data.raw, bgcorrect.method="mas", normalize=FALSE, pmcorrect.method="mas", summary.method="mas")
2、rma函數,也是由affy包提供,其背景處理方法為rma法,歸一化處理使用分位數法,而匯總方法使用medianpolish:
eset.rma<-rma(data.raw)
它等價于:
eset.rma<-expresso(data.raw,bgcorrect.method="rma",normalize.method="quantiles",pmcorrect.method="pmonly",summary.method="medianpolish")
但rma函數是預編譯好的C語言函數,速度非常快!
3、gcrma函數,由gcrma包提供:
Affy的軟件(比如mas方法)使用MM數據做背景處理,但由于MM出現的問題(上面提到過),這些方法可能高估了背景值。而rma方法在做背景處理時沒有使用MM數據,這可能又低估了背景值。MM序列公布后有人對其特異性進行了評估,并使用這些評估結果建立了新方法。gcrma就是這樣的方法,也是封裝好的三合一方法。
>eset.gcrma<-gcrma(data.raw)
Adjustingforoptical effect........Done.
Computingaffinities.Done.
Adjustingfornon-specific binding........Done.
Normalizing
CalculatingExpression
五、芯片處理方法的優劣評估
芯片預處理的方法這么多,哪個好?我選哪個?知道得越多越迷惑。幸好這些已經有人做了,牛人Rafael Irizarry 和 Leslie Cope專門寫了一個R軟件包affycomp用于方法評估。
評估方法的優劣必需有數據,而且是包含已知因素的數據。affycomp需要兩個系列的數據,一個是RNA稀釋系列芯片數據,稱為Dilution data,另一個是使用了內參/外標RNA的芯片,稱為Spike-in data。Spike-in RNA是在目標物種中不存在、但在芯片上含有相應檢測探針的RNA,比如Affy的擬南芥芯片上有幾個人或細菌的基因檢測探針。由于稀釋倍數已知,內參/外標的RNA量和雜交特異性也已知,所以結果可以預測,也就可以用做方法評估。對于嚴格的芯片實驗來說,這些實驗都是必須的。但是絕大多數人不做,因為成本很高,尤其是只做幾張芯片的時候,一般直接使用別人認可的方法如RMA或MAS。下面是affycomp說明文檔比較MAS5和RMA方法優劣的一個演示圖,軟件具體用法此處不做介紹: