edgeR批次协变量建模与差异表达分析 - 第1节

edgeR 简介:为什么我们需要它?

说实话,做转录组分析的人,几乎都绕不开一个核心问题:差异表达基因。拿到表达矩阵之后,我们最想干的事就是——看看哪批基因在实验组和对照组之间玩命上蹿下跳。但理想很丰满,现实很骨感。原始 read count 数据直接拿来比,那结果基本没法看。

为什么?因为不同样本的测序深度不一样,基因长度不同,文库构建效率也有波动。这时候如果你拿原始计数直接做 t 检验,那就是在沙子上盖楼。我刚开始接触 RNA-seq 那会儿,就犯过这个错误。跑出来好多「显著差异」基因,结果一查,全是测序深度差异导致的假阳性。嗯,从那以后我就记住了:差异表达分析,必须用专门为 count 数据设计的工具。

edgeR 就是这类工具里的老牌战将。它隶属于 Bioconductor 家族,专门处理基因表达计数矩阵。它的核心武器是 负二项分布模型,说白了就是能更精准地描述 RNA-seq 数据的离散特性。普通的泊松分布假定均值和方差相等,但真实数据往往是方差远大于均值——这叫 overdispersion。edgeR 通过估计一个离散参数(dispersion),把这个问题扛了下来。

edgeR 的核心设计思想

你别把 edgeR 想得太玄乎。它的核心逻辑其实就三条:

  1. 基于测序深度的归一化:默认使用 TMM(trimmed mean of M-values)方法。它剔除那些极端高表达和差异极大的基因,用剩余基因的加权平均来校准样本间的测序深度差异。
  2. 负二项建模:用均值-方差关系来描述每个基因的表达波动。离散参数越小,说明基因表达越稳定;离散参数越大,说明基因受批次效应或其他噪声影响越严重。
  3. 经验贝叶斯收缩:这是 edgeR 的绝活。它会借整个数据集的力量来「收缩」单个基因的离散估计值,尤其是那些低表达基因。为什么?因为低表达基因的 read count 少,单靠它自己估计离散,误差巨大。借了邻基因的信息后,估计结果就稳健多了。
我的一个小习惯:拿到一个新数据集,我第一件事就是跑 edgeR 的 estimateDisp(),然后快速扫一眼 BCV(生物学变异系数)的分布。如果 BCV 超过 0.4,说明数据噪声很大,后面一定要小心批次效应校正。

edgeR 到底能解决什么问题?

