MAnorm2:ChIP-seq数据分组比较软件

前言

  ChIP-seq 技术是研究蛋白质与DNA相互作用的重要手段,被广泛用于揭示转录因子和组蛋白修饰在全基因组范围内的结合位点的分布情况。近年来,随着实验技术的发展和测序成本的不断降低,在ChIP-seq样本组之间进行比较分析越来越常见。随着样本的增加,实验人员可以通过增加多个生物学重复控制个体差异造成的影响来提高实验结果的可信度。然而,由于ChIP-seq实验固有的高复杂度和高噪声水平,以及不同比较场景所特有的技术困难,现阶段对多样本ChIP-seq数据进行分组定量比较仍然是一个巨大的计算方法学挑战。
  邵振课题组的方法学论文“MAnorm2 for quantitatively comparing groups of ChIP-seq samples”,报道了其开发的新一代MAnorm2计算模型。该模型沿用了MAnorm的核心假设,通过重构其信号强度变换体系,新发展了以参照样本为基准的多样本并行ChIP-seq信号标准化流程。MAnorm2设计了一个经验贝叶斯框架,利用拟合均值-方差曲线来给单个区域的组内变化水平赋予一个先验分布,并进一步通过平衡先验和后验观测来更准确地估计ChIP-seq信号的组内变化水平,从而提高对组间差异ChIP-seq信号的灵敏度。对该软件的统计实现过程感兴趣的话,可以详细阅读参考文献(PS:本人没有搞明白统计过程...@_@)。

  该模型的应用场景和统计模型具有良好的可扩展性,可用于比较两组之间的比较,有无重复均可;还可以用于同时比较任意多个样本组,并发现其使用效果优于传统的ANOVA方法。说了那么多废话,下面来看一下具体使用过程。

分析流程

  MAnorm2做差异分析时会将所有样本的peak汇总然后划分成无冗余的bin区间,然后考虑每个样本在bin区间的read和是否属于peak开放区,最后根据统计模型来做差异比较。在使用该软件之前,需要用peak、bam文件来准备特定的输入文件。对此,作者很贴心地准备好了转换所用的脚本sam2bed.py、profile_bins.py,详情见github仓库MAnorm2_utils。具体代码如下:

samtools view -O SAM -o sample.sam sample.bam
python sam2bed.py -i sample.sam -o sample.bed

第一步bam文件转化为bed文件还是很方便快捷的,转换后格式如下:

chrI    -7      143     E00516:574:H3MHVCCX2:6:1104:2432:2715   60      +
chrI    -23     127     E00516:574:H3MHVCCX2:6:1104:26068:24638 60      +
chrI    -23     127     E00516:574:H3MHVCCX2:6:1104:27397:25605 60      +
chrI    -30     92      E00516:574:H3MHVCCX2:6:1104:15727:34641 60      +
chrI    -60     90      E00516:574:H3MHVCCX2:6:1105:27093:37489 60      +
chrI    -8      142     E00516:574:H3MHVCCX2:6:1106:10805:13281 60      +
chrI    -8      142     E00516:574:H3MHVCCX2:6:1106:10886:13351 60      +
chrI    -20     130     E00516:574:H3MHVCCX2:6:1107:28595:70785 60      +
chrI    -49     101     E00516:574:H3MHVCCX2:6:1108:23734:49531 60      +
chrI    0       150     E00516:574:H3MHVCCX2:6:1110:2077:23372  60      +
chrI    -54     96      E00516:574:H3MHVCCX2:6:1118:8450:47738  48      +
chrI    -12     138     E00516:574:H3MHVCCX2:6:1119:8532:68834  60      +
chrI    -74     76      E00516:574:H3MHVCCX2:6:1120:20060:12683 52      +

  格式看上去就是正规的bed,但仔细一想发现有不合理的地方,也许大家心里也想到了,那就是bed前三列表示的染色体坐标位置是不可能出现负值的情况,这个转换后起始坐标居然有很多负值,真是unbelievable!这个原因暂且不管了,接着继续往下走:

