生物统计与实验设计(Experimental Design for Bioinformatics)¶
一句话说明¶
实验设计决定了"你的数据能不能回答你的问题"——统计方法再高级,如果实验设计有缺陷(伪重复、批次效应混杂、样本量不够),结论也是站不住脚的。面试官最爱问的不是你会什么统计检验,而是你懂不懂为什么这么设计实验。
为什么实验设计比统计方法更重要¶
白话说:统计方法是"事后补救",实验设计是"事前预防"。
| 对比维度 | 统计方法 | 实验设计 |
|---|---|---|
| 作用时机 | 数据产生之后 | 数据产生之前 |
| 能力范围 | 只能分析已有数据 | 决定数据质量和可信度 |
| 能否补救 | 无法修复设计缺陷 | 从源头避免问题 |
| 面试比方 | 好比法官判案的技术 | 好比警察取证的规范 |
经典例子:如果你把所有T2D样本放在第一批提取RNA、所有健康样本放在第二批,那你发现的"差异基因"到底是疾病导致的还是批次导致的?——再厉害的统计方法也无法区分。这就是实验设计的重要性。
Fisher(统计学奠基人)名言:"To consult the statistician after an experiment is finished is often merely to ask him to conduct a post mortem examination."(实验做完才找统计学家,等于让他做尸检。)
生物学重复 vs 技术重复(面试必考)¶
定义¶
| 概念 | 英文 | 定义 | 白话解释 |
|---|---|---|---|
| 生物学重复 | Biological replicate | 来自不同个体/独立样本的重复 | 不同的老鼠/不同的病人 |
| 技术重复 | Technical replicate | 同一个样本做多次测量 | 同一管血抽三次测 |
白话类比¶
- 生物学重复:你调查"中国人平均身高",去不同城市找了30个人分别量——每个人是一个生物学重复
- 技术重复:你只找了一个人,用3把不同的尺子量3次——这3次是技术重复
关键区别: - 生物学重复反映的是群体内的自然变异(个体差异) - 技术重复反映的是测量本身的误差(仪器精度) - 统计推断必须基于生物学重复,技术重复不能替代生物学重复
测序实验中的区分¶
| 场景 | 属于什么重复 |
|---|---|
| 3个不同T2D患者的粪便样本 | 3个生物学重复 |
| 同一个患者的粪便分成3份分别测序 | 3个技术重复 |
| 同一个文库上不同lane测序 | 技术重复(测序技术重复) |
| 同一个RNA提取物建两个文库 | 技术重复(建库技术重复) |
为什么面试必问¶
面试官问"该项目有多少生物学重复",本质是在检验你是否理解: 1. 你的结论能不能推广到群体 2. 你的统计检验是否合法(n=3的技术重复做t检验 = 伪重复)
样本量计算(功效分析 Power Analysis)¶
核心概念¶
| 术语 | 英文 | 含义 | 白话 |
|---|---|---|---|
| 统计功效 | Power (1-β) | 当差异真实存在时,能检测到它的概率 | "抓到真凶"的概率 |
| I类错误 | α (Type I error) | 没差异说有差异(假阳性) | 冤枉好人 |
| II类错误 | β (Type II error) | 有差异说没差异(假阴性) | 放走坏人 |
| 效应量 | Effect size (d) | 差异的实际大小 | 犯罪证据的明显程度 |
四要素关系(知三求一):
给定其中三个,可以算出第四个。经验法则¶
| 效应量(Cohen's d) | 大小 | RNA-seq对应 |
|---|---|---|
| d = 0.2 | 小效应 | log2FC ≈ 0.3 |
| d = 0.5 | 中等效应 | log2FC ≈ 0.7 |
| d = 0.8 | 大效应 | log2FC ≈ 1.0 |
生信常见经验¶
- 转录组差异表达:每组至少3个生物学重复(最低要求),推荐 6-12 个
- 宏基因组/16S:每组至少10-20个样本(微生物组群体变异大)
- 临床队列研究:通常需要 50-100+ 样本才有足够统计功效
- Power ≥ 0.8(80%)是公认的最低标准
批次效应(Batch Effect)¶
是什么¶
定义:由于实验在不同时间/不同条件/不同操作员下进行,导致数据中出现的非生物学系统性偏差。
白话解释:就像考试换了监考老师——有的老师宽松有的严格,学生成绩的差异一部分来自真实水平,一部分来自"这场考试的阅卷松紧"。批次效应就是"阅卷松紧"造成的假差异。
常见来源¶
| 来源 | 例子 |
|---|---|
| 时间 | 周一提RNA vs 周五提RNA |
| 操作员 | 张三建库 vs 李四建库 |
| 试剂批次 | 不同批号的试剂盒 |
| 设备 | 不同型号/不同run的测序仪 |
| 样本处理 | 冻存时间不同、保存条件不同 |
怎么检测¶
- PCA/PCoA图看分组:如果样本按批次聚类而不是按实验分组聚类,说明有批次效应
- 相关性热图:样本间相关性如果按批次分block,有问题
- 已知管家基因的表达:不应该因批次而变
怎么控制(实验设计阶段)¶
| 策略 | 具体做法 |
|---|---|
| 随机化 | 把不同分组的样本随机分配到各批次 |
| 平衡设计 | 每个批次中,各组样本数量相近 |
| 同一批次 | 条件允许时,所有样本同一天处理 |
| 记录批次信息 | 记下每个样本的批次编号,后续可以作为协变量校正 |
怎么校正(分析阶段)¶
| 方法 | 包/函数 | 适用场景 |
|---|---|---|
| ComBat | sva::ComBat() | 经验贝叶斯方法,适合小样本,最常用 |
| limma removeBatchEffect | limma::removeBatchEffect() | 线性模型去除,适合可视化 |
| SVA | sva::sva() | 未知批次变量时,用代理变量 |
| 模型中加入批次项 | DESeq2/edgeR的design公式 | 差异分析时首选 |
重要原则: - ComBat/removeBatchEffect 产生的校正数据仅用于可视化和聚类 - 差异分析时,应在统计模型中加入批次作为协变量(如 ~ batch + condition),而不是先去批次再分析
随机化和分层设计¶
随机化(Randomization)¶
白话:把样本随机打乱分配到实验条件中,打破已知和未知混杂因素与实验分组的关联。
| 随机化类型 | 做法 | 例子 |
|---|---|---|
| 完全随机化 | 所有样本随机分到各组 | 随机选哪些笼子喂高脂饲料 |
| 限制性随机化 | 在分层/区组内随机化 | 保证每个批次中案例/对照各半 |
| 拉丁方设计 | 同时控制两个混杂因素 | 样本处理顺序+操作员都均匀分配 |
分层设计(Stratified Design)¶
白话:先把样本按某个重要特征分层(如年龄、性别),再在每层内随机抽样或分组。
为什么需要:如果T2D组全是老年人、健康组全是年轻人,你发现的差异菌可能是年龄导致的而不是糖尿病导致的。分层保证每组的年龄分布一致。
生信中的分层交叉验证:
# 宏基因组示例项目中用的 StratifiedKFold
# 保证每一折中T2D和健康样本的比例与整体一致
from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
混杂变量(Confounding Variable)¶
白话解释¶
混杂变量:一个同时影响"原因"和"结果"的第三方因素,让你误以为原因和结果有直接关系。
经典例子: - 冰淇淋销量和溺水人数正相关——混杂变量是"夏天/高温" - T2D患者肠道菌群和健康人不同——混杂变量可能是"BMI/年龄/饮食/用药"
图示¶
生信中常见的混杂变量¶
| 混杂变量 | 影响 | 解决方法 |
|---|---|---|
| 年龄 | 老年人菌群本来就不同 | 匹配或作为协变量 |
| BMI | 肥胖本身影响菌群 | 纳入模型校正 |
| 用药(二甲双胍) | 二甲双胍直接改变肠道菌群 | 排除用药者或分层分析 |
| 饮食 | 饮食模式影响菌群组成 | 收集饮食数据作为协变量 |
| 性别 | 男女菌群有差异 | 匹配或分层 |
控制方法¶
- 匹配(Matching):案例组和对照组按混杂变量1:1匹配(如年龄、性别匹配的健康对照)
- 随机化:随机分组(RCT),混杂变量在各组中均匀分布
- 统计校正:在回归/差异分析模型中加入混杂变量作为协变量
- 限制纳入标准:只纳入特定范围(如只要BMI 18-25的人)
多重比较问题(与11_统计学互补)¶
11_统计学基础讲了 FDR/Bonferroni 校正的原理和代码。这里补充实验设计层面如何减轻多重比较负担:
先验假设缩小检验范围¶
| 策略 | 做法 | 效果 |
|---|---|---|
| 预过滤 | 只检验出现率 > 5% 的菌属 | 减少检验次数 |
| 聚焦假设 | 只检验文献已知的10个候选菌 | 极大减轻校正负担 |
| 层次检验 | 先检验门/纲级别,显著时再下探 | 有层次的多重校正 |
预注册与假设驱动¶
- 探索性分析(hypothesis-generating):承认是探索,FDR阈值可宽松(如0.1)
- 验证性分析(hypothesis-testing):预先指定假设,用独立验证队列验证
- 面试要点:该项目是探索性还是验证性的?如果面试官问"为什么FDR用0.05",你要能解释清楚
多重比较与实验设计的关系¶
检验次数 = 基因/菌属数量 × 比较组数 × 模型数量
实验设计越清晰(分组少、假设明确),多重比较负担越轻。
测序实验设计¶
三大核心参数¶
| 参数 | 含义 | 经验推荐 |
|---|---|---|
| 测序深度 | 每个样本产出多少reads | RNA-seq: 20-30M reads/样本;宏基因组: 5-10G/样本 |
| 生物学重复数 | 每组多少独立样本 | RNA-seq: ≥3(推荐6+);微生物组: ≥10 |
| 对照组设置 | 参照标准 | 匹配的健康对照、同批次处理 |
深度 vs 重复数的权衡¶
核心结论(Genome Biology 2016综述):在预算有限时,增加生物学重复数比增加测序深度更能提高统计功效。
预算固定 = 总reads数固定
方案A:3个样本 × 100M reads/样本 = 300M reads
方案B:10个样本 × 30M reads/样本 = 300M reads
→ 方案B几乎总是更优(检测到更多差异基因/菌)
原因:测序深度到一定程度后边际效用递减,但生物学变异只能通过更多独立样本来估计。
对照组设置原则¶
| 原则 | 做法 |
|---|---|
| 匹配性 | 对照组与实验组在混杂变量上匹配 |
| 同批处理 | 对照和实验样本同一天提取/建库/上机 |
| 阳性对照 | 加入已知有差异的参考样本(如ERCC spike-in) |
| 内参对照 | 管家基因/空载体对照验证流程 |
测序深度参考¶
| 实验类型 | 推荐深度 | 说明 |
|---|---|---|
| mRNA-seq(差异表达) | 20-30M mapped reads | 中高丰度基因足够 |
| mRNA-seq(低表达/新转录本) | 50-100M | 提高低丰度灵敏度 |
| 16S rRNA测序 | 10,000-50,000 reads/样本 | 覆盖主要OTU |
| 宏基因组(物种组成) | 5-10 Gb/样本 | 基本分类够用 |
| 宏基因组(功能注释+MAG组装) | 10-20 Gb/样本 | 需要更深覆盖 |
常见实验设计陷阱¶
1. 伪重复(Pseudoreplication)¶
定义:把技术重复当作生物学重复来做统计分析。
白话:只调查了1个人,量了3次身高,然后说"我有n=3的样本量"——这是自欺欺人。
测序中的伪重复例子: - 同一个小鼠的肝脏分3份测序 → n=1,不是n=3 - 同一个患者不同时间点的样本当独立样本 → 配对设计,不是独立样本 - 同一培养皿中的不同单细胞 → 不是独立生物学重复(共享培养环境)
怎么避免: - 每个生物学重复必须来自独立的个体/独立培养体系 - 技术重复可以取均值后作为一个数据点
2. 技术偏差(Technical Bias)¶
| 偏差来源 | 影响 | 控制方法 |
|---|---|---|
| GC含量偏差 | GC高/低的片段扩增效率不同 | PCR-free建库、计算校正 |
| 文库复杂度 | PCR过度扩增导致重复reads | 去重(deduplication) |
| 3'/5'偏差 | RNA降解导致3'端富集 | 检查RIN值、用rRNA depletion |
| 组成偏差(compositional) | 微生物组数据是相对丰度 | CLR变换/ALDEx2 |
3. 选择偏差(Selection Bias)¶
定义:样本的选择方式导致样本不能代表目标群体。
例子: - 只选住院的重症T2D患者 → 不能代表所有T2D患者 - 只选愿意参与研究的志愿者 → 健康意识高的人过度代表 - 数据库偏差:公共数据集中西方人群过度代表
怎么避免: - 明确纳入/排除标准并报告 - 尽量随机抽样 - 报告样本来源和局限性
4. 混杂与批次完全混淆(Confounding)¶
最致命的设计错误:实验条件与批次完全一致。
如果批次和分组完全混杂,没有任何统计方法能拯救。
R代码实操¶
样本量计算(pwr包)¶
#!/usr/bin/env Rscript
# ============================================================
# 样本量计算实操 —— pwr 包(Power Analysis)
# pwr包版本: 1.3-0,基于Cohen (1988) 的方法
# 核心思路:给定效应量、显著性水平、功效,计算需要多少样本
# ============================================================
# 安装(如果没有的话)
# install.packages("pwr")
library(pwr) # 加载pwr包
# ============================================================
# 场景1:两组t检验的样本量计算
# 问题:比较T2D组和健康组的某个菌属丰度,需要多少样本?
# ============================================================
# 参数设定:
# d = 0.8 → 大效应量(两组均值差 = 0.8倍标准差,对应约2倍丰度差异)
# sig.level = 0.05 → 显著性水平5%(犯I类错误的概率)
# power = 0.8 → 统计功效80%(检测到真实差异的概率)
# type = "two.sample" → 两组独立样本
# alternative = "two.sided" → 双侧检验
result_t <- pwr.t.test(
d = 0.8, # 效应量(Cohen's d)
sig.level = 0.05, # 显著性水平
power = 0.8, # 目标功效
type = "two.sample", # 两组独立样本t检验
alternative = "two.sided" # 双侧检验
)
cat("===== 场景1:两组t检验样本量 =====\n")
print(result_t)
cat(sprintf("结论:每组至少需要 %d 个样本\n", ceiling(result_t$n)))
# ceiling()向上取整,因为样本数必须是整数
# ============================================================
# 场景2:不同效应量下的样本量比较
# 实际意义:效应越小,需要越多样本才能检测到
# ============================================================
cat("\n===== 场景2:效应量与样本量的关系 =====\n")
cat("(固定 α=0.05, power=0.8, two-sample, two-sided)\n\n")
effect_sizes <- c(0.2, 0.3, 0.5, 0.8, 1.0, 1.2) # 从小到大的效应量
for (d in effect_sizes) {
res <- pwr.t.test(d = d, sig.level = 0.05, power = 0.8,
type = "two.sample", alternative = "two.sided")
cat(sprintf(" d = %.1f → 每组需要 %3d 个样本\n", d, ceiling(res$n)))
}
# ============================================================
# 场景3:已知样本量,计算能达到的功效
# 问题:该 T2D项目只有每组10个样本,功效够不够?
# ============================================================
cat("\n===== 场景3:已有样本量的功效评估 =====\n")
result_power <- pwr.t.test(
n = 10, # 每组10个样本
d = 0.8, # 假设大效应
sig.level = 0.05, # α = 0.05
type = "two.sample",
alternative = "two.sided"
)
cat(sprintf("每组10个样本、d=0.8时的功效:%.1f%%\n", result_power$power * 100))
# 如果power < 80%,说明样本量不够
# ============================================================
# 场景4:ANOVA的样本量计算(多组比较)
# 问题:比较3组(健康/轻度T2D/重度T2D)需要多少样本?
# ============================================================
cat("\n===== 场景4:ANOVA(3组)样本量 =====\n")
result_anova <- pwr.anova.test(
k = 3, # 3个组
f = 0.4, # 中-大效应量(Cohen's f)
sig.level = 0.05, # α = 0.05
power = 0.8 # 目标功效80%
)
cat(sprintf("3组ANOVA(f=0.4):每组需要 %d 个样本\n", ceiling(result_anova$n)))
# ============================================================
# 场景5:相关性分析的样本量
# 问题:检测菌属丰度与HbA1c的Spearman相关(r=0.3)需要多少样本?
# ============================================================
cat("\n===== 场景5:相关性检验样本量 =====\n")
result_cor <- pwr.r.test(
r = 0.3, # 预期相关系数(中等相关)
sig.level = 0.05,
power = 0.8,
alternative = "two.sided"
)
cat(sprintf("检测r=0.3的相关性:需要 %d 个样本\n", ceiling(result_cor$n)))
批次效应校正(ComBat + limma::removeBatchEffect)¶
#!/usr/bin/env Rscript
# ============================================================
# 批次效应校正实操
# 方法1:sva::ComBat() —— 经验贝叶斯方法,最常用
# 方法2:limma::removeBatchEffect() —— 线性模型方法
# ============================================================
# 安装(Bioconductor包)
# if (!require("BiocManager")) install.packages("BiocManager")
# BiocManager::install(c("sva", "limma"))
library(sva) # ComBat函数所在的包
library(limma) # removeBatchEffect函数所在的包
# ============================================================
# 1. 模拟有批次效应的表达数据
# ============================================================
set.seed(42)
n_genes <- 1000 # 模拟1000个基因
n_samples <- 20 # 20个样本
# 模拟真实表达矩阵(行=基因,列=样本)
true_expr <- matrix(rnorm(n_genes * n_samples, mean = 8, sd = 2),
nrow = n_genes, ncol = n_samples)
rownames(true_expr) <- paste0("Gene", 1:n_genes)
colnames(true_expr) <- paste0("Sample", 1:n_samples)
# 定义分组信息
condition <- factor(c(rep("Healthy", 10), rep("T2D", 10)))
# 定义批次信息(正确设计:每个批次中各组各5个)
batch <- factor(c(rep("Batch1", 5), rep("Batch2", 5),
rep("Batch1", 5), rep("Batch2", 5)))
# 添加批次效应(Batch2的所有基因系统性偏高1.5)
batch_effect <- matrix(0, nrow = n_genes, ncol = n_samples)
batch_effect[, batch == "Batch2"] <- rnorm(n_genes * sum(batch == "Batch2"),
mean = 1.5, sd = 0.5)
# 添加真实生物学差异(T2D组前50个基因上调)
bio_effect <- matrix(0, nrow = n_genes, ncol = n_samples)
bio_effect[1:50, condition == "T2D"] <- 2 # 前50个基因在T2D中上调
# 最终观测数据 = 真实表达 + 批次效应 + 生物学差异
observed_expr <- true_expr + batch_effect + bio_effect
cat("===== 数据概况 =====\n")
cat(sprintf("基因数: %d, 样本数: %d\n", nrow(observed_expr), ncol(observed_expr)))
cat(sprintf("批次: %s\n", paste(levels(batch), collapse = ", ")))
cat(sprintf("分组: %s\n", paste(levels(condition), collapse = ", ")))
# ============================================================
# 2. ComBat 校正
# ============================================================
cat("\n===== ComBat 批次效应校正 =====\n")
# 构建模型矩阵(保留我们感兴趣的生物学差异)
mod <- model.matrix(~ condition) # 保护condition的效应不被去除
# 运行ComBat
# par.prior=TRUE: 使用参数化经验贝叶斯(推荐,尤其是小样本)
combat_expr <- ComBat(
dat = observed_expr, # 输入表达矩阵(行=基因,列=样本)
batch = batch, # 批次标签
mod = mod, # 保护的生物学模型(不去除condition效应)
par.prior = TRUE # 参数化先验(适合小样本,TRUE=默认推荐)
)
cat("ComBat校正完成\n")
cat(sprintf("校正前Batch1均值: %.2f, Batch2均值: %.2f\n",
mean(observed_expr[, batch == "Batch1"]),
mean(observed_expr[, batch == "Batch2"])))
cat(sprintf("校正后Batch1均值: %.2f, Batch2均值: %.2f\n",
mean(combat_expr[, batch == "Batch1"]),
mean(combat_expr[, batch == "Batch2"])))
# ============================================================
# 3. limma::removeBatchEffect 校正
# ============================================================
cat("\n===== limma::removeBatchEffect 校正 =====\n")
# design参数:告诉函数哪些效应要保留
design <- model.matrix(~ condition)
# removeBatchEffect:去除batch效应,保留condition效应
limma_expr <- removeBatchEffect(
x = observed_expr, # 输入表达矩阵
batch = batch, # 要去除的批次变量
design = design # 要保留的设计矩阵
)
cat("limma校正完成\n")
cat(sprintf("校正后Batch1均值: %.2f, Batch2均值: %.2f\n",
mean(limma_expr[, batch == "Batch1"]),
mean(limma_expr[, batch == "Batch2"])))
# ============================================================
# 4. PCA可视化验证校正效果
# ============================================================
cat("\n===== PCA验证(看样本是否不再按批次聚类) =====\n")
# 校正前PCA
pca_before <- prcomp(t(observed_expr), scale. = TRUE)
cat("校正前PC1解释方差:",
sprintf("%.1f%%", summary(pca_before)$importance[2,1] * 100), "\n")
# 校正后PCA(ComBat)
pca_after <- prcomp(t(combat_expr), scale. = TRUE)
cat("ComBat校正后PC1解释方差:",
sprintf("%.1f%%", summary(pca_after)$importance[2,1] * 100), "\n")
# ============================================================
# 5. 差异分析中的正确做法:模型中纳入批次
# ============================================================
cat("\n===== 差异分析中的批次处理(推荐做法) =====\n")
cat("在DESeq2/edgeR/limma中,不要先去批次再分析,\n")
cat("而是在模型公式中直接加入批次:\n")
cat(" DESeq2: design = ~ batch + condition\n")
cat(" edgeR: design <- model.matrix(~ batch + condition)\n")
cat(" limma: design <- model.matrix(~ batch + condition)\n")
cat("\n这样统计模型会同时估计批次效应和处理效应,更稳健。\n")
cat("ComBat/removeBatchEffect的输出主要用于PCA可视化和热图展示。\n")
面试怎么答¶
Q1: 该项目有多少生物学重复?为什么选这个数量?¶
该 T2D肠道菌群项目使用了公共数据集(公共数据集编号),包含健康组和T2D组,每组都有20+个独立个体的粪便样本。每个样本来自不同的人,属于独立的生物学重复。
选择这个样本量是因为:微生物组数据的个体差异很大(群体间变异远大于组间变异),根据功效分析,如果要检测中等效应量(d=0.5)的差异,在α=0.05、power=0.8的标准下,每组至少需要约64个样本。我们的样本量虽然不完美,但对于大效应量(d=0.8)的差异(如log2FC > 1的菌属),每组26个样本已经能达到约80%的功效。
另外,我没有将技术重复(如同一样本多次测序)当作生物学重复来分析,统计检验的自由度是基于独立个体数而不是测序run数。
Q2: 怎么处理批次效应?¶
首先在实验设计阶段应该通过随机化来避免批次和分组完全混杂——理想的做法是把各组样本均匀分配到每个批次中。
在数据分析阶段,我通常分三步处理:
第一步检测:做PCA看样本是否按批次聚类而不是按生物学分组聚类。如果PC1或PC2主要解释的是批次变异,说明有明显批次效应。
第二步可视化校正:用ComBat或limma::removeBatchEffect去除批次效应后做PCA/热图,验证校正效果。ComBat用经验贝叶斯方法,对小样本特别稳健。
第三步差异分析:在DESeq2或edgeR的模型公式中加入批次作为协变量(
~ batch + condition),让统计模型在估计处理效应时自动调整批次影响。这比先去批次再分析更统计学上正确。重点是:ComBat产出的数据用于可视化,差异分析要在模型中直接处理批次。
Q3: 什么是伪重复?该项目有没有这个问题?¶
伪重复就是把技术重复当生物学重复来做统计推断。比如同一个患者的粪便分3份分别测序,这3份不是3个独立样本,它们的来源是同一个人,不能代表群体变异。如果把它们当n=3做t检验,就会严重低估p值,得到虚假的"显著差异"。
该项目中没有这个问题,因为每个样本来自独立的个体。如果确实存在技术重复(比如同一样本测了两次),我会先对技术重复取平均值,然后只保留一个数据点参与后续统计分析。
Q4: 为什么说"增加重复数比增加测序深度更重要"?¶
这是RNA-seq/宏基因组实验设计中一个核心结论。原因是:
统计功效主要受组内变异的估计精度限制。测序深度到一定程度后(比如RNA-seq 20-30M reads),继续加深只能稍微提高低丰度基因的检测,对统计功效的边际贡献递减。但是,群体的生物学变异只能通过更多独立样本来准确估计。
具体来说:3个样本×100M reads vs 10个样本×30M reads,总测序量相同,但后者在大多数情况下能检测到更多差异基因/菌。因为你有更多自由度来估计组内方差,t检验/Wilcoxon的功效就更高。
所以在预算有限时,优先保证足够的生物学重复数,测序深度达到基本标准即可。
Q5: 你在设计宏基因组实验时会考虑哪些因素?¶
我会从以下几个方面考虑:
样本量:根据研究目的做功效分析。如果是发现差异菌(探索性),每组至少15-20个;如果是验证特定假设,根据预期效应量计算。
对照组设计:对照组必须与实验组在年龄、性别、BMI、饮食等混杂变量上匹配。比如研究T2D菌群,必须排除二甲双胍用药的影响(因为二甲双胍本身改变菌群)。
批次控制:所有样本尽量同一天提取DNA、同一批建库。如果必须分批,确保每批中各组样本数均衡,并记录批次信息用于下游校正。
测序深度:宏基因组物种组成分析一般5-10 Gb/样本;如果要做功能注释或MAG组装,需要10-20 Gb。深度够用后,把预算分给更多样本。
随机化:样本的DNA提取顺序、建库顺序、上机顺序都随机化,避免系统性偏差。
元数据收集:收集尽可能多的临床/人口学信息作为协变量,后续分析时可以统计校正。
速查表¶
实验设计检查清单¶
| 检查项 | 合格标准 | 不合格后果 |
|---|---|---|
| 生物学重复数 | 每组 ≥ 3(RNA-seq)/ ≥ 10(微生物组) | 功效不足,假阴性高 |
| 批次与分组是否交叉 | 每批次含各组样本 | 批次混杂,结论不可信 |
| 混杂变量是否控制 | 匹配/随机化/记录 | 假关联 |
| 技术重复vs生物学重复 | 明确区分 | 伪重复,p值膨胀 |
| 样本随机化 | 处理顺序随机 | 系统偏差 |
| 对照组匹配 | 年龄/性别/BMI匹配 | 混杂效应 |
| 测序深度是否足够 | 达到该实验类型标准 | 灵敏度不足 |
| 功效分析 | Power ≥ 0.8 | 检测力不够 |
关键公式/数字速记¶
| 概念 | 数字/公式 |
|---|---|
| Power标准 | ≥ 0.8(80%) |
| α标准 | 0.05 |
| 大效应量 Cohen's d | 0.8 |
| 中效应量 Cohen's d | 0.5 |
| 小效应量 Cohen's d | 0.2 |
| RNA-seq最低重复 | 每组3个(推荐6+) |
| 微生物组推荐重复 | 每组15-30个 |
| RNA-seq推荐深度 | 20-30M reads/样本 |
| 宏基因组推荐深度 | 5-10 Gb/样本 |
批次效应工具速查¶
| 目的 | 工具 | 函数 |
|---|---|---|
| 去批次(可视化用) | sva | ComBat(dat, batch, mod) |
| 去批次(可视化用) | limma | removeBatchEffect(x, batch, design) |
| 差异分析中处理批次 | DESeq2 | design = ~ batch + condition |
| 未知批次/隐藏变量 | sva | sva(dat, mod, mod0) |
| PCA检测批次效应 | base R | prcomp(t(expr)) |
延伸资源¶
- Conesa et al. (2016) "A survey of best practices for RNA-seq data analysis" Genome Biology 17:13 — RNA-seq实验设计和分析的权威综述,包含重复数/深度/批次的推荐
- Hurlbert (1984) "Pseudoreplication and the design of ecological field experiments" Ecological Monographs — 伪重复问题的经典论文,生态学/微生物组面试常被引用
- Leek et al. (2010) "Tackling the widespread and critical impact of batch effects in high-throughput data" Nature Reviews Genetics 11:733-739 — 批次效应的综述
- R pwr 包文档 — CRAN: https://cran.r-project.org/package=pwr(版本1.3-0,基于Cohen 1988)
- sva 包 Bioconductor — https://bioconductor.org/packages/release/bioc/html/sva.html(ComBat所在包)
- StatQuest: Statistical Power — YouTube频道 Josh Starmer 讲解功效分析,通俗易懂
与本知识库其他文档的关系¶
| 文档 | 与本文的关系 |
|---|---|
| 11_统计学基础 | 11讲统计方法(怎么算),本文讲实验设计(怎么规划)和样本策略 |
| 01_宏基因组全流程 | 提供实际分析流程,本文补充"流程之前"的设计原则 |
| 12_机器学习基础 | 交叉验证中的分层设计与本文分层概念呼应 |
| 13_测序技术原理 | 理解测序深度/批次来源需要知道测序仪原理 |