4. 数据标准化方法:相对丰度、CSS、TMM、RLE详解
拿到测序数据后,很多人上来就做差异分析。但你知道吗?不同样本的测序深度、文库大小、甚至批次效应都会让原始计数没法直接比较。我记得刚开始做宏基因组项目时,没做标准化就直接跑热图,结果全是假差异——那次教训挺深刻的。
标准化说白了就是给每个样本的计数“找个公平的基准”。不同方法思路不一样,适用场景也不同。下面我带你逐个捋一遍。
核心观点:没有万能的标准化方法。选择取决于你的数据特性和分析目标。
4.1 相对丰度(Relative Abundance)
这是最直观的方法——把每个物种的计数除以该样本的总计数,再乘以100%,得到百分比。用R实现极其简单:
# 假设 counts 是矩阵,行是物种,列是样本
rel_abund <- sweep(counts, 2, colSums(counts), "/") * 100
为什么很多人爱用它?因为解释起来方便:这个菌占了多少比例。但它有个硬伤——所有样本的总和都变成100%,丢失了绝对丰度信息。比如A样本测了100万条reads,B样本测了10万条,变成百分比后完全看不出总量差异。
我建议:只用于快速探索性分析,比如画堆叠柱状图、饼图。真正做差异检验时别用它。
| 优点 | 缺点 |
|---|---|
| 计算快、直观 | 丢失绝对丰度信息 |
| 适合可视化比例 | 对零值敏感,不适合稀疏数据 |
| 不受测序深度影响 | 假阳性率高(组成效应的根源) |
避坑:我曾经用相对丰度做PCA,结果所有样本聚成一团——完全看不出来分组差异。后来换成CSS标准化才分离出生物学差异。记住:相对丰度只能看“比例”,不能用于统计建模。
4.2 CSS(Cumulative Sum Scaling,累积和缩放)
CSS是metagenomeSeq包的拿手好戏。它的思路挺聪明:找所有样本中计数的“分位数”作为缩放因子,而不是用总计数。具体来说,它会计算每个样本的累积和曲线,找到那个“不再受零膨胀干扰”的点(通常是第50个百分位数),然后用这个点去缩放。
# 使用 metagenomeSeq 包
library(metagenomeSeq)
obj <- newMRexperiment(counts)
obj <- cumNorm(obj, p = cumNormStat(obj))
css_norm <- cumNormMat(obj)
# 或者用 phyloseq 的 wrapper
# 需要先安装,然后直接调 normalize() 函数
CSS的好处是:对稀疏矩阵(很多零)很稳健。因为零值不会干扰分位数估计。但它只适合比较样本间的相对丰度变化,不适合定量绝对丰度。我一般用它做有监督的差异丰度分析(比如metagenomeSeq的零膨胀高斯混合模型)。
| 参数 | 说明 |
|---|---|
| p(分位数) | 默认0.5,但可以用cumNormStat()自动估计 |
| 缩放因子 | 每个样本的累积和截止点 |
| 适用场景 | 稀疏矩阵、有大量零值的宏基因组数据 |
经验:CSS对低深度样本不太友好。如果某个样本总reads不到10万,它的分位数估计会很不稳定。建议先过滤低丰度OTU(平均丰度<10),再做CSS。
4.3 TMM(Trimmed Mean of M-values)
TMM来自edgeR包,最初是为RNA-seq设计的,但宏基因组数据也常用。它的核心是:找两个样本间表达量变化最稳定的那些基因(或OTU)来估计缩放因子。
具体来说,它会剔除上下30%的极端M值(log倍变化),然后用剩下的基因计算加权平均。这样做的好处是,那些差异很大的高丰度物种不会扭曲缩放因子。
library(edgeR)
dge <- DGEList(counts = counts)
dge <- calcNormFactors(dge, method = "TMM")
norm_factors <- dge$samples$norm.factors
# 归一化后的计数可以直接用 cpm(dge, normalized.lib.sizes = TRUE) 获得
tmm_cpm <- cpm(dge, normalized.lib.sizes = TRUE)
我自己在肠道菌群项目中用过TMM,效果不错。但要注意:TMM假设大多数物种没有差异。如果你的实验是极端对比(比如无菌vs正常),这个假设可能不成立。
| 特性 | TMM | RLE(见下一节) |
|---|---|---|
| 基准样本 | 用某个参考样本(默认第一个) | 用伪参考(所有样本的中位数) |
| 截断比例 | 默认上下30% | 默认上下30% |
| 适用数据类型 | RNA-seq,宏基因组的相对丰度比较 | 与TMM类似,但更稳健 |
曾经踩坑:有一组样本,其中一个全是低丰度物种,TMM的缩放因子直接变成了0.2,导致那个样本所有物种计数都被放大5倍。检查发现是参考样本选得太差。解决办法:用某个高质量的样本作为参考,或者改用RLE。
4.4 RLE(Relative Log Expression)
RLE是DESeq2的默认标准化方法。它的思路更优雅:对每个物种,计算其在所有样本中的几何均值,然后每个样本的每个物种计数除以这个几何均值,再取中位数作为缩放因子。
说白了,RLE假设大多数物种的表达量在样本间是稳定的。这个假设在很多微生物组数据中成立(因为核心菌群的存在)。
# DESeq2 方法
library(DESeq2)
dds <- DESeqDataSetFromMatrix(countData = counts,
colData = metadata,
design = ~ condition)
dds <- estimateSizeFactors(dds)
size_factors <- sizeFactors(dds)
rle_norm <- counts(dds, normalized = TRUE)
RLE比TMM更稳,因为它用的是中位数,而且伪参考不依赖任何特定样本。我用RLE做过几十个项目的差异分析,翻车案例极少。
| 方法 | 缩放因子计算 | 推荐R包 | 我的评分(5分满) |
|---|---|---|---|
| 相对丰度 | 总计数 | 基础R | ⭐ |
| CSS | 累积和分位数 | metagenomeSeq | ⭐⭐⭐⭐ |
| TMM | 修剪M值加权平均 | edgeR | ⭐⭐⭐ |
| RLE | 几何均值中位数 | DESeq2 | ⭐⭐⭐⭐⭐ |
实用技巧:如果你不确定用哪种,可以先跑一遍RLE。然后检查标准化后的样本间箱线图——如果中位数都对齐了,说明成功。如果还歪,换TMM或CSS试试。
4.5 方法选择决策流程
为了让你一眼看明白,我画了张流程图。按照这个走,基本不会错。
4.6 实操中的注意事项
- 检查缩放因子:无论用哪种方法,先打印sizeFactors或norm.factors,看看有没有异常值(比如0.1或10+)。有的话说明该样本质量差。
- 标准化后做QC:用boxplot看样本间的分布是否对齐。如果中位数差异大,换方法。
- 不要混合使用:同一个分析里别混用TMM和RLE的缩放因子。选定一种,全程一致。
- 零值处理:所有基于比值的标准化方法(TMM、RLE)都会受到大量零值的影响。如果数据稀疏率超过80%,优先考虑CSS或基于模型的方法(如ZINB)。
我的默认配置:现在只要做微生物组差异分析,我第一步跑DESeq2的RLE,同时用CSS做一遍敏感性验证。如果结果一致,放心;不一致就深挖原因。这招帮我省了不少返工时间。
4.7 综合对比表
| 方法 | 核心思想 | 适用软件包 | 典型场景 |
|---|---|---|---|
| 相对丰度 | 占总计数的比例 | 基础R | 堆叠柱状图、饼图 |
| CSS | 累积和分位数缩放 | metagenomeSeq | 稀疏宏基因组数据 |
| TMM | 修剪M值加权平均 | edgeR | RNA-seq、细菌16S |
| RLE | 几何均值中位数 | DESeq2 | 默认首选,稳健 |