使用DSS进行BS-seq差异甲基化分析

总览

为了检测差异甲基化,在每个CpG位点进行统计测试,然后根据指定的阈值进行差异甲基化位点(DML)或差异甲基化区域(DMR)分析。 严格的统计测试应考虑重复样本之间的生物学差异和测序深度,而大多数现有的差异甲基化检测手段都是基于hoc方法。 例如,使用Fisher精确值会忽略生物学变异,使用t检验来估计甲基化水平则会忽略测序深度。 在一些情况下,有些不期望发生的过滤却会发生:当一个过滤阈值被随意的设置后,一些深度达不到硬性标准的基因座将会被过滤,这从而导致了信息的丢失。
DSS中实施的差异甲基化检测程序系针对β-二项分布的严格Wald检验。测试统计基于生物学差异(通过离散参数表征)以及测序深度来实现。 作为DSS实施算法的重要部分,离散参数估计是通过基于贝叶斯层次模型的收缩估计器实现的。 DSS的优点是可以在没有生物学重复的条件下进行。 这是因为通过平滑处理,相邻的CpG位点可以被视为伪复制,基于此离散度仍可以在合理的精度下被估算。
DSS对于一般的实验设计也是有效的,这是通过基于具有反正弦函数的beta-二项式回归模型来实现的。 使用广义最小二乘法对变换后的数据进行模型拟合,与基于广义线性模型的方法相比,可以大大提高计算性能。
DSS依赖于Bioconductor的bsseq软件包,该软件包对数据结构的定义清晰,并且具有许多有用的实用功能。 为了使用DM检测功能,需要预先安装bsseq。

输入数据准备

DSS上游的数据来自于bismark软件的结果,这里通过转换bismark_methylation_extractor的cov结果文件来获得输入文件。

这是bismark_methylation_extractor的cov结果文件:

$ head speciman_pe.deduplicated.bismark.cov | column -t
rCRS  33  33  0                  0   15
rCRS  34  34  1.2987012987013    5   380
rCRS  61  61  0                  0   42
rCRS  62  62  0.283687943262411  2   703
rCRS  78  78  3.50877192982456   2   55
rCRS  79  79  2.08768267223382   20  938
rCRS  80  80  3.44827586206897   2   56
rCRS  81  81  2.02634245187437   20  967
rCRS  91  91  0                  0   62
rCRS  92  92  1.95167286245353   21  1055

这是DSS所需要读取的输入文件:

$ head specimen.dss.input.txt | column -t
chr   pos  N    X
rCRS  33   15   0
rCRS  34   385  5
rCRS  61   42   0
rCRS  62   705  2
rCRS  78   57   2
rCRS  79   958  20
rCRS  80   58   2
rCRS  81   987  20
rCRS  91   62   0

用于格式转换的Python脚本代码:

# -*- coding:utf-8 -*-

import glob
import gzip
import logging
import os
import sys

import pandas as pd

logging.basicConfig(format='%(asctime)s\t%(name)s\t%(levelname)s : %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

if __name__ == '__main__':
    dirs_path = sys.argv[1]
    dir_paths = glob.glob(os.path.join(dirs_path, '*'))
    for path in dir_paths:
        sp_name = os.path.basename(path)
        fp = os.path.join(os.path.join(path, 'result/{}_pe.deduplicated.bismark.cov'.format(sp_name)))
        if not os.path.isfile(fp) and os.path.isfile('{}.gz'.format(fp)):
            logger.debug('Unzip {}.gz'.format(fp))
            with gzip.GzipFile('{}.gz'.format(fp)) as gz_file:
                open(fp, 'wb+').write(gz_file.read())
        logger.debug('Process {}'.format(fp))
        df = pd.read_table(fp, header=None)
        df[6] = df[4] + df[5]
        df.rename({0: 'chr', 1: 'pos', 4: 'X', 6: 'N'}, axis=1, inplace=True)
        df = df.reindex(['chr', 'pos', 'N', 'X'], axis=1)
        output_dir = os.path.join(path, 'output')
        if not os.path.isdir(output_dir):
            os.mkdir(output_dir)
        df.to_csv(os.path.join(output_dir, '{}.dss.input.txt'.format(sp_name)), sep='\t', index=False)

从两两组间比较中进行DML/DMR检测

DML: Differential Methylation Loci
DMR: Differential Methylation Regions

Step 1. 加载文库。读取输入的文本数据并创建BSseq类的对象。

library(DSS)
require(bsseq)

dat1A <- read.table("specimen1A.dss.input.txt", header = T)
dat1B <- read.table("specimen1B.dss.input.txt", header = T)
dat1C <- read.table("specimen1C.dss.input.txt", header = T)
dat2A <- read.table("specimen2A.dss.input.txt", header = T)
dat2B <- read.table("specimen2B.dss.input.txt", header = T)
dat2C <- read.table("specimen2C.dss.input.txt", header = T)

BSobj <- makeBSseqData(
    list(dat1A, dat1B, dat1C, dat2A, dat2B, dat2C),
    c("specimen1A", "specimen1B", "specimen1C",
      "specimen2A", "specimen2B", "specimen2C")
)

Step 2. 调用DMLtest函数对DML执行统计测试。DMLtest函数将基本上执行以下步骤:(1)估算所有CpG位点的平均甲基化水平;(2)估算每个CpG位点的离散度; (3)进行瓦尔德检验。我们在函数参数中可以选择是否进行平滑处理。因为甲基化水平显示出很强的空间相关性,所以当数据中的CpG位点密集时(such as from the whole-genome BS-seq),平滑处理有助于更好地估计平均甲基化。但是,对于CpG稀疏的数据(such as from RRBS or hydroxyl-methylation),不建议进行平滑处理。

本次分析是WGBS,因此进行平滑处理。

dmlResult <- DMLtest(BSobj, group1 = c("specimen1A", "specimen1B", "specimen1C"), group2 = c("specimen2A", "specimen2B", "specimen2C"), smoothing = T)

注意:我们可以选择是否平滑处理甲基化水平,默认不做处理。对于WGBS数据,建议进行平滑处理,如此可以合并CpG位点附近的信息以改善对甲基化水平的估计效果。在RRBS中,由于CpG覆盖范围很稀疏,平滑处理可能不会对结果产生太大影响。如果要求做平滑处理,则平滑跨度将是一个重要参数,该参数能显著影响DMR的检测效果;DSS的DMLtest函数没有开放该参数,并将500 bp作为默认值,作者认为该参数在实际数据测试中也会获得良好的表现。

Step 3. 使用callDML函数做DML检测。 结果按将显著性排序。

dmls <- callDML(dmlResult, delta = 0.1, p.threshold = 0.05)

Step 4. 我们将基于DML检测结果来调用callDMR函数进行DMR检测。DMR系具有许多统计上显着CpG位点的区域。此外,我们还能使用一些规定限制条件的参数来做DMR的显著性检测,包括最小长度,最小CpG站点数,该区域中CpG站点的百分比等等。不仅如此,还有一些后续的方法能一快区域内的DMR片段合并为一段更长的DMR。

dmrs <- callDMR(dmlResult, delta = 0.1, p.threshold = 0.05)

你可能感兴趣的:(使用DSS进行BS-seq差异甲基化分析)