1. DESeq2 与 edgeR 简介:两种差异表达分析工具概述

做 RNA-seq 差异表达分析,绕不开两个名字:DESeq2 和 edgeR。我入行那会儿,实验室师兄丢给我一套双端测序数据,第一句话就是“你拿 edgeR 跑一下吧”。后来我发现,圈里人基本分成两派,有爱 DESeq2 的,也有死磕 edgeR 的。说白了,这两个工具解决的是同一个问题——找出不同条件下表达量有显著变化的基因,但背后的统计假设和处理细节差别挺大。

我先带你把这两个工具的核心思路捋一遍。之后你会明白,选哪个不只看个人习惯,更看你的数据长啥样、实验设计有多复杂。

1.1 它们到底在解决什么问题?

RNA-seq 数据有个天生麻烦:count 值波动大,重复少,而且表达量越高,波动越厉害。你直接拿 t 检验去比,假阳性能高到你怀疑人生。DESeq2 和 edgeR 都用了负二项分布(Negative Binomial)来建模,这样能同时处理均值与方差的关系,也就是所谓的“过离散”问题。

我简单解释一下:

  • 泊松分布要求方差等于均值,但 RNA-seq 数据方差通常比均值大很多。
  • 负二项分布多了一个离散参数,允许方差随均值灵活变化。
  • 两个工具的核心就是在估计这个离散参数,然后做统计检验。

核心区别一句话:DESeq2 用的是“收缩估计”(shrinkage),把离散度往全局曲线上拉;edgeR 先用经验贝叶斯估计基因特异的离散度,再用一个加权的条件似然方法做检验。

1.2 我眼中的 DESeq2

DESeq2 是 Simon Anders 和 Wolfgang Huber 在 2010 年(DESeq)的基础上发展出来的,2014 年出了正式论文。我个人非常喜欢它的稳健性——尤其在小样本量下表现不错。

DESeq2 是怎么工作的?

  1. 先对每个基因的 count 做归一化,用的方法叫“median of ratios”,消除文库深度和基因长度的影响。
  2. 然后估计每个基因的离散度,再用所有基因的离散度拟合一条曲线,把离散度往曲线上“收缩”。
  3. 最后用 Wald 检验或似然比检验找出差异基因。

我在项目中遇到过这种情况:一组只有 2 个生物学重复,另一组有 3 个重复。DESeq2 跑下来,假阳性控制得还可以。如果是 edgeR,同样的数据会警告离散度估计不准,需要手动加“prior n”。所以遇到极端小样本,我个人习惯先跑 DESeq2。

小技巧:DESeq2 的 results() 函数默认使用 apeglm 或 ashr 对 log2 fold change 做收缩,这在低表达基因上特别有用——能避免把那些表达量很低、随机波动很大的基因误判为差异。我一般不会关掉这个收缩。

1.3 edgeR 又有什么不同?

edgeR 是 Gordon Smyth 团队很早就推出的工具(2008 年),在转录组领域几乎是“老牌劲旅”。它的统计思路更强调“经验贝叶斯”,用一个加权似然的方法把各基因的离散度往一个共同基准上推。

edgeR 的典型流程:

  • 用 TMM(Trimmed Mean of M-values)做归一化,这是它的默认方法。
  • 估计基因特异的离散度,然后用经验贝叶斯算法(Cox-Reid 或 Tagwise)做“收缩”。
  • 使用精确检验(exact test)或广义线性模型(GLM)做差异检验。

我曾试过用 edgeR 处理一个多因子设计:时间点×处理条件。edgeR 的 GLM 框架非常灵活,可以轻松添加交互项。相比之下,DESeq2 的公式接口虽然也能做,但 edgeR 在复杂设计下的计算速度更快。

注意:edgeR 对 0 counts 的处理方式跟 DESeq2 不同。如果你的数据有很多全零基因,建议提前过滤掉。我曾经直接丢一个稀疏矩阵进 edgeR,结果离散度估计直接崩了,程序报错。后来做了过滤就稳了。

