微生物组差异丰度分析:ALDEx2/ANCOM-BC2/MaAsLin3¶
一句话概述¶
差异丰度分析就是回答"哪些菌在两组之间真的不一样?"——听起来简单,但微生物数据的组成性、零膨胀、高维度让这变成了生信领域最有争议的问题之一。
核心知识点表格¶
| 知识点 | 说明 |
|---|---|
| 组成性数据 | 微生物丰度是相对丰度,加起来等于100%,一个上升必有别的下降 |
| 零膨胀 | 大量物种在很多样本中丰度为0 |
| ALDEx2 | 贝叶斯框架+CLR变换,最保守但最一致的方法 |
| ANCOM-BC2 | 估计样本特异性偏差,支持多组和重复测量 |
| MaAsLin3 | 2025年发布,同时检测丰度和存在性关联 |
| 核心问题 | 不同方法得出不同结果,尚无金标准 |
白话解释¶
假设你在比较两个班级的成绩分布: - 传统做法:直接比较每科平均分 → 简单但可能有偏 - 微生物数据的问题: 你只知道每科的排名占比(相对丰度),不知道实际分数(绝对丰度)
比如:A班数学占30%,B班数学占20%。你能说"A班数学更好"吗?不一定!可能只是A班英语考得太差拉低了其他科目的比例,数学实际分数可能一样。
这就是组成性数据的核心陷阱——你看到的差异可能只是"此消彼长"的假象。
三种工具各有应对策略: - ALDEx2:先用统计方法"脱掉比例的帽子"(CLR变换),再做检验 - ANCOM-BC2:估计每个样本的"测序偏差",校正后再比较 - MaAsLin3:把"菌有没有"和"菌有多少"分开分析
ALDEx2¶
白话解释: ALDEx2是最保守的方法——宁可漏掉真差异,也不报假差异。它用贝叶斯框架处理零值问题,用CLR变换处理组成性问题,是可重复性最高的方法之一(2025年研究显示重复率79%)。
# ====== R语言实现 ======
# 安装ALDEx2
if (!require("BiocManager")) install.packages("BiocManager") # 安装BiocManager
BiocManager::install("ALDEx2") # 安装ALDEx2
library(ALDEx2) # 加载ALDEx2
# 读取数据
# counts: 行=物种/ASV,列=样本,值=原始计数
counts <- read.csv("otu_table.csv", row.names = 1) # 读取OTU表
groups <- read.csv("metadata.csv")$Group # 读取分组信息
# 第一步:CLR变换 + 蒙特卡洛采样
# ALDEx2先从贝叶斯Dirichlet先验采样,再做CLR变换
# mc.samples=128表示采样128次取平均
aldex_clr <- aldex.clr(
reads = counts, # 输入原始计数矩阵
conds = groups, # 分组条件(如"T2D"和"Control")
mc.samples = 128, # 蒙特卡洛采样次数
denom = "all" # 使用所有特征作为CLR的分母
)
# 第二步:统计检验
# 两组比较
aldex_test <- aldex.ttest(
aldex_clr, # 输入CLR变换后的数据
paired.test = FALSE # 非配对检验
)
# 效应量计算
aldex_effect <- aldex.effect(
aldex_clr # 计算效应量
)
# 合并所有结果
aldex_results <- data.frame(aldex_test, aldex_effect) # 合并结果
# 第三步:筛选显著差异的物种
sig_aldex <- aldex_results[
aldex_results$wi.eBH < 0.05 & # BH校正后的Wilcoxon p值<0.05
abs(aldex_results$effect) > 1, # 效应量绝对值>1
]
cat("ALDEx2发现的显著差异物种数:", nrow(sig_aldex), "\n") # 打印数量
# 可视化:效应量图
aldex.plot(aldex_results, type = "MA") # MA图
aldex.plot(aldex_results, type = "MW") # MW图(效应量 vs 差异)
ALDEx2结果解读¶
# 关键列说明:
# we.ep — Welch t检验的原始p值
# we.eBH — Welch t检验的BH校正p值
# wi.ep — Wilcoxon检验的原始p值
# wi.eBH — Wilcoxon检验的BH校正p值
# effect — 效应量(衡量差异大小,>1为大效应)
# overlap — 两组分布的重叠度(0=完全不重叠,1=完全重叠)
# 推荐使用 wi.eBH(Wilcoxon更稳健)+ effect 联合判断
ANCOM-BC2¶
白话解释: ANCOM-BC2的核心思想是"校正测序偏差"。不同样本的总reads数不同,导致看到的相对丰度有偏。ANCOM-BC2用EM算法估计每个样本的偏差,然后校正再做比较。它还支持多组比较和重复测量设计。
# 安装ANCOM-BC2
BiocManager::install("ANCOMBC") # 安装
library(ANCOMBC) # 加载ANCOMBC
library(phyloseq) # 加载phyloseq(用于数据管理)
# 创建phyloseq对象
otu <- otu_table(as.matrix(counts), taxa_are_rows = TRUE) # OTU表
meta <- sample_data(metadata) # 元数据
tax <- tax_table(as.matrix(taxonomy)) # 分类信息
ps <- phyloseq(otu, meta, tax) # 合并为phyloseq对象
# 运行ANCOM-BC2
ancombc2_result <- ancombc2(
data = ps, # 输入phyloseq对象
fix_formula = "Group", # 固定效应公式(分组变量)
p_adj_method = "BH", # p值校正方法
prv_cut = 0.10, # 最低流行度阈值(至少10%样本中出现)
lib_cut = 1000, # 最低文库大小
group = "Group", # 分组变量名
struc_zero = TRUE, # 检测结构零
neg_lb = TRUE, # 使用负下界估计
pseudo_cnt = TRUE, # 添加伪计数
pairwise = TRUE, # 多组两两比较
global = TRUE # 全局检验
)
# 提取结果
res <- ancombc2_result$res # 差异丰度结果表
# 筛选显著差异的物种
sig_ancombc <- res[res$q_GroupT2D < 0.05, ] # BH校正q值<0.05
cat("ANCOM-BC2发现的显著差异物种数:", nrow(sig_ancombc), "\n")
# 查看结构零(某组中完全不存在的物种)
struc_zero <- ancombc2_result$zero_ind # 结构零指示矩阵
ANCOM-BC2处理零值的策略¶
# ANCOM-BC2将零值分为三类:
# 1. 异常零(Outlier zeros) → 当作缺失值处理
# 2. 结构零(Structural zeros) → 一组完全不存在,直接标为差异显著
# 3. 采样零(Sampling zeros) → 用伪计数替换
#
# 还会检验结果对伪计数大小的敏感性
MaAsLin3(2025年最新发布)¶
白话解释: MaAsLin3是Huttenhower实验室2025年发表在Nature Methods的新方法。它最大的创新是同时分析丰度关联和存在性关联——不仅看菌"有多少"的差异,还看菌"有没有"的差异。
# 安装MaAsLin3
# devtools::install_github("biobakery/maaslin3") # 从GitHub安装
BiocManager::install("maaslin3") # 或从Bioconductor安装
library(maaslin3) # 加载MaAsLin3
# 准备输入数据
# input_data: 行=样本,列=物种/通路,值=丰度
# input_metadata: 行=样本,列=元数据变量
# 运行MaAsLin3
maaslin3_results <- maaslin3(
input_data = "otu_table.tsv", # 输入丰度表
input_metadata = "metadata.tsv", # 输入元数据
output = "maaslin3_output", # 输出目录
fixed_effects = c("Group", "Age", "BMI"), # 固定效应
random_effects = c("SubjectID"), # 随机效应(纵向数据时使用)
normalization = "TSS", # 标准化方法:总和缩放
transform = "LOG", # 变换方法:对数变换
analysis_type = "PREVALENCE,ABUNDANCE", # 同时分析存在性和丰度
min_prevalence = 0.1, # 最低流行度10%
min_abundance = 0.0001, # 最低丰度阈值
correction = "BH", # 多重比较校正
cores = 4 # 并行核心数
)
# MaAsLin3输出:
# 1. all_results.tsv — 完整结果表
# 2. significant_results.tsv — 显著结果
# 3. 丰度关联 + 存在性关联分别报告
MaAsLin3处理组成性¶
# MaAsLin3可以通过多种方式处理组成性:
# 方法1:使用实验方法获得的绝对丰度(如qPCR校正)
# 设置 normalization = "NONE"
# 方法2:使用spike-in标准品校正
# 设置 normalization = "NONE",输入校正后的数据
# 方法3:计算CLR变换(无实验校正时)
# 设置 normalization = "CLR"
三种方法对比¶
| 特性 | ALDEx2 | ANCOM-BC2 | MaAsLin3 |
|---|---|---|---|
| 发表年份 | 2014 | 2023 | 2025 |
| 组成性处理 | CLR变换 | 偏差估计校正 | 支持多种标准化 |
| 零值处理 | 贝叶斯Dirichlet先验 | 三类零值分别处理 | 分开分析存在/丰度 |
| 假阳性率 | 最低 | 2025年研究显示较高 | 较低(保守) |
| 可重复性 | 79%(最高之一) | 3%(较低) | 待更多验证 |
| 统计能力 | 较低(保守) | 较高 | 较高 |
| 多组比较 | 不直接支持 | 支持 | 支持 |
| 纵向数据 | 不支持 | 支持(重复测量) | 支持(混合效应) |
| 协变量调整 | 不直接支持 | 支持 | 支持 |
实践建议:多方法交叉验证¶
# ====== 推荐策略:同时运行多种方法取交集 ======
# 1. 运行ALDEx2
aldex_sig <- run_aldex2(counts, groups) # 获取显著物种列表
# 2. 运行ANCOM-BC2
ancombc_sig <- run_ancombc2(ps) # 获取显著物种列表
# 3. 运行MaAsLin3
maaslin_sig <- run_maaslin3(counts, metadata) # 获取显著物种列表
# 4. 取交集(至少2个方法同时认为显著的物种)
library(VennDiagram) # 加载Venn图包
# 画Venn图展示重叠
venn.plot <- venn.diagram(
x = list(
ALDEx2 = aldex_sig,
"ANCOM-BC2" = ancombc_sig,
MaAsLin3 = maaslin_sig
),
filename = "DA_methods_comparison.png", # 输出文件
fill = c("red", "blue", "green"), # 颜色
alpha = 0.5, # 透明度
main = "差异丰度分析方法比较" # 标题
)
# 取交集
consensus <- Reduce(intersect, list(aldex_sig, ancombc_sig, maaslin_sig))
cat("三种方法一致的差异物种:", length(consensus), "\n")
常见报错与解决¶
| 报错 | 原因 | 解决方案 |
|---|---|---|
ALDEx2 cannot allocate vector | 物种太多内存不足 | 先过滤低频物种,减少输入维度 |
ANCOM-BC2 phyloseq object error | phyloseq对象构建有误 | 检查otu_table/sample_data/tax_table的行列对应 |
MaAsLin3 singular matrix | 协变量间存在共线性 | 减少协变量或检查变量类型 |
| 结果全是0个显著 | 阈值太严或样本量不足 | 降低流行度阈值,考虑增加样本 |
| 三种方法结果完全不同 | 正常现象,方法假设不同 | 取2/3方法的交集更可靠 |
grouping factor error | 分组变量不是factor类型 | metadata$Group <- as.factor(metadata$Group) |
速查表¶
# 工具选择
最保守、最可重复 → ALDEx2
多组比较、重复测量 → ANCOM-BC2
协变量多、需要同时分析存在性 → MaAsLin3
建议策略 → 至少跑2种方法取交集
# 预处理要求
ALDEx2: 输入原始计数,不要做任何标准化
ANCOM-BC2: 输入phyloseq对象
MaAsLin3: 输入丰度表(TSV/CSV)+ 元数据表
# 过滤建议
最低流行度:10-20%(至少10%的样本中出现)
最低丰度:0.01-0.1%
移除单例ASV
# 多重比较校正
BH (Benjamini-Hochberg) — 最常用,控制FDR
Bonferroni — 最严格
q < 0.05 为显著阈值
# R包安装命令
BiocManager::install("ALDEx2")
BiocManager::install("ANCOMBC")
BiocManager::install("maaslin3")
面试高频问题¶
Q1:为什么微生物组数据的差异分析这么难?
A:三个核心困难:①组成性——相对丰度加起来等于1,一个升高必然导致其他降低,不能直接用传统统计方法;②零膨胀——大量真零(物种真不存在)和技术零(测序没测到)混在一起;③高维度——物种很多但样本少,多重比较校正后很难显著。
Q2:ALDEx2、ANCOM-BC2、MaAsLin3你会选哪个?
A:不选一个而是同时跑多个。ALDEx2最保守可重复性最好;ANCOM-BC2适合复杂实验设计;MaAsLin3(2025)能同时分析丰度和存在性关联。取2-3种方法的交集结果最可靠。
Q3:什么是组成性数据?怎么处理?
A:组成性数据是指各组分比例加起来等于固定值(如100%)的数据。处理方法:①CLR变换(ALDEx2);②偏差估计校正(ANCOM-BC2);③使用组成性感知的统计方法;④用spike-in或qPCR获得绝对丰度。
Q4:假阳性和假阴性哪个更值得担心?
A:取决于研究目的。如果是探索性研究(发现候选biomarker),假阴性更可怕(不想漏掉真差异),可以用灵敏度高的方法。如果是验证性研究(确认差异),假阳性更可怕(不想报错),用ALDEx2这类保守方法更安全。
Q5:2025年最新的benchmark研究有什么结论?
A:2025年Briefings in Bioinformatics的研究发现:ALDEx2的可重复性最高(79%),ANCOM-BC2的可重复性最低(3%)但统计能力最强。简单方法(如Wilcoxon/t-test配合TSS标准化)表现也不差。建议用多种方法交叉验证。