跳转至

微生物组差异丰度分析:ALDEx2/ANCOM-BC2/MaAsLin3

一句话概述

差异丰度分析就是回答"哪些菌在两组之间真的不一样?"——听起来简单,但微生物数据的组成性、零膨胀、高维度让这变成了生信领域最有争议的问题之一。


核心知识点表格

知识点说明
组成性数据微生物丰度是相对丰度,加起来等于100%,一个上升必有别的下降
零膨胀大量物种在很多样本中丰度为0
ALDEx2贝叶斯框架+CLR变换,最保守但最一致的方法
ANCOM-BC2估计样本特异性偏差,支持多组和重复测量
MaAsLin32025年发布,同时检测丰度和存在性关联
核心问题不同方法得出不同结果,尚无金标准

白话解释

假设你在比较两个班级的成绩分布: - 传统做法:直接比较每科平均分 → 简单但可能有偏 - 微生物数据的问题: 你只知道每科的排名占比(相对丰度),不知道实际分数(绝对丰度)

比如: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"

三种方法对比

特性ALDEx2ANCOM-BC2MaAsLin3
发表年份201420232025
组成性处理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 errorphyloseq对象构建有误检查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标准化)表现也不差。建议用多种方法交叉验证。