python profile_bins.py --peaks=myc1_peaks.narrowPeak,yaf9d_peaks.narrowPeak --reads=myc1_reads.bed,yaf9d_reads.bed --labs=myc1,yaf9d -n myc1_yaf9d

这一步输入peak文件和上一步得到的bed文件,就会生成最终需要的输入文件,格式如下所示:

chrom   start   end     myc1.read_cnt   yaf9d.read_cnt  myc1.occupancy  yaf9d.occupancy
chrI    0       591     412     548     1       1
chrI    1808    2185    176     238     0       1
chrI    11703   12113   120     276     0       1
chrI    45896   46719   521     774     0       1
chrI    56742   57311   340     321     1       0
chrI    60586   61545   921     848     1       0
chrI    62426   63070   690     601     1       0
chrI    68394   68881   504     873     0       1

MAnorm做差异比较分为三种情况,一是两组间比较且两组都有重复样本;二是两组间比较但组内没有重复样本;三是多组间比较。下面先来看看第一种情况:

library(MAnorm2)
# 自带的测试数据
head(H3K27Ac)
chrom  start    end GM12890_H3K27Ac_1.read_cnt GM12891_H3K27Ac_1.read_cnt
1  chr1  29023  29346                          8                         16
2  chr1 712983 715873                        440                        498
3  chr1 740056 741095                         81                         54
4  chr1 751252 753001                          2                        139
5  chr1 760716 764177                        234                        329
6  chr1 800556 801985                          4                         26
  GM12891_H3K27Ac_2.read_cnt GM12892_H3K27Ac_1.read_cnt
1                          9                         23
2                        477                        439
3                         39                         44
4                         84                         11
5                        350                        326
6                         59                         16
  GM12892_H3K27Ac_2.read_cnt GM12890_H3K27Ac_1.occupancy
1                         22                           0
2                        508                           1
3                         40                           1
4                         11                           0
5                        376                           1
6                         19                           0
  GM12891_H3K27Ac_1.occupancy GM12891_H3K27Ac_2.occupancy
1                           0                           0
2                           1                           1
3                           0                           0
4                           1                           0
5                           1                           1
6                           0                           1
  GM12892_H3K27Ac_1.occupancy GM12892_H3K27Ac_2.occupancy
1                           1                           1
2                           1                           1
3                           1                           0
4                           0                           0
5                           1                           1
6                           0                           0

# 标准化
norm <- normalize(H3K27Ac, count = 5:6, occupancy = 10:11)
norm <- normalize(norm, count = 7:8, occupancy = 12:13)
conds <- list(GM12891 = bioCond(norm[5:6], norm[10:11], name = "GM12891"), GM12892 = bioCond(norm[7:8], norm[12:13], name = "GM12892"))
conds <- normBioCond(conds)

# 拟合mean-variance曲线
conds <- fitMeanVarCurve(conds, method = "parametric", occupy.only = TRUE)
# 统计检验差异区域
res <- diffTest(conds[[1]], conds[[2]])
head(res)
GM12891.mean GM12892.mean       Mval   Mval.se     Mval.t         pval
1     2.962750     4.378686  1.4159352 0.6952966  2.0364479 4.170540e-02
2     8.599608     8.842037  0.2424297 0.1687241  1.4368406 1.507633e-01
3     4.978799     5.282421  0.3036218 0.4299372  0.7062003 4.800636e-01
4     6.286417     3.357143 -2.9292743 0.4749251 -6.1678654 6.921801e-10
5     8.043483     8.401049  0.3575665 0.1852377  1.9303114 5.356827e-02
6     4.742082     4.015697 -0.7263855 0.5490536 -1.3229775 1.858429e-01
          padj
1 7.478628e-02
2 2.234701e-01
3 5.746783e-01
4 5.306019e-09
5 9.286274e-02
6 2.663536e-01

接着来看第二种情况怎么处理,与情况一大体相似,具体代码如下:

library(MAnorm2)

