常用批次校正方法简介

做批次效应校正这么多年,我见过太多人一上来就问:“到底该用哪个方法?”

其实吧,没有万能的方法。每种方法都有自己的脾气。ComBat 在基因组学里很流行,Limma 在转录组中常见,RUV 则擅长处理未知扰动。你想想看,选错方法就跟穿错鞋一样,跑不远。

这一章,我会结合自己踩过的坑,带你快速看懂几个主流方法的区别。别急,咱们一个一个来。

ComBat(Combating Batch Effects)

ComBat 是 Johnson 等人 2007 年提出的。逻辑说白了,就是用经验贝叶斯来估计批次效应。我个人觉得它是“稳妥派”的代表——参数调好了,效果很稳。

核心思路:假设每个基因都有一个“批次均值”和一个“批次方差”。ComBat 先估算它们,然后从数据里扣掉。

我习惯把它理解为“去中心化 + 去离散化”。为什么?因为 ComBat 同时调整均值和方差。这在许多 ADMET 项目中非常好用。尤其是当你的样本量不大时,它比简单标准化要稳健。

代码跑起来很简单,sva 包里一行就行:

library(sva)
# expression_data: 基因表达矩阵,行是基因,列是样本
# batch: 批次标签向量
combat_data <- ComBat(dat = expression_data, batch = batch)
注意:如果你有协变量(比如性别、年龄),记得加上 mod 参数。否则 ComBat 会把它们当批次效应一起干掉。

我曾经在一个 ADMET 项目中,因为漏了 age 这个协变量,结果校正后的数据跟真实生理趋势完全反了。嗯,那种感觉,就像炒菜忘了放盐。

Limma(Linear Models for Microarray Data)

Limma 本来是为微阵列设计的,后来被广泛用于 RNA-seq 和代谢组学。它的强项在于线性建模——你把批次当成一个因子,放进线性模型里就行。

说白了,Limma 是在做回归。它会告诉你:这个基因的表达到底受不受批次影响?

关键区别:ComBat 是两步走(先估计、后校正),Limma 是一步到位(建模时包含批次项)。两者哲学不同,但结果经常相似。

代码示例:

library(limma)
# 设计矩阵,包含感兴趣变量和批次
design <- model.matrix(~ condition + batch, data = meta)
# 拟合线性模型
fit <- lmFit(expression_data, design)
# 减去批次效应(使用其系数)
corrected_data <- removeBatchEffect(expression_data, batch = batch,
                                    design = design[, 1:2])

我个人在项目里经常把 Limma 和 ComBat 对比跑一遍。如果两者结果高度一致,我就可以放心了。如果差别大,那就得仔细检查数据——是不是有未记录的混扰因子?

RUV(Remove Unwanted Variation)

RUV 是 Gagnon-Bartsch 等人 2011 年提出的。它的假设很务实:我们肯定漏掉了一些未知的、混杂的变量。所以 RUV 通过“负对照基因”或者“重复样本”来直接估计这些未观察到的扰动。

你可以这么理解:ComBat 要求你知道批次标签,RUV 可以帮你在不知道的情况下,自动提取隐藏的嵌套因子。

适用场景:当你的批次信息不完整,或者认为批次效应与一些未记录的生理状态混杂时,RUV 是一个好选择。

代码示例:

library(ruvseq)
# 假设你会挑一些稳定表达的基因作为对照
scIdx <- matrix(1:100, ncol = 10)  # 示例对照基因索引
ruv_data <- RUVg(expression_data, scIdx, k = 2)

RUV 有一个坑要小心:k 值(要移除的未观测因子数)怎么选?选少了,残留效应还在;选多了,会把真实信号一起“洗掉”。我见过有人用 RUV 把生物学差异全给洗没了,数据变得比白纸还干净——可惜,那是错的。

常用方法对比

为了方便你快速决策,我做个表格。你在选方法前,可以对照看看:

方法 核心原理 需要批次标签? 是否需要协变量? 主要强项 主要局限
ComBat 经验贝叶斯(同时调整均值和方差) 是 建议提供 小样本稳健,操作简便 假设批次效应独立于生物学因素
Limma 线性建模,批次作为因子 是 必需 无缝融入差异表达分析 依赖模型正确指定
RUV 因子分析,从对照基因中学习未观测扰动 否 可选的 能处理未知混杂因子 对对照基因选择敏感

我在ADMET项目中的真实经验

说个我自己的教训。有一回处理一批肝微粒体代谢数据,来自两家不同的CRO。批次标签是分了,但两家的仪器型号不同,溶媒体系也不同。我起初用 ComBat,折腾半天效果很差。

后来才意识到:仪器型号差异比批次标签更剧烈。ComBat 只知道 A 和 B 批次不同,但它没有模型去区分“仪器 + 溶媒”这样复杂的嵌套结构。

那次我换了 RUV,通过一些已知不代谢的化合物作为对照,才把真正的代谢差异和仪器信号分离开来。嗯,那个项目让我明白了一件事:不要迷信任何方法,要理解你的数据是怎么产生的。

这也是为什么我在实战课程里,会把“实验设计”放在最前面讲。后面的章节,你会看到 ComBat 如何一步步处理 ADMET 数据,但我们今天先把这些方法的底色看透。

你别觉得这部分枯燥。一个仪器信号错误,可能让你多花三个月去追 root cause。我经历过,真心话。

知识体系总览

下面这张图,概括了这三种主流批次校正方法的定位与关系。你可以收藏起来,以后做选择时当参考:

批次校正方法知识结构 批次校正方法 ComBat Limma RUV 经验贝叶斯 均值和方差同时调整 小样本稳健 需批次标签 线性回归框架 批次作为固定效应 一键移除效果 依赖模型正确 因子分析 学习未观测混杂 不需要批次标签 对照基因选择关键 选择依据:批次标签完整性、样本量、是否已知混杂因子

这张图把三种方法放在一起对比。核心信息很直接:如果你的批次标签清晰、样本量偏小,ComBat 是个稳妥的起点。如果批次与其他变量有明显交互,Limma 的线性框架更灵活。如果批次标签不完整或者有未知混杂,RUV 值得一试,但要选好对照基因。

再多说一句:我一直强调“理解数据胜过套方法”。你可以在同一个数据集上把三种方法都试一遍,然后比较结果。如果差异巨大,往往说明数据本身有更隐蔽的问题。