R包sva去除批次效應

關于sva包

sva的用戶說明:http://www.bioconductor.org/packages/release/bioc/vignettes/sva/inst/doc/sva.pdf

其中關于去除批次效應的函數有CombatCombat_seq兩個,而Combat主要面對的是帶有小數的數據(比方說芯片數據),基于的是貝葉斯原理;而Combat_seq主打RNA-seq的count數據,基于負二項分布回歸

Combat

測試數據的設計矩陣為:



表達矩陣為:



按照說明書那樣,我們需要事先知道這些batch的變量類型
# 提取batch的信息
batch = pheno$batch
# 建立對照組模型,這不也可以省略
modcombat = model.matrix(~1, data=pheno)

# 去除批次效應
combat_edata1 = ComBat(dat=edata, batch=batch, mod=NULL, par.prior=TRUE,  prior.plots=FALSE)

這樣返回的就是去除批次效應后的數據了

而Combat函數的核心代碼:

# 輸入數據
dat=edata
batch=batch
mod = NULL    ## 忽略設計矩陣
par.prior = TRUE
prior.plots = FALSE
mean.only = FALSE
ref.batch = NULL

# 定義出批次效應的項
batch <- as.factor(batch)

# dat 為表達矩陣,s.data相當于標準化后的表達矩陣
s.data <- (dat-stand.mean)/(sqrt(var.pooled) %*% t(rep(1,n.array)))

# 找到相同levels的sample,并歸類
n.batch <- nlevels(batch)
  batches <- list()
  for (i in 1:n.batch) {
    ## 把相同 levels 的 sample 歸為一類,即 batches[[1]] 代表所有levels = 1 的sample
    batches[[i]] <- which(batch == levels(batch)[i])
  } # list of samples in each batch  

# 計算去除批次效應的表達矩陣
bayesdata <- s.data
## batches 代表有批次效應的sample
## 所有有批次效應的sample需要扣除批次效應的影響
for (i in batches){
    bayesdata[,i] <- (bayesdata[,i]-t(batch.design[i,]%*%gamma.star))/(sqrt(delta.star[j,])%*%t(rep(1,n.batches[j]))) 
    ### t(batch.design[i,]%*%gamma.star) 代表批次效應所引起的基因表達量的差異,這一部分是需要被扣除的
    j <- j+1
  }

# 最后乘上系數
 bayesdata <- (bayesdata*(sqrt(var.pooled)%*%t(rep(1,n.array))))+stand.mean # FIXME

而這段代碼的理論部分來自于文章《Adjusting batch effects in microarray expression data using empirical Bayes methods》

文章對去除批次效應分為了三步:
step_1:Standardize the data


簡單分析下各個因素對表達量的影響

其中:

  1. Yijg 代表 gene g for sample j from batch i
  2. αg 代表 overall gene expression,即 gene g 在所有sample中平均表達量
  3. X 代表 a design matrix for sample conditions,代表實驗設計所制定的矩陣
  4. βg 代表對X矩陣的回歸系數,代表不同設計矩陣各個因素下的效應值
  5. X·βg 代表設計矩陣各個因素除平均表達量αg以外的額外的表達值,對于sample j (因素 j)最后加上 αg 則代表sample j 中 gene g 的表達量
  6. γig 代表 the additive and multiplicative batch effects of batch i for gene g
  7. δig 代表 the additive and multiplicative batch effects of batch i for gene g

標準化

由上面的公式結合代碼我們不難看出,此時忽略設計矩陣

## 定義設計矩陣
## combine batch variable and covariates
design <- cbind(batchmod,mod)
## batchmod為與batch有關的設計矩陣,mod為實驗設計矩陣
  
# 均值的計算
stand.mean <- stand.mean+t(tmp %*% B.hat)
# 方差的計算
var.pooled <- ((dat-t(design %*% B.hat))^2) %*% rep(1/n.array,n.array)
## B.hat代表β.hat
## tmp為與batch相關的設計矩陣,即與,如果不考慮實驗設計因素,那么tmp為0矩陣

Step_2: EB batch effect parameter estimates using parametric empirical priors
假設每一個元素所服從分布如下:


顯而易見的是經過標準化后的sample j 中 gene g 的表達量的不同,完全是由于批次效應所導致(因為標準化過程以及扣除均值αg,實驗設計的差異部分 X·βg 的影響,僅剩下批次效應的影響)

假設標準化后的表達矩陣里面的元素值 Zijg 服從正態分布,均值為 γig(γig為the additive and multiplicative batch effects of batch i for gene g),而這些參數估計需要用到貝葉斯后驗來進行估計


