跳转至

674 微生物组效应量与统计功效

一句话概述:效应量(effect size)衡量"差异有多大",统计功效(power)回答"样本量够不够"——微生物组研究中R²通常只有2-5%,需要合理估算才能设计有效的实验。

核心知识点速查表

知识点关键内容
效应量衡量差异大小的无量纲指标(不受样本量影响)
Cohen's d两组均值差异/标准差,适用于单变量
R²/η²解释的方差比例,PERMANOVA输出
统计功效在真实差异存在时检测到它的概率(目标≥80%)
样本量估算基于效应量和期望功效计算所需样本数
微生物组特殊性R²通常2-5%,需要大样本量

一、效应量是什么?(白话解释)

打个比方:p值告诉你"这个差异是不是碰巧的",效应量告诉你"这个差异到底有多大"。p<0.05只说明差异"统计上显著",但可能实际差异很小(比如1000人的研究中体温差0.01°C也能显著)。效应量帮你判断"这个差异在生物学上有没有意义"。

核心公式: - Cohen's d = (均值₁ - 均值₂) / 合并标准差 → 两组差异大小 - = 组间变异 / 总变异 → 解释了多少比例的变异 - 统计功效 = P(拒绝H₀ | H₁为真) → 检测到真实差异的概率

效应量
Cohen's d0.20.50.8
0.010.060.14
Cohen's f²0.020.150.35

二、微生物组中的效应量

# 微生物组效应量计算
library(vegan)        # 生态学统计
library(phyloseq)     # 微生物组数据
library(pwr)          # 统计功效分析

# ============ 1. PERMANOVA效应量(R²) ============
# R²是PERMANOVA最直接的效应量指标
# 准备数据
otu <- as(otu_table(ps), "matrix")       # OTU表
if (!taxa_are_rows(ps)) otu <- t(otu)    # 确保物种在行
otu_t <- t(otu)                          # 转置(样本在行)
meta <- as(sample_data(ps), "data.frame")  # 元数据

# 计算Bray-Curtis距离
bc_dist <- vegdist(otu_t, method = "bray")  # Bray-Curtis距离

# PERMANOVA检验
perm_result <- adonis2(
  bc_dist ~ Group + Age + BMI,           # 公式:距离 ~ 分组 + 协变量
  data = meta,                           # 元数据
  permutations = 999,                    # 置换次数
  by = "margin"                          # 边际检验(控制其他变量)
)
print(perm_result)  # 查看结果

# 提取R²(效应量)
r2_group <- perm_result$R2[1]            # Group的R²
cat("Group的效应量(R²):", r2_group, "\n")
# 微生物组中R²通常2-5%是正常的!
# R² > 10% 在微生物组研究中已经很大了

# ============ 2. ω²(Omega-squared,校正后的效应量) ============
# R²会高估效应量,ω²是校正后的无偏估计
omega_squared <- function(adonis_result, term_idx = 1) {
  ss_term <- adonis_result$SumOfSqs[term_idx]  # 组间平方和
  ss_total <- sum(adonis_result$SumOfSqs)       # 总平方和
  ms_residual <- adonis_result$SumOfSqs[nrow(adonis_result)] /
                 adonis_result$Df[nrow(adonis_result)]  # 残差均方
  n <- sum(adonis_result$Df) + 1                # 总样本数
  df_term <- adonis_result$Df[term_idx]         # 组间自由度

  omega2 <- (ss_term - df_term * ms_residual) /
            (ss_total + ms_residual)             # ω²公式
  return(omega2)
}

w2 <- omega_squared(perm_result)
cat("校正效应量(ω²):", w2, "\n")

# ============ 3. 单变量效应量(Cohen's d) ============
# 对单个物种计算效应量
cohens_d <- function(x1, x2) {
  n1 <- length(x1)                       # 组1样本数
  n2 <- length(x2)                       # 组2样本数
  s_pooled <- sqrt(((n1-1)*var(x1) + (n2-1)*var(x2)) /
                    (n1+n2-2))           # 合并标准差
  d <- (mean(x1) - mean(x2)) / s_pooled  # Cohen's d
  return(d)
}

# 对每个物种计算Cohen's d
group1 <- meta$Group == "Disease"        # 疾病组
group2 <- meta$Group == "Control"        # 对照组
effect_sizes <- apply(otu_t, 2, function(x) {
  cohens_d(x[group1], x[group2])         # 计算每个物种的d值
})
top_effects <- sort(abs(effect_sizes), decreasing = TRUE)[1:10]
cat("\n效应量最大的10个物种:\n")
print(round(top_effects, 3))

三、统计功效分析与样本量估算

# 统计功效分析
library(pwr)          # 功效分析包
library(micropower)   # 微生物组专用功效分析(如可用)

# ============ 1. 基于Cohen's d的功效分析 ============
# 场景:两组比较(t检验),估算所需样本量

