使用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)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,718评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,683评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,207评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,755评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,862评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,050评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,136评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,882评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,330评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,651评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,789评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,477评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,135评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,864评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,099评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,598评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,697评论 2 351