3. DESeq 对象构建与 DESeq 函数核心参数:test、fitType、betaPrior 归纳总结

当你手里有一张干净的计数矩阵和实验设计表之后,下一步就是构建 DESeq 对象,然后跑 DESeq() 这个核心函数。很多人以为这步就是「点一下运行」,但事实上,三个关键参数——test、fitType、betaPrior——直接决定了差异基因的统计结果和后续可视化效果。

我接触过的项目里,有不止一次因为用了默认参数而错过重要生物学信号。比如某个 scRNA-seq 的模拟数据,用了默认 test="Wald" 就没检出某个已知的 marker 基因,换成 LRT 一下就出来了。你想想看,这要是没注意到,后面结论全歪了。

3.1 三个参数到底干啥的?

先把它们拆开看:

参数 默认值 影响范围
test "Wald" 差异检验的统计方法
fitType "parametric" 离散度–均值关系的拟合方式
betaPrior TRUE(当设计为多因子且无交互时) 对数倍数变化的先验收缩强度

这三个参数在 DESeq() 函数里的调用方式很简单:

dds <- DESeq(dds, test="Wald", fitType="parametric", betaPrior=TRUE)

但具体怎么选,咱们得一个一个看。

3.2 test 参数:Wald 还是 LRT?

Wald 检验是默认的。它会基于最大似然估计的系数和标准误,直接计算每个基因的 p 值。适合简单的两组比较,速度快,输出直接。但有个坑——它依赖标准误的准确估计。如果你的样本量极小(比如只有 3 个样本),或者数据离散度异常,Wald 结果可能会膨胀假阳性。

LRT(似然比检验)则需要你提供一个简化模型(reduced formula)。它会比较完整模型和简化模型的拟合优度,用来检验多个系数是否同时为零。适合多因子设计、时间序列或交互效应。我在做一个时间点 vs 对照的实验时,用了 LRT 一次性检测所有时间点的变化,避免逐对比较的多次检验校正问题。

举个例子:假设你的 design 是 ~ treatment + time,想检验 treatment 效应是否显著:

dds_full <- DESeq(dds, test="LRT", reduced=~ time)
results(dds_full)

注意:LRT 必须指定 reduced 参数,否则报错。

个人经验:如果实验只有两组(比如 treat vs control),直接用 Wald 就够了。一旦涉及多因子或时间序列,我几乎总是先用 LRT 做全局筛选,再对显著基因做 post-hoc 分析。

3.3 fitType 参数:离散度拟合的“发动机”

DESeq2 的核心创新之一是根据基因表达均值来估计离散度(dispersion)。fitType 决定了用哪种曲线去拟合均值–离散度关系。

  • parametric(默认):用一个参数化的代数函数(类似 a/mean + b)去拟合。效果稳定,在大多数 RNA-seq 数据上表现良好。但如果你的数据有严重批次效应或异常值,拟合曲线可能走偏。
  • local:用局部加权回归(loess)去拟合,更灵活。我记得在一个酵母细胞周期数据上,因为样本间的离散度差异非常大,用 parametric 拟合出的曲线跟实际散点差很远,换成 local 就紧跟数据了。
  • mean:直接用每个基因的离散度等于该均值组的平均离散度(不依赖曲线)。极少用,除非 param 和 local 都报错。

怎么选?看诊断图:跑完 DESeq() 后,用 plotDispEsts(dds) 画一下。如果红色的拟合线被大部分黑点(基因)包裹,说明拟合 ok;如果拟合线明显偏离了云团,就换 fitType。

我曾经踩过的坑:在处理一个混合细胞系数据时,用默认 parametric 跑 DE 结果,火山图的 p 值分布明显偏双峰。一查,原来是部分基因的离散度被严重高估。换用 local 后 p 值分布回归均匀,最后多发现了 300 多个差异基因。

3.4 betaPrior 参数:要不要给 log2FC 戴个“紧箍咒”?

betaPrior 控制是否对对数倍数变化(log2 fold change)施加先验收缩。默认是 TRUE(当设计中无交互项时)。它的作用是:那些表达量很低或波动很大的基因,它们算出的 log2FC 往往极端不靠谱(比如 log2FC = 20),先验会把它们往 0 方向拉一拉。

什么时候改成 FALSE?

  • 你的设计中有交互项(比如 ~ treatment*time),因为交互项的稀疏性,先验可能产生收缩偏差。
  • 你想直接用 log2FC 做排序或 GSEA,不希望任何收缩影响。
  • 样本量大(比如每组 20+),离散度估计本身就很稳定,收缩可有可无。

但注意:关闭先验后,低表达基因的 log2FC 会非常“跳”,后续 MA 图上会看到很多毛刺。

# 关闭先验的例子
dds <- DESeq(dds, betaPrior=FALSE)
一句话总结:如果你不确定,就用默认。只有在做交互模型或你要原始 log2FC 做下游分析时,才考虑关掉 betaPrior。

3.5 知识结构图:三个参数如何影响 DESeq 对象

DESeq 对象构建与参数影响流程 DESeqDataSet DESeq( ) 核心参数 test + fitType + betaPrior test Wald / LRT fitType parametric / local / mean betaPrior TRUE / FALSE p值检验方式 影响统计功效 离散度拟合曲线 影响方差估计 log2FC 收缩 影响效应大小 DESeqDataSet (结果对象)

3.6 参数选择速查表

场景 推荐 test 推荐 fitType 推荐 betaPrior
两组比较(例:Tumor vs Normal) Wald parametric(默认) TRUE(默认)
多组比较 / 时间序列 LRT(需指定 reduced) local(若离散度拟合不佳) TRUE(默认)
有交互项设计(如 treatment*time) Wald 或 LRT parametric FALSE(避免收缩偏差)
样本量极大(每组 > 20) Wald parametric FALSE(可不收缩)
极低表达基因过多(如 scRNA-seq 模拟) LRT local TRUE(收缩稳住极端 log2FC)
实用原则:先用默认参数跑一次,画 dispersion 诊断图和 p-value 直方图。如果看到异常(比如 p 值双峰、离散度拟合线明显偏离),再一步步调整这三个参数。别一口气全改,不然你不知道是谁救了你的结果。

好了,这章的内容就是这么多。记住这三个参数不是摆设,每个都值得你花几分钟去理解它们在做什么。下次跑 DESeq() 之前,先问自己:我这次实验设计需要 LRT 吗?离散度拟合靠谱吗?log2FC 需要收缩吗?想清楚了再点运行。