191_微生物组常见统计错误¶
一句话概述¶
微生物组数据具有组成性、高维稀疏、零膨胀等特殊属性,使用不当的统计方法(如直接用t检验比较相对丰度、忽略组成性偏差、不做多重检验校正)会导致严重的假阳性或假阴性,本文系统总结微生物组分析中最常见的统计陷阱和正确方法。
核心知识点表格¶
| 知识点 | 说明 |
|---|---|
| 组成性数据 | 相对丰度受总量约束(和为1),变量间非独立 |
| 组成性偏差 | 一个物种增加导致其他物种的相对丰度被动下降 |
| 零膨胀 | 大量零值(真零 vs 抽样零),普通检验失效 |
| 假发现率 | 同时检验数百个物种必须做FDR校正 |
| rarefaction争议 | 稀释抽平损失数据但统计更公平 |
| CLR变换 | 中心对数比变换,处理组成性数据的标准方法 |
| ANCOM-BC | 组成性数据差异丰度分析的推荐方法 |
| 效应量 | 仅看p值不够,应同时报告效应量 |
步骤详解¶
第一步:理解组成性数据问题¶
白话解释:微生物组数据是"你多我少"的零和博弈。所有物种的相对丰度加起来必须等于100%。这意味着即使某个物种的绝对数量没变,只要其他物种增加了,它的相对丰度就会"被动下降"。用普通统计方法分析这种数据会得到错误的结论。
技术细节:组成性约束(compositional constraint)违反了大多数统计检验的独立性假设。Pearson相关系数在组成性数据上会产生虚假负相关(spurious correlation)。Aitchison提出的对数比(log-ratio)方法是处理组成性数据的理论基础。
# 错误示例:直接对相对丰度做Pearson相关
# 这会产生虚假的负相关!
rel_abundance <- matrix(c(0.3, 0.3, 0.4,
0.5, 0.2, 0.3,
0.1, 0.4, 0.5), nrow = 3, byrow = TRUE)
cor(rel_abundance) # 会显示负相关,但这是数学必然而非生物学真实
# 正确方法:使用CLR变换后再计算相关
library(compositions)
clr_data <- clr(rel_abundance)
cor(clr_data) # 更可靠的相关性估计
# 或使用SparCC(专门处理组成性数据的相关分析)
# sparcc(otu_table)
第二步:常见错误一——不做多重检验校正¶
白话解释:检测100个物种的差异,即使都没有真正差异,按5%显著性水平也会有约5个"假阳性"。多重检验校正(如BH/FDR方法)专门解决这个问题。
# 错误做法:对每个物种做t检验,不校正p值
p_values <- apply(otu_table, 2, function(x) {
t.test(x ~ group)$p.value
})
sum(p_values < 0.05) # 可能很多"显著",但多数是假阳性
# 正确做法:BH校正
p_adjusted <- p.adjust(p_values, method = "BH")
sum(p_adjusted < 0.05) # 校正后的显著结果
# 更好的做法:使用专门的差异丰度工具
library(ANCOMBC)
result <- ancombc2(
data = phyloseq_obj,
fix_formula = "group",
p_adj_method = "BH",
alpha = 0.05
)
# ANCOM-BC内部处理了组成性偏差和多重检验
第三步:常见错误二——忽略数据标准化¶
白话解释:不同样本的测序深度不同(有的测了100万reads,有的只有10万),直接比较原始counts是不公平的。但简单地除以总数(TSS)也有问题,因为这引入了组成性约束。
# 错误1:直接用原始counts比较
# t.test(raw_counts[group == "A", "OTU1"], raw_counts[group == "B", "OTU1"])
# 结果主要反映测序深度差异
# 错误2:简单相对丰度可能引入组成性偏差
relative <- sweep(otu_table, 1, rowSums(otu_table), "/")
# 推荐方法1:Rarefaction(有争议但仍广泛使用)
library(vegan)
set.seed(42)
otu_rarefied <- rrarefy(otu_table, min(rowSums(otu_table)))
# 推荐方法2:CLR变换
library(compositions)
# 加伪计数处理零值
otu_pseudo <- otu_table + 0.5
clr_transformed <- clr(otu_pseudo)
# 推荐方法3:CSS标准化(metagenomeSeq)
library(metagenomeSeq)
MRobj <- newMRexperiment(t(otu_table))
MRobj <- cumNorm(MRobj, p = cumNormStatFast(MRobj))
css_normalized <- MRcounts(MRobj, norm = TRUE, log = TRUE)
# 推荐方法4:DESeq2的VST/rlog
library(DESeq2)
dds <- DESeqDataSetFromMatrix(t(otu_table), colData = metadata, design = ~ group)
dds <- estimateSizeFactors(dds, type = "poscounts")
vsd <- varianceStabilizingTransformation(dds)
第四步:常见错误三——对零值处理不当¶
白话解释:微生物组数据中有大量的零。这些零可能是"真零"(该物种确实不存在)或"抽样零"(存在但没检测到)。不区分两种零,或者不当处理零值,都会导致问题。
# 零值问题演示
otu_example <- c(0, 0, 0, 0, 0, 5, 8, 12, 0, 0)
# 这个物种只在3个样本中检出
# 错误:直接做log变换(log(0)=-Inf)
# log2(otu_example) # 产生-Inf
# 方法1:加伪计数(简单但有偏)
log2(otu_example + 1) # 最常用,但1的选择是任意的
# 方法2:零值替换(如Bayesian multiplicative replacement)
library(zCompositions)
otu_imputed <- cmultRepl(otu_table, method = "CZM", output = "p-counts")
# 方法3:使用零膨胀模型
library(pscl)
# 零膨胀负二项模型
zinb_model <- zeroinfl(abundance ~ group | 1, dist = "negbin", data = df)
# 方法4:使用原生支持零值的差异分析工具
# ANCOM-BC, DESeq2, ALDEx2 都内部处理了零值
第五步:常见错误四——错误使用统计检验¶
# 错误1:对非正态数据使用t检验
# 微生物丰度数据几乎从不是正态分布
shapiro.test(otu_table[, 1]) # 检查正态性
# 应使用非参数检验
wilcox.test(otu_table[, 1] ~ group) # Wilcoxon检验
# 错误2:对相关丰度数据使用Pearson相关
# 应使用SparCC或基于CLR的相关
# sparcc_result <- sparcc(otu_table, iter = 20, xiter = 10)
# 错误3:对多组比较使用多次t检验
# 应使用Kruskal-Wallis
kruskal.test(abundance ~ group, data = df)
# 事后多重比较
library(dunn.test)
dunn.test(df$abundance, df$group, method = "bh")
# 错误4:PERMANOVA不检查方差齐性
# 必须先做betadisper
library(vegan)
dist_matrix <- vegdist(otu_table, method = "bray")
bd <- betadisper(dist_matrix, metadata$group)
permutest(bd) # p>0.05 才能信任PERMANOVA结果
第六步:推荐的差异丰度分析方法¶
# 2024年推荐的差异丰度分析方法
# 1. ANCOM-BC2(推荐首选)
library(ANCOMBC)
result <- ancombc2(
data = phyloseq_obj,
fix_formula = "group + age + sex", # 支持协变量
p_adj_method = "BH",
pseudo_sens = TRUE,
alpha = 0.05
)
significant <- result$res[result$res$q_group < 0.05, ]
# 2. ALDEx2(组成性数据理论基础最严格)
library(ALDEx2)
aldex_result <- aldex(t(otu_table), conditions = group,
mc.samples = 128, test = "t", effect = TRUE)
sig_aldex <- aldex_result[aldex_result$we.eBH < 0.05, ]
# 3. MaAsLin2(灵活,支持多种模型)
library(Maaslin2)
maaslin_result <- Maaslin2(
input_data = otu_table,
input_metadata = metadata,
output = "maaslin2_output",
fixed_effects = c("group"),
normalization = "TSS",
transform = "LOG"
)
# 推荐策略:运行2-3种方法,取交集
实战命令速查¶
# FDR校正
p.adjust(p_values, method = "BH")
# CLR变换
compositions::clr(otu_table + 0.5)
# ANCOM-BC快速运行
ancombc2(data = physeq, fix_formula = "group", p_adj_method = "BH")
# ALDEx2快速运行
aldex(counts, conditions, mc.samples = 128, test = "t")
# 正态性检验
shapiro.test(x) # n<5000
面试常问点¶
Q1: 什么是组成性偏差(compositional bias)?如何解决? A: 组成性偏差指相对丰度受总量约束导致的虚假变化。当一个物种的绝对丰度增加时,所有其他物种的相对丰度都被动下降,即使它们的绝对丰度不变。解决方法:(1)使用CLR变换处理数据;(2)使用ANCOM-BC等理论上考虑了组成性偏差的方法;(3)如果可能,使用绝对定量方法(如spike-in标准品)。
Q2: rarefaction到底应不应该用? A: 学术争议很大。反对者(McMurdie & Holmes 2014)认为丢弃数据不合理。支持者认为它确保样本间可比性。实际建议:(1)Alpha多样性分析中rarefaction仍是标准做法;(2)差异丰度分析建议用DESeq2/ANCOM-BC等不需要rarefaction的方法;(3)如果必须rarefaction,应做多次随机抽样取平均。
Q3: 如何正确报告微生物组研究的统计结果? A: (1)明确说明使用的统计方法和理由;(2)报告FDR校正后的p值(q值);(3)报告效应量(如fold change, Cohen's d);(4)说明样本量和检验力;(5)对差异丰度分析,说明使用的标准化方法;(6)可视化原始数据分布。
Q4: 样本量多少算够? A: 取决于效应量和群落变异度。一般规则:(1)每组至少5-10个样本用于基本的alpha/beta多样性分析;(2)差异丰度分析每组至少15-20个样本;(3)可用micropower或HMP包做功效分析。
Q5: 为什么不能直接用Pearson相关分析微生物共现模式? A: 因为组成性约束:所有物种的相对丰度之和为1,这数学上必然产生负相关,无论物种间是否有真实的生物学关联。应使用SparCC、SPIEC-EASI或基于CLR变换的相关分析。
易错点¶
- 不做多重检验校正:同时检验数百个物种不做FDR校正是最常见的错误
- 直接用相对丰度做t检验:忽略组成性数据特性
- rarefaction后做差异分析:丢弃数据后再做统计检验不合理
- 忽略样本量不足:小样本量导致统计检验力不足
- 过度依赖p值:不报告效应量,p<0.05不代表生物学显著性
- 混淆相关与因果:微生物共现不等于因果关系
- 不检查统计前提假设:如正态性、方差齐性
补充知识¶
差异丰度分析工具推荐排名(2024)¶
| 推荐度 | 工具 | 优势 |
|---|---|---|
| 强推荐 | ANCOM-BC2 | 理论完善,控制FDR |
| 强推荐 | ALDEx2 | 组成性数据基础严格 |
| 推荐 | MaAsLin2 | 灵活,支持混合模型 |
| 推荐 | LinDA | 线性模型,适合复杂设计 |
| 谨慎使用 | DESeq2 | 原设计用于RNA-seq,FPR偏高 |
| 不推荐 | LEfSe | FPR高,不控制协变量 |
| 不推荐 | 简单t检验/Wilcoxon | 忽略组成性和多重检验 |