# 已知效应量,求样本量
power_result <- pwr.t.test(
  d = 0.5,            # 效应量(中等效应)
  sig.level = 0.05,   # 显著性水平
  power = 0.80,       # 期望功效(80%)
  type = "two.sample", # 双样本t检验
  alternative = "two.sided"  # 双侧检验
)
cat("中等效应量(d=0.5)需要每组", ceiling(power_result$n), "个样本\n")

# 不同效应量的样本量需求
effect_sizes <- c(0.2, 0.3, 0.5, 0.8, 1.0)  # 效应量范围
sample_sizes <- sapply(effect_sizes, function(d) {
  res <- pwr.t.test(d = d, sig.level = 0.05, power = 0.80,
                     type = "two.sample")
  ceiling(res$n)                         # 每组所需样本数
})
power_table <- data.frame(
  effect_size = effect_sizes,
  samples_per_group = sample_sizes,
  total_samples = sample_sizes * 2
)
print(power_table)
# 输出:
# effect_size samples_per_group total_samples
#         0.2               394           788  ← 小效应量需要很多样本
#         0.3               176           352
#         0.5                64           128  ← 中效应量
#         0.8                26            52
#         1.0                17            34  ← 大效应量

# ============ 2. PERMANOVA功效分析 ============
# 基于模拟的PERMANOVA功效估算
permanova_power <- function(n_per_group, n_groups = 2,
                             effect_size_r2 = 0.05,
                             n_vars = 100, n_sims = 100) {
  """通过模拟估算PERMANOVA的统计功效"""
  significant <- 0                       # 显著次数计数

  for (i in 1:n_sims) {
    n_total <- n_per_group * n_groups    # 总样本数
    groups <- rep(1:n_groups, each = n_per_group)  # 分组

    # 模拟数据:组间有一定差异
    data_matrix <- matrix(rnorm(n_total * n_vars), nrow = n_total)
    # 给不同组添加效应
    shift <- sqrt(effect_size_r2 / (1 - effect_size_r2)) * sqrt(n_vars)
    data_matrix[groups == 2, 1:5] <- data_matrix[groups == 2, 1:5] + shift

    # PERMANOVA检验
    dist_mat <- vegdist(abs(data_matrix), method = "bray")
    result <- adonis2(dist_mat ~ factor(groups), permutations = 199)
    if (result$`Pr(>F)`[1] < 0.05) {
      significant <- significant + 1     # 统计显著次数
    }
  }
  power <- significant / n_sims          # 功效=显著比例
  return(power)
}

# 不同样本量的功效
cat("\nPERMANOVA功效分析 (R²=0.05):\n")
for (n in c(10, 20, 30, 50, 100)) {
  pwr <- permanova_power(n_per_group = n, effect_size_r2 = 0.05, n_sims = 50)
  cat(sprintf("  每组%d个样本: 功效=%.2f\n", n, pwr))
}

# ============ 3. 功效曲线可视化 ============
library(ggplot2)      # 绑图

# 生成功效曲线数据
power_data <- expand.grid(
  n = seq(10, 200, by = 10),             # 样本量范围
  d = c(0.2, 0.3, 0.5, 0.8)             # 效应量
)
power_data$power <- mapply(function(n, d) {
  pwr.t.test(n = n, d = d, sig.level = 0.05,
             type = "two.sample")$power
}, power_data$n, power_data$d)

# 绘制功效曲线
ggplot(power_data, aes(x = n, y = power, color = factor(d))) +
  geom_line(linewidth = 1.2) +           # 线图
  geom_hline(yintercept = 0.80, linetype = "dashed", color = "red") +
  annotate("text", x = 180, y = 0.82, label = "80% 功效线",
           color = "red") +               # 标注80%线
  labs(x = "每组样本量", y = "统计功效",
       color = "效应量 (Cohen's d)",
       title = "统计功效 vs 样本量") +
  theme_minimal() +                       # 简洁主题
  scale_y_continuous(limits = c(0, 1))    # y轴范围
ggsave("power_curve.png", width = 8, height = 5, dpi = 150)

四、微生物组特有的效应量考量

# 微生物组效应量的特殊性分析
import numpy as np   # 数值计算
import pandas as pd  # 数据处理

# 1. 微生物组研究中的典型效应量
typical_effects = pd.DataFrame({
    "研究类型": [
        "疾病 vs 健康(IBD)",
        "疾病 vs 健康(T2D)",
        "饮食干预",
        "抗生素干预",
        "地理/种族差异",
        "季节变化",
        "个体内时间变异"
    ],
    "典型R²": [0.05, 0.02, 0.03, 0.15, 0.10, 0.01, 0.30],
    "效应大小": ["中", "小", "小-中", "大", "中-大", "小", "大"],
    "建议每组样本量": ["50-100", "100-200", "80-150", "20-40",
                       "30-60", "200+", "20-30"]
})
print("微生物组研究典型效应量:")
print(typical_effects.to_string(index=False))