1.4 一张图看懂两个工具的核心逻辑

DESeq2 vs edgeR 核心流程对比 DESeq2 vs edgeR 核心流程对比 原始 Count 矩阵(各基因-样本) DESeq2:median of ratios 归一化 估计离散度 + 收缩(shrinkage) Wald 检验 / LRT 检验 结果:p 值、padj、LFC edgeR:TMM 归一化 经验贝叶斯估计离散度 精确检验 / 似然比检验 结果:p 值、FDR、logFC 两者都基于负二项分布,差别在于离散度估计策略和归一化方法

1.5 关键差异一览

我把工作中最常对比的几个点列成表格,方便你快速对照:

对比维度DESeq2edgeR
归一化方法median of ratiosTMM(Trimmed Mean of M-values)
离散度估计拟合 gamma-family GLM,再 shrinkage条件似然 + 经验贝叶斯
检验方法Wald 检验 或 似然比检验精确检验 或 GLM 似然比检验
对小样本的适应性非常好(内置稳健先验)需要手动控制 prior.n
复杂实验设计支持,公式接口灵活同样支持,GLM 多因子友好
计算速度偏慢(尤其样本量大时)较快
LFC 收缩默认提供(apeglm/ashr)需额外步骤或使用 glmTreat
输出结果结构DESeqDataSet 对象,易提取DGEList 对象,手动提取

1.6 选哪个?我的一点经验

说实话,很多场景下两个工具结果重合度很高。但你如果非要我给建议:

  • 如果你只有 2-3 个重复,尤其每个条件重复数不对称,先试 DESeq2。它的 shrinkage 可以帮你稳住离散度。
  • 如果你的实验设计很繁杂,比如有四个因子、多个交互项,edgeR 的 GLM 速度和灵活性会让日子更舒服。
  • 如果你特别在意 log2 fold change 不要被高估,DESeq2 默认的 apeglm 收缩很棒,边缘基因不会乱蹦。
  • 如果你需要做融合基因、多比对等非常规分析,edgeR 的底层数据结构更轻量,容易定制。

一个实战小坑:我曾经在两个批次合并的数据上,先用 DESeq2 跑了跑,发现很多明显的批次效应。DESeq2 内置了 ~batch+condition 公式,但需要调整设计矩阵。edgeR 用 blocking 也可以处理,但有时会丢失自由度。嗯,建议你在跑主分析前,先用 PCA 或多维缩放看看批次影响有多大。

1.7 数据准备:通用的第一步

不管用哪个工具,输入都长差不多。你需要一个基因×样本的 count 矩阵,每列是一个样本,每行是一个基因,单元格是比对后计数。不要自己手动做 RPKM/FPKM 归一化——工具自己会处理。

我常用的读取方式:

# 假设你已经有了 counts.csv,第一列是基因名,其他列是样本
library(DESeq2)
countData <- read.csv("counts.csv", row.names=1)
# 或者用 edgeR
library(edgeR)
counts <- readDGE(files = files, columns = c(1,2))  
# 如果你只有矩阵,直接用 DGEList(counts = countData)

注意:行名不能重复,count 值必须是整数。我之前收到过一版数据,有人提前做了 log2 转换……那个结果跑出来惨不忍睹。你一定要保留原始 count。

1.8 你需要掌握的 R 代码基础

这两个工具都是 R 包,我假设你至少会用 library()、read.csv()、data.frame 这些基础功能。如果你对 Bioconductor 的 SummarizedExperiment 或 DGEList 比较陌生,后面几章我会手把手带你写完整流程,不用担心。

嗯,这一章先把两个工具的背景搞清楚。下一部分我们直接上手实战——用同一套数据跑 DESeq2 和 edgeR,看结果差多少。到时候你再回头看这张表格,感受会很不一样。