跳转至

Bisulfite测序数据分析

一句话概述

Bisulfite测序(WGBS/RRBS)是检测DNA甲基化的金标准方法,通过亚硫酸氢盐处理将未甲基化的C转化为U,经Bismark比对后提取单碱基分辨率的甲基化信息,再用DSS/methylKit进行差异甲基化区域(DMR)检测。


核心知识点表格

知识点关键内容常用工具
实验原理亚硫酸氢盐将未甲基化C→U,甲基化C不变-
WGBS vs RRBS全基因组 vs 酶切富集CpG密集区-
数据质控转化率检测、去接头、去duplicationTrim 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%数据不可用。


易错点

  1. 未检查转化率:转化不完全会导致所有位点甲基化水平被高估,是最致命的质量问题。

  2. M-bias未校正:Read两端常有甲基化水平偏差(尤其是双端测序的read2前几bp),不校正会产生系统性偏差。

  3. 覆盖度过滤不当:低覆盖位点的甲基化估计方差大(如2x覆盖,只能是0%、50%或100%),需至少5-10x覆盖。

  4. 忽略链信息:CpG是对称结构,两条链的同一CpG通常合并计算(destrand=TRUE)。

  5. PCR重复未去除:RRBS数据重复率很高(因为片段来源有限),必须去重。

  6. 氧化损伤混淆:5hmC也不会被Bisulfite转化,标准WGBS无法区分5mC和5hmC。需要oxBS-seq或TAB-seq。


补充知识

新一代甲基化检测技术

技术原理优势局限
WGBS亚硫酸氢盐+WGS金标准,全面成本高,DNA损伤
EM-seq酶法转化DNA损伤小,均匀性好较新
Nanopore直接测序无需化学处理,检测多种修饰准确率稍低
EPIC Array杂交芯片高通量,成本低固定位点,不全面

甲基化功能解读

启动子CpG岛高甲基化 → 基因沉默
基因体高甲基化 → 活跃转录(矛盾但真实)
增强子低甲基化 → 增强子活化
重复序列高甲基化 → 转座子沉默
印记基因 → 等位基因特异性甲基化
X染色体失活 → 全染色体高甲基化