假設 γig 服從正態分布,這個假設我有點吐槽,萬一 γig(批次效應所引起的差異值)并不服從這種分布呢?

并且作者定義

為批次效應所引起的基因表達量的差異,這一部分是需要被扣除的

Step_3: Adjust the data for batch effects


由上面式子我們知道,最終去除批次效應結果的主體是標準化的數據減去批次效應所引起的基因表達量的差異而得
其中
為扣除批次效應后的表達量
帶帽的
代表批次效應所引起的基因表達量的差異的估計值

Combat_seq

這個函數主打RNA-seq的count數據,而它的下載方式需要用:

# 下載方式
devtools::install_github("zhangyuqing/sva-devel")

# 示例數據
count_matrix <- matrix(rnbinom(400, size=10, prob=0.1),nrow=50, ncol=8)
batch <- c(rep(1, 4), rep(2, 4))
adjusted <- ComBat_seq(count_matrix, batch=batch, group=NULL)

我們參考這篇文獻來分析它的原理:《ComBat-Seq: batch effect adjustment for RNA-Seq count data》
Combat_seq基于的原理是負二項分布回歸

這里的負二項分布指的是基因的表達服從負二項分布,如下圖



橫坐標表示基因的表達量,縱坐標表示的是基因表達量在某個區間范圍內的頻率,那么整個count矩陣數據符合負二項分布,用具有這樣數據特點的矩陣做的回歸稱為負二項分布回歸


同樣的,它的基本模型也是線性模型,理解起來和Combat的是類似的

其中:

  1. μijg 代表 gene g for sample j from batch i
  2. αg 代表 overall gene expression,即 gene g 在所有sample中平均表達量
  3. Xj 代表 a design matrix for sample conditions,代表實驗設計所制定的矩陣
  4. βg 代表對X矩陣的回歸系數,代表不同設計矩陣各個因素下的效應值
  5. Xj·βg 代表設計矩陣各個因素除平均表達量αg以外的額外的表達值,對于sample j (因素 j)最后加上 αg 則代表sample j 中 gene g 的表達量
  6. γgi 代表批次效應 i 影響 gene g 的表達值從而產生差異的部分(均值)
  7. ** ?gi** 代表批次效應 i 影響 gene g 的表達值從而產生差異的部分(dispersion)
  8. Nj 代表文庫大小

而關于Combat_seq的核心代碼:

# 讀入相關的內容
## count_matrix為count矩陣
counts = count_matrix
## batch 為批次效應向量
batch=batch
group=NULL
covar_mod=NULL
full_mod=TRUE
shrink=FALSE
shrink.disp=FALSE
gene.subset.n=NULL


# 廣義線性模型擬合數據,即建立真實的基因表達量
## 這里的design代表的是batch的設計矩陣
## dge_obj$counts為counts矩陣
## 參數 phi_matrix 通過edgeR包中的函數estimateGLMCommonDisp進行估計
glm_f2 <- glmFit.default(dge_obj$counts, design=design, dispersion=phi_matrix, 
                         offset=new_offset, prior.count=1e-4) 
  

# gamma_hat 為glm_f2 模型的系數,代表不同batch對每個sample的影響
gamma_hat <- glm_f2$coefficients[, 1:n_batch]
# mu_hat為利用模型擬合的count值
mu_hat <- glm_f2$fitted.values
phi_hat <- do.call(cbind, genewise_disp_lst)

design矩陣

design矩陣的行為不同的sample1-8
而dge_obj$counts為counts矩陣,counts矩陣的行為不同的基因

前1-4個sample受到batch1的影響,后5-8個sample受到batch2的影響,由于batch的設計矩陣都是0,1型的因子變量,所以模型的系數就可以定義為γgi,即Xj·gamma_hat(X取值為0或1)對應的就是γgi(批次效應 i 影響 gene g 的表達值從而產生差異的部分)的值

然而去除批次效應所帶來影響需要將原始counts值,減去對應batch所帶來的影響γgi

mu_star <- matrix(NA, nrow=nrow(counts), ncol=ncol(counts))
## mu_hat 可以理解為count值
## vec2mat(gamma_star_mat[, jj], n_batches[jj])可以理解為batch的效應值 γgi,只不過將它做成矩陣形式方便計算
for(jj in 1:n_batch){
    ## count值減去batch的效應值 γgi,最終得到去除批次效應的結果
    mu_star[, batches_ind[[jj]]] <- exp(log(mu_hat[, batches_ind[[jj]]])-vec2mat(gamma_star_mat[, jj], n_batches[jj]))
  }

最后對 mu_star 進行整數化的矯正就可以得到最終結果了:


行為基因,列為sample1-8

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容