# H3K27Ac为自带测试数据
norm <- normalize(H3K27Ac, c(5, 7), c(10, 12))
conds <- list(GM12891 = bioCond(norm[5], norm[10], name = "GM12891"), GM12892 = bioCond(norm[7], norm[12], name = "GM12892"))

conds$blind <- bioCond(norm[c(5, 7)], norm[c(10, 12)], occupy.num = 2, name = "blind")
conds <- fitMeanVarCurve(conds, method = "parametric", occupy.only = TRUE, init.coef = c(0.1, 10))
res <- diffTest(conds[[1]], conds[[2]])
head(res)
GM12891.mean GM12892.mean       Mval   Mval.se      Mval.t       pval
1     3.423438     4.554589  1.1311505 1.3268737  0.85249295 0.44690929
2     8.622954     8.779719  0.1567654 0.5014371  0.31263231 0.77181360
3     5.246252     5.475733  0.2294818 0.8931912  0.25692353 0.81123771
4     6.680080     3.523562 -3.1565184 0.9576459 -3.29612253 0.03509689
5     7.991326     8.350939  0.3596130 0.5272771  0.68201903 0.53654681
6     4.146230     4.044394 -0.1018357 1.2841904 -0.07929955 0.94100180
       padj
1 0.8219632
2 0.9459544
3 0.9568767
4 0.5210109
5 0.8637627
6 0.9864314

最后看一下多组之间的比较,据说比直接使用ANOVA分析的结果要好,下面来看一下具体代码:

norm <- normalize(H3K27Ac, count = 4, occupancy = 9)
norm <- normalize(norm, count = 5:6, occupancy = 10:11)
norm <- normalize(norm, count = 7:8, occupancy = 12:13)

conds <- list(GM12890 = bioCond(norm[4], norm[9], name = "GM12890"), GM12891 = bioCond(norm[5:6], norm[10:11], name = "GM12891"), GM12892 = bioCond(norm[7:8], norm[12:13], name = "GM12892"))

conds <- normBioCond(conds)
conds <- fitMeanVarCurve(conds, method = "parametric", occupy.only = TRUE)
res <- aovBioCond(conds)
head(res)
conds.mean between.ms   within.ms  prior.var posterior.var      mod.f
1   3.877391 1.24798909 0.154992959 0.42340216    0.42340216  2.9475265
2   8.838753 0.02103485 0.003559212 0.02236859    0.02236859  0.9403745
3   5.848512 0.22555106 0.073885521 0.11474682    0.11474682  1.9656410
4   3.979706 9.02918943 0.124069261 0.39503584    0.39503584 22.8566336
5   8.233196 0.15408184 0.004609297 0.02930508    0.02930508  5.2578535
6   3.997513 2.98081654 0.272270951 0.39030110    0.39030110  7.6372230
          pval         padj
1 5.246933e-02 6.504417e-02
2 3.904816e-01 4.199157e-01
3 1.400661e-01 1.623538e-01
4 1.184378e-10 4.159661e-10
5 5.206469e-03 7.439914e-03
6 4.821655e-04 7.897353e-04

  三种比较方法用起来都挺方便的,其实该软件还支持一些其他情况如Combining Replicates and Using Local Regression,这里就不介绍了,感兴趣的可以自己去查阅文献和资料。不过,有一点还是要提醒一下,MAnorm2不是直接比较peak区域的差异,而是先把peak划分为bin,划分bin大小视情况而定,默认组蛋白推荐2000转录因子1000,然后再进行比较,所以最后得到的是差异的bin区域。

最后

  ChIP-seq的差异分析,目前并没有统一的标准,MAnorm2在MAnorm的核心假设基础上,通过重构其信号强度变换体系,发展了以参照样本为基准的多样本并行ChIP-seq信号标准化流程,考虑了不同样本间的系统误差,从而提高对组间差异信号的灵敏度,使其展现处更优越的性能。对于ChIP-seq差异分析大家有什么看法?

参考

多样本ChIP-seq数据分组定量比较的MAnorm2计算模型

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

推荐阅读更多精彩内容