你可能会问:那么多差异分析工具,为什么我偏偏要学 edgeR?我罗列几个它在实际项目中的典型应用场景:

  • 两组比较:比如正常 vs 疾病,最简单也最经典。
  • 多组比较:多个时间点、多个处理水平,edgeR 能处理广义线性模型。
  • 加入协变量:这就是我们这门课的核心——把批次、性别、年龄等 nuisance 因素作为协变量放进模型,消除它们对差异结果的干扰。
  • 多因子实验:比如同时看药物和时间的交互作用,edgeR 的 GLM 框架完全覆盖。
  • 说白了,只要你有基因表达计数矩阵,样本有明确的分组信息,edgeR 就基本能搞定。我个人还特别喜欢它的 cpm() 函数,把 count 转成 CPM(counts per million),做 QC 视觉检查的时候特别好使。

    安装 edgeR:别在第一步卡住

    安装这件事,听起来简单,但我在课上见过不少同学在这栽跟头。最常见的问题是什么?——版本冲突。R 的版本太老,或者 Bioconductor 的版本对不上。

    标准安装方式

    edgeR 是 Bioconductor 的包,所以你得用 BiocManager 来装。不要直接用 install.packages(),那个是从 CRAN 装的,虽然也能搜到一些包,但 Bioconductor 的包依赖链更复杂。

    # 第一步:确保 BiocManager 已安装
    if (!requireNamespace("BiocManager", quietly = TRUE))
        install.packages("BiocManager")
    
    # 第二步:安装 edgeR
    BiocManager::install("edgeR")
    
    # 第三步:验证安装
    library(edgeR)
    packageVersion("edgeR")

    我个人习惯在执行完上面三步后,顺手看一眼输出。如果没报错,并且能看到类似 [1] ‘4.2.0’ 这样的版本号,那就说明装上了。

    避坑指南:我曾经遇到一个用户,装了一天都没装上。最后发现他 R 版本是 3.6,而 edgeR 最新版需要 R >= 4.0。所以,如果你报错说「package not available」或「dependency xxx is not available」,先检查一下 R 版本。运行 R.version.string 看看,至少是 4.1 以上才保险。

    依赖包检查

    edgeR 的依赖不算多,但有几个关键包你必须留意:

    包名 用途 安装方式
    limma 线性模型框架,edgeR 的 GLM 实际依赖于它 BiocManager::install("limma")
    statmod 提供精确检验所需的分布函数 install.packages("statmod")
    splines R 自带,通常无需额外安装 R 内置

    你看,依赖其实很轻量。但为什么还要列出来?因为我在项目里碰到过这样的情况:limma 没更新到最新版,结果 edgeR 的 glmFit() 函数死活跑不出来。解决办法很简单:把这三个包都更新到最新。

    # 一键更新所有 Bioconductor 包
    BiocManager::install(ask = FALSE, update = TRUE)

    验证安装是否完整

    装好了,别急着关。跑一个最简单的 demo 验证一下环境:

    # 加载包
    library(edgeR)
    
    # 生成一个假数据矩阵:1000 个基因,4 个样本
    set.seed(42)
    counts <- matrix(rnbinom(4000, mu = 10, size = 0.2), nrow = 1000)
    
    # 创建分组
    group <- factor(c("A", "A", "B", "B"))
    
    # 创建 DGEList 对象
    y <- DGEList(counts = counts, group = group)
    
    # 运行过滤
    keep <- filterByExpr(y)
    y <- y[keep, , keep.lib.sizes = FALSE]
    
    # 归一化
    y <- calcNormFactors(y)
    
    # 查看结果
    head(y$samples)

    如果这段代码能无错跑通,说明你的 edgeR 环境就绪了。我看到 calcNormFactors 返回的 norm.factors 都在 0.9-1.1 之间,就放心了。

    为什么这么干? 这段代码模拟了 edgeR 标准分析的前四步:数据导入 → 低表达过滤 → 归一化 → 样本统计查看。每一步都是我们整个课程的基础。

    你可能会问:为什么非要跑一遍 demo?说实话,我在给客户部署分析流程的时候,每次都这么干。因为经常出现「装上了,但某个底层 C 库链接有问题」的情况。跑一段真实的代码,才是检验安装的唯一标准。

    本章知识体系速览

    edgeR 批次效应校正教程 · 第 1 章知识结构 📦 edgeR 核心 TMM 归一化 (测序深度校准) 负二项模型 (overdispersion 建模) 经验贝叶斯收缩 (稳健离散估计) 🛠 安装流程:BiocManager → edgeR → limma → 依赖检查 → Demo验证 两组 / 多组比较 协变量 + 批次校正 多因子交互实验

    这张图概括了本章的两条主线:edgeR 的设计思想(左侧三块核心能力)和学习路径(从安装走向实际应用)。你可以看到,三大设计思想都指向一个目标——让差异表达分析更稳健、更准确。而安装流程是整个课程的基础,没有这一步,后面的批次校正流程连跑都跑不了。

    给新手的建议:如果你以前用过 DESeq2,不要习惯性地把 DESeq2 的归一化逻辑套在 edgeR 上。两者虽然都基于负二项模型,但 edgeR 的 TMM 方法和 DESeq2 的 median-of-ratios 方法在数学细节上有差异。实战中,两个工具的结果通常趋势一致,但在低表达和高离散基因上会有分歧。我的做法是:主要分析用 edgeR,敏感性分析用 DESeq2 交叉验证。