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 方法选择决策流程

为了让你一眼看明白,我画了张流程图。按照这个走,基本不会错。

标准化方法选择决策流程 标准化方法选择决策流程 原始计数数据 只做可视化? 相对丰度(%) 差异分析 稀疏多零? CSS / 零膨胀模型 多数物种稳定? RLE(DESeq2 默认) TMM(edgeR) 💡 如果样本间文库大小差异极大,可结合 voom 或方差稳定变换(vst)

4.6 实操中的注意事项

  1. 检查缩放因子:无论用哪种方法,先打印sizeFactors或norm.factors,看看有没有异常值(比如0.1或10+)。有的话说明该样本质量差。
  2. 标准化后做QC:用boxplot看样本间的分布是否对齐。如果中位数差异大,换方法。
  3. 不要混合使用:同一个分析里别混用TMM和RLE的缩放因子。选定一种,全程一致。
  4. 零值处理:所有基于比值的标准化方法(TMM、RLE)都会受到大量零值的影响。如果数据稀疏率超过80%,优先考虑CSS或基于模型的方法(如ZINB)。

我的默认配置:现在只要做微生物组差异分析,我第一步跑DESeq2的RLE,同时用CSS做一遍敏感性验证。如果结果一致,放心;不一致就深挖原因。这招帮我省了不少返工时间。

4.7 综合对比表

方法 核心思想 适用软件包 典型场景
相对丰度 占总计数的比例 基础R 堆叠柱状图、饼图
CSS 累积和分位数缩放 metagenomeSeq 稀疏宏基因组数据
TMM 修剪M值加权平均 edgeR RNA-seq、细菌16S
RLE 几何均值中位数 DESeq2 默认首选,稳健