# 2. 多重比较校正对功效的影响
def adjusted_power(n, d, n_tests, alpha=0.05):
    """考虑多重比较校正后的功效"""
    from scipy.stats import norm  # 正态分布
    # Bonferroni校正后的alpha
    alpha_adj = alpha / n_tests          # 校正后的显著性水平
    # 非中心参数
    ncp = d * np.sqrt(n / 2)             # 非中心参数
    # 临界值
    z_crit = norm.ppf(1 - alpha_adj / 2)  # 临界z值
    # 功效
    power = 1 - norm.cdf(z_crit - ncp) + norm.cdf(-z_crit - ncp)
    return power

# 不同物种数的功效影响
print("\n多重比较对功效的影响(n=50/组, d=0.5):")
for n_taxa in [10, 50, 100, 500, 1000]:
    pwr = adjusted_power(n=50, d=0.5, n_tests=n_taxa)
    print(f"  {n_taxa}个物种: 校正后功效={pwr:.3f}")

# 3. 效应量的置信区间
def cohens_d_ci(d, n1, n2, alpha=0.05):
    """Cohen's d的置信区间(近似)"""
    from scipy.stats import norm
    se = np.sqrt((n1+n2)/(n1*n2) + d**2/(2*(n1+n2)))  # 标准误
    z = norm.ppf(1 - alpha/2)            # z值
    ci_lower = d - z * se                # 下界
    ci_upper = d + z * se                # 上界
    return ci_lower, ci_upper

# 示例
d = 0.5                                  # 点估计
ci = cohens_d_ci(d, n1=30, n2=30)        # 30/组
print(f"\nCohen's d = {d}, 95% CI: [{ci[0]:.3f}, {ci[1]:.3f}]")
print("→ 效应量的不确定性很大,需要足够的样本量")

常见报错与解决

报错原因解决方案
pwr包报"n太小无法计算"效应量太小或功效要求太高降低期望功效(0.70)或增加效应量估计
PERMANOVA R²很小但显著大样本量下即使小效应也显著关注R²而非p值,报告效应量
功效分析结果不切实际效应量估计不准基于预实验或文献的效应量来估算
模拟功效分析太慢置换次数太多减少置换次数(199)或用解析公式近似
效应量为负值方向相反取绝对值,Cohen's d只看大小

速查表

# 效应量解读
Cohen's d: 0.2(小) 0.5(中) 0.8(大)
R²: 0.01(小) 0.06(中) 0.14(大)
微生物组R²: 0.02-0.05 是很常见的

# 样本量经验法则
小效应(d=0.2): 每组~400个样本
中效应(d=0.5): 每组~65个样本
大效应(d=0.8): 每组~26个样本

# 微生物组样本量建议
横断面研究: 50-200/组(取决于效应量)
纵向研究: 20-50/组(重复测量增加功效)
干预研究: 30-80/组

# 功效分析步骤
1. 估算效应量(文献/预实验)
2. 设定α=0.05, power=0.80
3. 用pwr包或模拟计算样本量
4. 考虑多重比较的功效损失
5. 加20%余量应对样本丢失

# 报告效应量的最佳实践
- 同时报告p值和效应量
- 给出效应量的置信区间
- 对比文献中同类研究的效应量

面试高频问题

Q1:为什么微生物组研究的R²通常很小(2-5%)? A:因为微生物组受很多因素影响——饮食、药物、遗传、地理、时间等。单个研究变量(如疾病状态)通常只能解释一小部分变异。这不意味着结果不重要——2%的R²在数千个物种的背景下可能代表关键的生态学变化。Nature 2019年综述指出,微生物组变异的最大驱动因素是个体间差异(~50%),而非疾病状态。

Q2:p值和效应量有什么区别? A:p值回答"差异是否偶然"(依赖样本量),效应量回答"差异有多大"(不依赖样本量)。样本量1000时,微小的、无生物学意义的差异也能p<0.001。所以ASA(美国统计学会)2019年声明建议不要仅依赖p值,同时报告效应量和置信区间。

Q3:怎么做微生物组研究的样本量估算? A:(1) 从文献或预实验获取效应量估计;(2) 设定α=0.05, power=0.80;(3) 对于PERMANOVA可用模拟法(micropower包);(4) 对于差异丰度分析需考虑多重比较校正后的功效损失;(5) 加20-30%余量应对样本丢失和不合格样本。通常50-100/组是合理的起点。

Q4:如何报告微生物组研究的效应量? A:(1) PERMANOVA→报告R²和ω²(校正效应量);(2) 差异丰度→报告log2 fold change和Cohen's d;(3) 多样性指数→报告均值差异的Cohen's d及95%CI;(4) 对比该领域的典型效应量大小。STORMS报告指南推荐同时报告效应量和p值。