Bisulfite测序数据分析¶
一句话概述¶
Bisulfite测序(WGBS/RRBS)是检测DNA甲基化的金标准方法,通过亚硫酸氢盐处理将未甲基化的C转化为U,经Bismark比对后提取单碱基分辨率的甲基化信息,再用DSS/methylKit进行差异甲基化区域(DMR)检测。
核心知识点表格¶
| 知识点 | 关键内容 | 常用工具 |
|---|---|---|
| 实验原理 | 亚硫酸氢盐将未甲基化C→U,甲基化C不变 | - |
| WGBS vs RRBS | 全基因组 vs 酶切富集CpG密集区 | - |
| 数据质控 | 转化率检测、去接头、去duplication | Trim Galore, FastQC |
| 比对 | 三字母比对(C→T转化后参考基因组) | Bismark, BSMap, bwa-meth |
| 甲基化提取 | 逐位点统计甲基化水平 | Bismark methylation_extractor |
| DMR检测 | 差异甲基化区域识别 | DSS, methylKit, dmrseq |
| 可视化 | 甲基化热图/track/基因组浏览器 | IGV, deepTools, ggplot2 |
| 下游分析 | 基因注释、通路富集、与表达关联 | ChIPseeker, clusterProfiler |
各步骤详解¶
第一步:理解Bisulfite测序原理¶
白话解释: DNA上的甲基化(主要是CpG位点上的5-甲基胞嘧啶)就像基因的"开关标记"。亚硫酸氢盐处理是一种化学方法:没有甲基保护的C碱基被转化成U(测序时读为T),而有甲基保护的C保持不变。通过比较处理后的序列与原始参考基因组,就能知道每个C位点是否被甲基化。
技术细节: - CpG甲基化:最常见,基因启动子区的CpG甲基化通常抑制转录 - CHG/CHH甲基化:主要见于植物,在哺乳动物中少见 - WGBS:覆盖全基因组所有C位点,成本高(需30x以上测序深度) - RRBS:用MspI酶切富集CpG岛区域,成本低但覆盖有偏 - 转化率:理想>99%,通过掺入lambda DNA(无甲基化)监控
代码示例:
# 计算转化率(使用lambda DNA对照)
# lambda DNA无甲基化,所有C应该被转化为T
# 转化率 = (转化的C数) / (总C数) × 100%
# 在Bismark比对后查看lambda DNA的转化效率
grep "lambda" bismark_report.txt
# C methylated in CpG context: 0.3% → 转化率 = 99.7%
第二步:数据质控与预处理¶
白话解释: 原始测序数据需要先做质量检查和清洗。Bisulfite处理后DNA会比较碎,read质量两端往往较差。另外需要去除接头序列和低质量碱基。
技术细节: - Bisulfite处理导致DNA降解,文库片段较短 - Read末端有filling-in区域,可能引入无甲基化假象(需要M-bias校正) - RRBS数据前几bp通常是MspI识别位点(CCGG),可能有bias - 去重复很重要,尤其是RRBS数据
代码示例:
# 安装工具
conda install -c bioconda trim-galore bismark bowtie2 samtools
# 质量检查
fastqc -t 8 sample_R1.fastq.gz sample_R2.fastq.gz
# Trim Galore预处理(自动检测adapter)
# 对WGBS数据:
trim_galore --paired --fastqc \
--clip_R1 10 --clip_R2 10 \
--three_prime_clip_R1 10 --three_prime_clip_R2 10 \
-o trimmed/ \
sample_R1.fastq.gz sample_R2.fastq.gz
# 对RRBS数据(需要加--rrbs参数):
trim_galore --paired --fastqc --rrbs \
-o trimmed/ \
sample_R1.fastq.gz sample_R2.fastq.gz
# --rrbs: 自动处理MspI位点末端的人工甲基化偏差
# --clip_R1/R2: 去除5'端指定bp数
# --three_prime_clip: 去除3'端指定bp数
第三步:Bismark比对¶
白话解释: Bismark是最常用的Bisulfite比对工具。由于C→T转化,不能直接用普通比对软件。Bismark的策略是:同时将参考基因组做C→T和G→A转化,reads也做相应转化后再用Bowtie2比对,然后回推原始序列的甲基化状态。
技术细节: - 三字母比对策略:减少字母表从4个变为3个 - 方向性文库(directional):95%以上reads来自两条原始链 - 唯一比对(unique alignment):多比对位置的reads默认丢弃 - 比对率通常60-80%(低于普通WGS,因为序列复杂度降低)
代码示例:
# 1. 构建Bismark参考基因组索引
bismark_genome_preparation --bowtie2 /path/to/genome/
# 2. Bismark比对
bismark --genome /path/to/genome/ \
--bowtie2 \
--parallel 4 \
--temp_dir /tmp/ \
-1 trimmed/sample_R1_val_1.fq.gz \
-2 trimmed/sample_R2_val_2.fq.gz \
-o aligned/
# 关键参数:
# --parallel 4: 使用4个并行实例(实际用8个CPU核)
# --non_directional: 如果是非方向性文库
# --pbat: 如果是PBAT文库
# 3. 去重复
deduplicate_bismark --bam aligned/sample_R1_val_1_bismark_bt2_pe.bam \
--output_dir dedup/
# 4. 查看比对报告
cat aligned/sample_R1_val_1_bismark_bt2_PE_report.txt
# Mapping efficiency: 72.5%
# Unique best hit: 68.3%
# Sequences with no alignment: 27.5%
# 5. 排序和索引
samtools sort dedup/sample_R1_val_1_bismark_bt2_pe.deduplicated.bam \
-o sorted_sample.bam
samtools index sorted_sample.bam
第四步:甲基化信息提取¶
白话解释: 比对完成后,Bismark会逐个检查每个C位点:比对到该位点的reads中有多少保持为C(说明被甲基化),多少变成了T(说明未甲基化)。比值就是该位点的甲基化水平。
技术细节: - 输出每个C位点的甲基化reads数和非甲基化reads数 - 分别统计CpG、CHG、CHH三种context - M-bias plot用于检测位置偏差(read两端可能有偏) - 覆盖度过滤:通常要求至少5-10x覆盖
代码示例:
# 甲基化提取
bismark_methylation_extractor --paired-end --gzip \
--bedGraph --cytosine_report \
--genome_folder /path/to/genome/ \
--parallel 4 \
--comprehensive \
--output methylation/ \
dedup/sample_R1_val_1_bismark_bt2_pe.deduplicated.bam
# 输出文件说明:
# CpG_context_*.txt.gz - CpG位点甲基化信息
# CHG_context_*.txt.gz - CHG位点信息
# CHH_context_*.txt.gz - CHH位点信息
# *.bedGraph.gz - bedGraph格式甲基化水平
# *.cov.gz - coverage文件(含甲基化/未甲基化读数)
# *_splitting_report.txt - 报告文件
# *.cytosine_report.txt - 全基因组cytosine报告
# M-bias检查
# 查看M-bias plot,决定是否需要额外trim
# 如果发现末端有明显偏差,需要在提取时加参数:
# --ignore 5 --ignore_r2 5 --ignore_3prime 5 --ignore_3prime_r2 5
# 生成全基因组报告
bismark2report
bismark2summary
第五步:差异甲基化区域(DMR)检测¶
白话解释: 有了每个位点的甲基化水平后,就可以比较不同样本(如肿瘤vs正常)之间的甲基化差异。DMR就是连续多个位点都有显著甲基化差异的区域。
技术细节: - DSS使用beta-binomial模型,处理生物学变异 - methylKit使用logistic回归(多样本)或Fisher's exact test(单样本) - dmrseq使用平滑方法检测区域性差异 - 需要设定最小覆盖度、最小差异阈值、最小CpG数等参数 - 多重检验校正至关重要
代码示例(R - DSS):
# 使用DSS进行DMR分析
library(DSS)
# 读入Bismark coverage文件
# 格式: chr, pos, N (total), X (methylated)
read_bismark_cov <- function(file, sample_name) {
df <- read.table(file, header=FALSE,
col.names=c("chr","start","end","meth_pct","count_M","count_U"))
data.frame(
chr = df$chr,
pos = df$start,
N = df$count_M + df$count_U,
X = df$count_M
)
}
# 读取样本
ctrl1 <- read_bismark_cov("ctrl1.bismark.cov.gz", "ctrl1")
ctrl2 <- read_bismark_cov("ctrl2.bismark.cov.gz", "ctrl2")
treat1 <- read_bismark_cov("treat1.bismark.cov.gz", "treat1")
treat2 <- read_bismark_cov("treat2.bismark.cov.gz", "treat2")
# 创建BSseq对象
BSobj <- makeBSseqData(
list(ctrl1, ctrl2, treat1, treat2),
c("ctrl1", "ctrl2", "treat1", "treat2")
)
# DML检测(单位点差异)
dmlTest <- DMLtest(BSobj,
group1 = c("ctrl1", "ctrl2"),
group2 = c("treat1", "treat2"),
smoothing = TRUE)
# DMR检测(区域差异)
dmrs <- callDMR(dmlTest,
delta = 0.2, # 最小甲基化差异20%
p.threshold = 0.001,
minlen = 50, # 最小区域长度50bp
minCG = 3, # 最少包含3个CpG
dis.merge = 50, # 相邻DMR合并距离
pct.sig = 0.5) # 至少50%的CpG显著
# 查看结果
head(dmrs)
nrow(dmrs)
# 导出
write.csv(dmrs, "DMR_results.csv", row.names=FALSE)
代码示例(R - methylKit):
library(methylKit)
# 读取Bismark coverage文件
file.list <- list(
"ctrl1.bismark.cov.gz",
"ctrl2.bismark.cov.gz",
"treat1.bismark.cov.gz",
"treat2.bismark.cov.gz"
)
# 创建methylRawList对象
myobj <- methRead(file.list,
sample.id = list("ctrl1","ctrl2","treat1","treat2"),
assembly = "hg38",
treatment = c(0, 0, 1, 1),
context = "CpG",
mincov = 10, # 最小覆盖度10x
pipeline = "bismarkCoverage")
# 过滤极端覆盖度
filtered <- filterByCoverage(myobj,
lo.count = 10, # 最低10x
lo.perc = NULL,
hi.count = NULL,
hi.perc = 99.9) # 去除top 0.1%异常高覆盖
# 合并样本(取交集位点)
meth <- unite(filtered, destrand=FALSE)
# 计算差异甲基化
myDiff <- calculateDiffMeth(meth,
overdispersion = "MN", # beta-binomial模型
adjust = "BH") # BH校正
# 筛选DMC(差异甲基化位点)
myDiff25 <- getMethylDiff(myDiff,
difference = 25, # 至少25%差异
qvalue = 0.01) # FDR < 0.01
# 获取hyper/hypo甲基化
hyper <- getMethylDiff(myDiff, difference=25, qvalue=0.01, type="hyper")
hypo <- getMethylDiff(myDiff, difference=25, qvalue=0.01, type="hypo")
# 区域分析(tiling window)
tiles <- tileMethylCounts(myobj, win.size=1000, step.size=1000)
meth_tile <- unite(tiles, destrand=FALSE)
diff_tile <- calculateDiffMeth(meth_tile)
# 基因注释
library(genomation)
gene.obj <- readTranscriptFeatures("hg38_refseq.bed")
diffAnn <- annotateWithGeneParts(as(myDiff25,"GRanges"), gene.obj)
第六步:可视化与下游分析¶
白话解释: 将DMR结果与基因组注释结合,看差异甲基化发生在哪些基因的启动子/增强子区域,与基因表达变化是否相关,然后做通路富集分析。
代码示例:
# 甲基化水平热图
library(ComplexHeatmap)
library(circlize)
# 提取DMR区域的甲基化值
meth_matrix <- percMethylation(meth)
dmr_sites <- as(myDiff25, "GRanges")
# 绘制热图
col_fun <- colorRamp2(c(0, 50, 100), c("blue", "white", "red"))
Heatmap(meth_matrix[1:100,],
col = col_fun,
name = "Methylation%",
cluster_rows = TRUE,
cluster_columns = TRUE,
show_row_names = FALSE)
# DMR基因组分布
library(ChIPseeker)
library(TxDb.Hsapiens.UCSC.hg38.knownGene)
txdb <- TxDb.Hsapiens.UCSC.hg38.knownGene
peakAnno <- annotatePeak(dmr_sites,
TxDb = txdb,
level = "gene")
plotAnnoPie(peakAnno)
plotDistToTSS(peakAnno)
# 甲基化与表达关联
# 合并甲基化和RNA-seq数据
# 启动子甲基化通常与基因沉默负相关
实战命令¶
# === WGBS完整分析流程 ===
#!/bin/bash
set -e
GENOME="/ref/hg38"
THREADS=16
# 批量处理多个样本
for SAMPLE in ctrl1 ctrl2 treat1 treat2; do
R1="raw/${SAMPLE}_R1.fastq.gz"
R2="raw/${SAMPLE}_R2.fastq.gz"
# 质控
trim_galore --paired --fastqc --cores 4 \
--clip_R1 10 --clip_R2 10 \
-o trimmed/ $R1 $R2
# 比对
bismark --genome $GENOME --bowtie2 --parallel 4 \
-1 trimmed/${SAMPLE}_R1_val_1.fq.gz \
-2 trimmed/${SAMPLE}_R2_val_2.fq.gz \
-o aligned/
# 去重
deduplicate_bismark --bam \
aligned/${SAMPLE}_R1_val_1_bismark_bt2_pe.bam \
--output_dir dedup/
# 甲基化提取
bismark_methylation_extractor --paired-end --gzip \
--bedGraph --cytosine_report \
--genome_folder $GENOME --parallel 4 \
-o methylation/ \
dedup/${SAMPLE}*.deduplicated.bam
done
# 汇总报告
bismark2report
bismark2summary
面试常问点¶
Q1: WGBS和RRBS的区别与选择? A: WGBS覆盖全基因组所有C位点(约2800万CpG),需高深度(30x),成本高但全面;RRBS用MspI酶切富集CpG岛(覆盖~10%CpG),成本低但有偏向性。全基因组研究用WGBS,CpG岛甲基化筛查用RRBS,临床大样本通常用甲基化芯片(EPIC 850K)。
Q2: 比对率为什么比普通WGS低? A: 1)Bisulfite处理降低序列复杂度(C→T使四字母变三字母);2)DNA降解产生短片段;3)重复序列区域在降低复杂度后更难唯一比对;4)转化不完全的reads可能比对到错误位置。
Q3: 甲基化定量的统计模型是什么? A: 每个位点的甲基化reads数服从二项分布B(n,p),n为总覆盖度,p为甲基化率。考虑到生物学重复间的过度离散,DSS使用beta-binomial模型。methylKit在有多个生物学重复时使用logistic回归,通过乘法过度离散参数(overdispersion="MN")校正;只有单样本对比时使用Fisher's exact test。
Q4: DMR分析需要多少生物学重复? A: 至少3个,推荐4-5个。没有重复时只能做DML(差异甲基化位点),无法区分生物学变异和真正差异。
Q5: 如何验证Bisulfite转化率? A: 1)加入lambda噬菌体DNA作为spike-in(完全无甲基化);2)查看CHH context的甲基化率(哺乳动物中应接近0%);3)理想转化率>99%,低于95%数据不可用。
易错点¶
未检查转化率:转化不完全会导致所有位点甲基化水平被高估,是最致命的质量问题。
M-bias未校正:Read两端常有甲基化水平偏差(尤其是双端测序的read2前几bp),不校正会产生系统性偏差。
覆盖度过滤不当:低覆盖位点的甲基化估计方差大(如2x覆盖,只能是0%、50%或100%),需至少5-10x覆盖。
忽略链信息:CpG是对称结构,两条链的同一CpG通常合并计算(destrand=TRUE)。
PCR重复未去除:RRBS数据重复率很高(因为片段来源有限),必须去重。
氧化损伤混淆:5hmC也不会被Bisulfite转化,标准WGBS无法区分5mC和5hmC。需要oxBS-seq或TAB-seq。
补充知识¶
新一代甲基化检测技术¶
| 技术 | 原理 | 优势 | 局限 |
|---|---|---|---|
| WGBS | 亚硫酸氢盐+WGS | 金标准,全面 | 成本高,DNA损伤 |
| EM-seq | 酶法转化 | DNA损伤小,均匀性好 | 较新 |
| Nanopore | 直接测序 | 无需化学处理,检测多种修饰 | 准确率稍低 |
| EPIC Array | 杂交芯片 | 高通量,成本低 | 固定位点,不全面 |