edgeR 基本原理与特点:准似然 F 检验、经验贝叶斯、TMM 归一化
聊完 DESeq2,咱们来正经看看 edgeR。说实话,这两个工具名字听起来像兄弟,但底层逻辑差别不小。edgeR 是更早一批的差分表达分析工具,到现在还在广泛用,说明它有真本事。
edgeR 的核心思想:从计数到统计
edgeR 做的其实就一件事:判断一个基因在不同条件下的表达量变化,到底是生物学差异还是技术噪音。它的假设和 DESeq2 很像——都认为 RNA-seq 计数服从负二项分布。但 edgeR 的推导路径更“直接”一些。
我个人习惯把 edgeR 的处理流程分成三步:
- 归一化——纠正不同样本之间的测序深度和文库组成差异,用的是 TMM 方法。
- 分散估计——通过经验贝叶斯方法,借用所有基因的信息来稳定每个基因的分散参数。
- 统计检验——用准似然 F 检验或精确检验,计算每个基因的 p 值。
嗯,这里要注意,edgeR 最新版本主推的是准似然 F 检验(QL F-test),而不是早期版本里的精确检验。原因很简单——QL 方法对分散估计的稳健性更好。
一句话总结:edgeR 用负二项分布建模计数,用 TMM 处理文库偏差,用经验贝叶斯借力打力,最后用 QL F 检验给出结果。
TMM 归一化:为什么要多此一举?
很多初学者会问:DESeq2 用中位数比值归一化,edgeR 用 TMM(Trimmed Mean of M-values),到底谁对?
我在项目里对比过这两种方法。实际上它们都在解决同一个问题:不同样本之间,除了生物学差异,还有测序深度和 RNA 组成的影响。举个真实的例子——如果某个样本里高表达基因特别多,那其他基因的读数就会相对变少,看起来像下调了,其实不是。
TMM 的思路很简单:先选一个参考样本(比如所有样本的中位数库),然后对每个样本,删除两端极端的基因(trim),只保留中间部分的 log-fold-change,加权平均得到一个缩放因子。这个缩放因子就是该样本相对于参考样本的校正系数。
# edgeR 默认使用 TMM 归一化
library(edgeR)
y <- DGEList(counts = counts, group = group)
y <- calcNormFactors(y, method = "TMM")
# 查看归一化因子
y$samples$norm.factors
实际用的时候,TMM 和 DESeq2 的 median-of-ratios 结果往往非常接近。但 edgeR 的 TMM 在文库大小差异很大或噪声比较多的情况下,稍微稳健一点。
一个小技巧:如果你发现某个样本的 TMM 归一化因子明显偏离 1(比如 0.8 或 1.3),最好检查一下这个样本的质量。我遇到过好几次,归一化因子异常其实是样本污染的预兆。
经验贝叶斯:借力打力的智慧
RNA-seq 数据有个典型问题——基因数量几万个,但每个基因的重复样本可能只有两三个。你想想看,基于两三个重复去估计一个基因的方差,那结果怎么可能靠谱?
edgeR 的解决方案是经验贝叶斯收缩。它的做法分两步:
- 先算所有基因的初始分散估计,得到一个全局趋势(比如分散随表达量变化的曲线)。
- 然后对每个基因,把它的个体分散往这条趋势线上拉(shrink),拉多少取决于该基因的原始数据量。
这就像你给一个新手 chef 调味——他自己的判断可能偏差大,但让他参考老师的平均水平,就能做出差不多的菜。edgeR 就是那个老师。
边缘似然函数的具体推导我就不展开了,但你要知道:edgeR 里用的是准似然(quasi-likelihood)模型,它在经验贝叶斯的基础上,额外引入了一个准似然分散参数(phi),用来捕获基因特异性的方差变化。这就是 QL F 检验的基础。
| 参数 | 含义 | edgeR 里的命名 |
|---|---|---|
| common dispersion | 所有基因共有的分散 | common.dispersion |
| trended dispersion | 随表达量变化的分散均值 | trended.dispersion |
| tagwise dispersion | 每个基因自己的分散(经验贝叶斯收缩后) | tagwise.dispersion |
| quasi-likelihood dispersion | QL 模型的额外分散(phi) | QL.dispersion |
我曾经被朋友问:为什么 edgeR 要搞这么多个分散?我的回答是:每个分散对应数据里的一个不确定性来源。Common 是基线,trended 是全局模式,tagwise 是个体调整,QL 是最后的保险。层次越多,检验越稳健。
准似然 F 检验:edgeR 的终极武器
准似然 F 检验是 edgeR 3.x 版本以后的主推方法,替代了以前的精确检验。它的核心逻辑和线性模型有点像:
- 对每个基因拟合一个负二项广义线性模型,把条件、批次等因子放进去。
- 用准似然分散 phi 来调整模型中的方差。
- 通过 F 检验比较全模型和简化模型的残差。
为什么用 F 检验而不是卡方?因为 F 检验能更好地处理小样本情况,而且对分散估计的不确定性更鲁棒。
# QL F 检验的标准流程
y <- estimateDisp(y, design)
fit <- glmQLFit(y, design)
qlf <- glmQLFTest(fit, coef = 2) # 比较感兴趣的系数
topTags(qlf)
回忆一下,DESeq2 用的是 Wald 检验(或者 LRT 似然比检验)。这两个各有优劣。Wald 检验计算快,但需要分散估计准确;QL F 检验计算稍慢,但允许分散有一定波动,不那么容易假阳性。
一个坑:如果你用的 edgeR 版本比较旧(3.0 之前),默认的 exactTest() 是精确检验,准似然方法需要手动调用。建议升级到最新版,直接用 QL F 检验。
edgeR 的完整工作流程
下面这张图是我自己画的,把 edgeR 从原始计数到差异基因的链条放一块了。你盯着看两分钟,后面写代码就不慌了。
实际经验:什么时候选 edgeR 而不是 DESeq2?
我个人的经验是:如果样本量很小(比如每组 2 个重复),edgeR 的 QL F 检验比 DESeq2 的 Wald 检验更不容易假阳性。但反过来,如果样本量大(每组 10+),两者结果基本一致,这时我更看重计算速度——edgeR 快那么一点点。
还有一个场景:如果你的数据里有很多零计数基因,edgeR 不会像 DESeq2 那样做独立的零膨胀处理。edgeR 假设所有零都是负二项分布的自然结果。我遇到过一批植物转录组数据,里边有大量基因在某个处理条件下全零,edgeR 的表现其实不错,因为它不额外惩罚零。
最后给个关键提示:不论选 edgeR 还是 DESeq2,归一化方法的一致性一定要检查。我之前做跨平台比较时,发现一个包用 TMM、另一个用 RLE,结果差异基因列表从 500 个变成 1200 个。你说吓不吓人?