Coder Social home page Coder Social logo

r-chip-data-analysis's Introduction

如何进行R-ChIP数据分析

提高自己分析能力的一个好的方法就是重复别人文章里的分析策略,所以这里会尝试对第一篇介绍R-ChIP技术文章"R-ChIP Using Inactive RNase H Reveals Dynamic Coupling of R-loops with Transcriptional Pausing at Gene Promoters"里的所有分析进行重复,我重复所用代码会更新在我的GitHub上,地址为https://github.com/xuzhougeng/R-ChIP-data-analysis

选择这篇文章进行重复的理由有三点:

一:最近要探索R-loop数据分析流程

二:这篇文章的通讯作者是大牛,Xiang-Dong Fu

三:这篇文章将分析所用代码都托管在https://github.com/Jia-Yu-Chen

背景知识

高通量数据分析其中在流程上大同小异,大多数会跑流程却不知道如何分析的人,更多缺乏的是生物学基础。在阅读文献后,我整理下几个我觉得和后续数据分析有关的几个知识点:

  • R-loop是一种RNA/DNA三链结构体,与基因组稳定性和转录调控有关。
  • 通过电镜观察,R-loop大小在150~500bp之间。
  • 硫酸氢盐测序(bisulfate sequencing)表明R-loop主要出现在基因启动子的下游。
  • R-loop所在非模板链(又称编码链)具有很强的序列偏好性,计算方式为(G-C)/(G+C)

R-loop的高通量分析方法目前都是依赖于S9.6抗体捕获RNA/DNA杂合体,然后超声打断或酶切,如果后续对DNA进行测序,那就是DRIP-seq(DNA:RNA immunoprecipitation [DRIP] sequencing),如果后续对RNA逆转成的cDNA继续测序,那就是 [DRIPc]-seq(DNA:RNA immunoprecipitation followed by cDNA conversion)。 然而酶切的分辨率不够,超声又容易破坏脆弱的R-loop结构,于是就导致目前很多文献报道有矛盾。

这篇文章就开发了一种新方法,基于RNase H的体内R-loop谱检测策略。作者构建一种没有催化活性的RNASE H1(原始的RNase H会同时靶向和基因组和线粒体基因组,因此在N端加上了NLS用于定位,在C端加上V5标签用于IP ),RNASEH1与RNA/DNA结合,超声打碎,用anti-V5抗体进行染色体免疫共沉淀(ChIP)。随后RNA/DNA杂合体转换成双链DNA(ds-DNA), 之后便是链特异性测序。

R-loop

关于链特异性测序,推荐拜读链特异性测序那点事

“和普通的RNAseq不同,链特异性测序可以保留最初产生RNA的方向”

文章的分析内容

后续的分析部分会尝试完成文章中出现的分析。

  1. 证明R-ChIP方法的效率和可靠度
    • 找到D210N特异而WKKD非特异的基因
    • peak的正负链比对情况
  2. 序列偏好性和基因组分布
    • 比较narrow Peak和broad peak的peak大小(boxplot)
    • broad peak是否包含narrow peak(韦恩图),且一方特异的peak的信号值也弱
    • G/C skew, 统计距离summit的ATCG比例,统计背景和R-loop相比,G二聚体、G-三聚体、G四聚体..的出现比例
    • G-rich 在非模板链出现次树显著增加
    • peak在基因组上的分布(promoter proximal regions, +- Kb from TSS). 比较不同基因不同部分的差异
  3. 与S9.6的R-loop结果系统性比较(基于K562 cells)
    • 比较DRIP-seq和R-ChIP的peak大小
    • 看两者的peak的overlap
    • 在JUN座位上的R-ChIP, DRIP-seq, DNase, H3K4me1, H3K4me2,H3K4me3, H3K27ac
  4. 人类基因组上其他R-loop热点分析
  5. R-loop诱导转录
  6. R-loop的形成需要游离RNA 末端(free RNA ends)

准备分析环境

软件部分

文章中"Software and Algorithms"这部分列出了分析主要所用的软件,加上下载SRA数据所需工具和一些常用软件,一共要安装的软件如下:

  • SRA Toolkit: 数据下载工具
  • Bowtie2: 比对工具
  • SAMtools: SAM格式处理工具
  • BEDtools: BED格式处理工具
  • MACS2: 比对后找peak
  • R: 统计作图
  • Ngsplot: 可视化工具
  • Deeptools: BAM文件分析工具, 可作图。

软件安装部分此处不介绍,毕竟如果你连软件安装都有困难,那你应该需要先学点Linux基础,或者去看生信必修课之软件安装

分析项目搭建

使用mkdir创建项目文件夹,用于存放后续分析的所用到的数据、中间文件和结果

mkdir -p r-chip/{analysis/0-raw-data,index,scripts,results}

个人习惯,在项目根目录下创建了四个文件夹

  • analysis: 存放原始数据、中间文件
  • index: 存放比对软件索引
  • scripts: 存放分析中用到的脚本
  • results: 存放可用于放在文章中的结果

后续所有的操作都默认在r-chip下进行,除非特别说明。

数据下载

根据文章提供的GEO编号(GEO: GSE97072)在NCBI上检索, 按照如下步骤获取该编号下所有数据的元信息, 我将其重命名为"download_table.txt"然后上传到服务器 。

获取数据元信息

然后在scripts下新建一个脚本01.sra_download.sh

#!/bin/bash

sra_files=${1?missing input file}

sra_ids=$(egrep -o 'SRR[0-9]{5,9}' $sra_files)

mkdir -p analysis/log

for id in $sra_ids
do
    prefetch $id >> analysis/log/download.log
done

在项目根目录下运行bash scritps/01.sra_download.sh ownload_table.txt

下载的数据默认情况下存放在~/ncbi/public/sra, 需要用fastq-dump解压缩到analysis/0-raw-data. fastq-dump的使用说明见Fastq-dump: 一个神奇的软件

新建一个脚本,叫做02.sra_uncompress.sh,存放在scripts文件下,代码如下

#!/bin/bash

file_in=${1?missing input file}
SRR_IDS=$( egrep -o 'SRR[0-9]{5,9}' ${file_in})
OUT_DIR="analysis/0-raw-data"
mkdir -p ${OUT_DIR}

for id in $SRR_IDS
do
   echo "fastq-dump --gzip --split-3 --defline-qual '+' --defline-seq '@\$ac-\$si/\$ri' $id -O ${OUT_DIR} &" | bash
done

然后用bash 02.sra_uncompress.sh download_table.txt运行。

如果空间不够用,可以用egrep -o 'SRR[0-9]{5,9}' download_table.txt | xargs -i rm ~/ncbi/public/sra/{}.sra删除SRR数据。

注意:这是单端测序,所以每个SRR只会解压缩出一个文件

此外还需要下载human genome (hg19)的bowtie2索引,用于后续bowtie2比对。

curl -s ftp://ftp.ccb.jhu.edu/pub/data/bowtie2_indexes/hg19.zip -o index/hg19.zip &
cd index
unzip hg19.zip

从索引提取每条染色体的长度

bowtie2-inspect -s index/hg19 | cut -f 2,3 | grep '^chr' > index/hg19.chrom.sizes

数据分析

文件重命名

我们需要对下载的SRRXXXXX文件进行重命名,毕竟有意义的命名才能方便后续展示。那么,应该如何做呢?

首先,你需要将GSE97072页面的中Samples这部分的内容复制到一个文本文件中(我将其命名为sample_name.txt),分为两列,第一列是GSM编号,第二列是样本的命名。

sample name

注:这里面有一个希腊字符在不同系统表示有所不同,所以我在复制之后手动修改。

此外,你还需要将里面的(-)(+)进行替换,因为括号在shell里有特殊含义, 为了保证命名的连贯性,我将(-)替换成-neg,将(+)替换成-pos.

 sed -i 's/(-)/-neg/; s/(+)/-pos/' sample_name.txt

随后,我们需要从download_table.txt中提取出SRR编号和GSM编号的对应的关系,这个需要用到Linux的文本处理命令

paste <(egrep -o 'GSM[0-9]{6,9}' download_table.txt ) <(egrep -o 'SRR[0-9]{6,9}' download_table.txt) >  gsm_srr.txt
join <(sort gsm_srr.txt ) <(head -n 24 sample_name.txt | sort) > gsm_srr_sample_name.txt

注: 样本一共有25行,而我们只下载了24个数据,所以删除了最后一行的"K562-WKKD-V5chip"

最后,就是根据生成的文件对样本进行重命名了。

awk '{print "rename " $2 " " $3   " analysis/0-raw-data/" $2 "*.gz"}' gsm_srr_sample_name.txt |bash

这行代码看起来有点复杂,但是其实做的事情就是构建了一系列rename的命令行,然后在bash下执行。

R-ChIP分析

数据预处理

这一部分主要是将序列比对后原来的参考基因组上,标记重复,并且去掉不符合要求的比对。

让我们先写一个比对脚本将序列比对到参考基因组上,脚本命名为03.r_chip_align.sh,存放在scripts

#!/bin/bash

set -e
set -u
set -o pipefail

# configuration
threads=8
index=index/hg19
FQ_DIR="analysis/0-raw-data"
ALIGN_DIR="analysis/2-read-align"
LOG_DIR="analysis/log"
TMP_DIR="analysis/tmp"

mkdir -p ${ALIGN_DIR}
mkdir -p ${LOG_DIR}
mkdir -p ${TMP_DIR}

samples=${1?missing sample file}

exec 0< $samples
# alignment
while read id;
do
    if [ ! -f ${FQ_DIR}/$id.bt2.done ]
    then
    echo "bowtie2 --very-sensitive-local --mm -p $threads -x $index -U ${FQ_DIR}/$id.fastq.gz 2> ${LOG_DIR}/$id.bt2.log | \
    samtools sort -@ 2 -m 1G -T ${TMP_DIR}/${id} -o ${ALIGN_DIR}/${id}.sort.bam \
    && touch ${ALIGN_DIR}/$id.bt2.done" | bash
    fi
done

这个脚本的前半部分都在定义各种变量,而#alignment标记的后半部分则是实际运行的比对命令

你会发现我的实际运行部分脚本有点奇怪,我没有直接运行比对,而是用echo通过管道传递给了bash执行。

这样做的原因是, 当我用sed -i 's/| bash/#| bash/ 03.r_chip_align.sh'| bash替换成#| bash后,运行这个脚本就可以检查代码是否正确,然后再用sed-i s/#| bash/| bash/03.r_chip_align.sh修改回来 。 后面的脚本同理。

接着再写一个脚本用于标记重复04.markdup.sh,也是放在scripts

#!/bin/bash

set -e
set -u
set -o pipefail

# configuration
threads=8
index=index/hg19
FQ_DIR="analysis/0-raw-data"
OUT_DIR="analysis/2-read-align"
LOG_DIR="analysis/log"
TMP_DIR="analysis/tmp"

mkdir -p ${OUT_DIR}
mkdir -p ${LOG_DIR}
mkdir -p ${TMP_DIR}

samples=${1?missing sample file}

exec 0< $samples
# mark duplication
while read id;
do
    if [ ! -f ${OUT_DIR}/${id}.mkdup.done ]
    then
    echo "sambamba markdup -t $threads ${OUT_DIR}/${id}.sort.bam ${OUT_DIR}/${id}.mkdup.bam \
    && touch ${OUT_DIR}/${id}.mkdup.done" | bash
    fi
done

再准备一个脚本用于去除不符合要求的比对,命名为05.bam_filter.sh

#!/bin/bash

set -e
set -u
set -o pipefail

# configuration
threads=8
index=index/hg19
FQ_DIR="analysis/0-raw-data"
ALIGN_DIR="analysis/2-read-align"
LOG_DIR="analysis/log"
TMP_DIR="analysis/tmp"

mkdir -p ${ALIGN_DIR}
mkdir -p ${LOG_DIR}
mkdir -p ${TMP_DIR}

samples=${1?missing sample file}

exec 0< $samples
# filter
while read id;
do
    if [ ! -f ${ALIGN_DIR}/${id}.flt.done ]
    then
    echo "
    samtools view -@ threads -bF 1804 -q 30 ${ALIGN_DIR}/${id}.mkdup.bam -o ${ALIGN_DIR}/${id}.flt.bam\
    && samtools index ${ALIGN_DIR}/${id}.flt.bam \
    && touch ${ALIGN_DIR}/${id}.flt.done "| bash
    fi
done

最后新建一个samples01.txt用于存放将要处理的样本名

HKE293-D210N-V5ChIP-Rep1
HKE293-D210N-Input-Rep1
HKE293-D210N-V5ChIP-Rep2
HKE293-D210N-Input-Rep2
HKE293-D210N-V5ChIP-Rep3
HKE293-D210N-Input-Rep3
HKE293-WKKD-V5ChIP
HKE293-WKKD-Input
HKE293-delta-HC-V5ChIP

这样子就可以依次运行脚本了

  • 比对: bash scripts/03.r_chip_align.sh samples01.txt
  • 标记重复:bash scripts/04.bam_markdup.sh samples01.txt
  • 去除不符合要求的比对: bash scripts/05.bam_filter.sh samples01.txt

处理完之后可以对每个样本都进行一次统计,包括如下信息:

  • 处理前的原始reads数
  • 处理后对唯一比对reads数
  • 唯一比对reads数所占原始reads数的比例

这个工作同样可以用shell脚本完成, 脚本为06.sample_align_stat.sh

#!/bin/bash

set -e
set -u
set -o pipefail

samples=${1?missing sample file}
threads=8
OUT_DIR="analysis/2-read-align"

echo -e "Experiment \t Raw Reads \t Uniquely mapped Reads \t ratio"
exec 0< $samples

while read sample;
do
     total=$( samtools view -@ ${threads} -c ${ALIGN_DIR}/${sample}.sort.bam )
     unique=$( samtools view -@ ${threads} -c ${ALIGN_DIR}/${sample}.flt.bam )
     ratio=$( echo "scale=2; 100 * $unique / $total " | bc )
     echo -e "$sample \t $total \t $unique \t $ratio %"
done

运行方法是bash scripts/06.sample_align_stat.sh samples01.txt > results/library_stat.txt,运行结果如下,和原本的Table S2对比,你会发现结果基本一致,有出入的地方我推测是标记重复这一步所用软件不同。

Experiment Raw Reads Uniquely mapped Reads ratio
HKE293-D210N-V5ChIP-Rep1 22405416 6443979 28.76%
HKE293-D210N-Input-Rep1 60302237 25673307 42.57%
HKE293-D210N-V5ChIP-Rep2 17763614 11778533 66.30%
HKE293-D210N-Input-Rep2 11131443 8553097 76.83%
HKE293-D210N-V5ChIP-Rep3 8799855 5640375 64.09%
HKE293-D210N-Input-Rep3 4529910 3209275 70.84%
HKE293-WKKD-V5ChIP 12734577 8612940 67.63%
HKE293-WKKD-Input 8830478 6643507 75.23%
HKE293-delta-HC-V5ChIP 25174573 9252009 36.75%

BAM相关性评估

上一步得到各个样本的BAM文件之后,就可以在全基因组范围上看看这几个样本之间是否有差异。也就是先将基因组分成N个区间,然后用统计每个区间上比对上的read数。

脚本scripts/07.genome_bin_read_coverage.sh如下

#!/bin/bash

set -e
set -u
set -o pipefail

samples=${1?missing sample file}
chromsize=${2:-index/hg19.chrom.sizes}
size=${3:-3000}
ALIGN_DIR="analysis/2-read-align"
COV_DIR="analysis/3-genome-coverage"

mkdir -p ${COV_DIR}

exec 0< $samples

while read sample
do
    bedtools makewindows -g $chromsize -w $size | \
      bedtools intersect -b ${ALIGN_DIR}/${sample}.flt.bam -a - -c -bed > ${COV_DIR}/${sample}.ReadsCoverage
done

准备一个输入文件存放待处理样本的前缀,然后运行脚本bash scripts/07.genome_bin_read_coverage.sh samples_rep.txt

HKE293-D210N-Input-Rep1
HKE293-D210N-Input-Rep2
HKE293-D210N-Input-Rep3
HKE293-D210N-V5ChIP-Rep1
HKE293-D210N-V5ChIP-Rep2
HKE293-D210N-V5ChIP-Rep3

最后将得到的文件导入到R语言中进行作图,使用的是基础绘图系统的光滑散点图(smoothScatter)。

files_list <- list.files("r-chip/analysis/3-genome-coverage","ReadsCoverage")
files_path <- file.path("r-chip/analysis/3-genome-coverage",files_list)

input_rep1 <- read.table(files_path[1], sep='\t')
input_rep2 <- read.table(files_path[2], sep='\t')
input_rep3 <- read.table(files_path[3], sep='\t')
chip_rep1 <- read.table(files_path[4], sep='\t')
chip_rep2 <- read.table(files_path[5], sep='\t')
chip_rep3 <- read.table(files_path[6], sep='\t')

pw_plot <- function(x, y, 
                    xlab="x",
                    ylab="y", ...){
  log2x <- log2(x)
  log2y <- log2(y)
  smoothScatter(log2x,log2y,
                cex=1.2,
                xlim=c(0,12),ylim=c(0,12),
                xlab=xlab,
                ylab=ylab)
  text(3,10,paste("R = ",round(cor(x,y),2),sep=""))
}

par(mfrow=c(2,3))
pw_plot(chip_rep1[,4], chip_rep2[,4],
        xlab = "Rep 1 (Log2 Tag Counts)",
        ylab = "Rep 2 (Log2 Tag Counts)")

pw_plot(chip_rep1[,4], chip_rep3[,4],
        xlab = "Rep 1 (Log2 Tag Counts)",
        ylab = "Rep 2 (Log2 Tag Counts)")

pw_plot(chip_rep2[,4], chip_rep3[,4],
        xlab = "Rep 1 (Log2 Tag Counts)",
        ylab = "Rep 2 (Log2 Tag Counts)")

pw_plot(input_rep1[,4], input_rep2[,4],
        xlab = "Rep 1 (Log2 Tag Counts)",
        ylab = "Rep 2 (Log2 Tag Counts)")

pw_plot(input_rep1[,4], input_rep3[,4],
        xlab = "Rep 1 (Log2 Tag Counts)",
        ylab = "Rep 3 (Log2 Tag Counts)")

pw_plot(input_rep2[,4], input_rep3[,4],
        xlab = "Rep 2 (Log2 Tag Counts)",
        ylab = "Rep 3 (Log2 Tag Counts)")

下图上为D210的R-ChIP三个重复间的相关性,下为Input三个重复间的相关性

correlationship

这种多个BAM文件之间相关性衡量,其实也可以用deepToolsplotCorrelation画出来,但是我觉得应该没有R语言画 的好看。

看图说话: 由于同一个样本间的BAM文件具有很强的相关性,因此可以将这些样本合并起来,这样子在基因组浏览器上就可以只用一个轨(tracks)

BigWig可视化

虽然可以直接用BAM也行对比对结果进行可视化展示,但是一般BAM文件文件太大,不方便传输,所以需要转换成bigwig格式,这样子在基因组浏览器(例如IGV, UCSC Browser, JBrowse)上方便展示。

如下的代码的目的就是先合并BAM,然后转换成BigWig,拆分成正链和反链进行保存

#!/bin/bash

set -e
set -u
set -o pipefail

samples=${1?please provied sample file}
threads=${2-8}
bs=${3-50}

ALIGN_DIR="analysis/2-read-align"
BW_DIR="analysis/4-normliazed-bw"

mkdir -p $BW_DIR

exec 0< $samples
cd $ALIGN_DIR

while read sample
do
    bams=$(ls ${sample}*flt.bam | tr '\n' ' ')
    if [ ! -f ../$(basename ${BW_DIR})/${sample}.tmp.bam ]; then
    echo "samtools merge -f -@ ${threads} ../$(basename ${BW_DIR})/${sample}.tmp.bam $bams  &&
          samtools index ../$(basename ${BW_DIR})/${sample}.tmp.bam" | bash
    fi
done

cd ../../
exec 0< $samples

cd ${BW_DIR}
while read sample
do
    bamCoverage -b ${sample}.tmp.bam -o ${sample}_fwd.bw -of bigwig  \
      --filterRNAstrand forward --binSize ${bs} --normalizeUsing CPM --effectiveGenomeSize 2864785220 \
      --extendReads 150 -p ${threads} 2> ../log/${sample}_fwd.log
    bamCoverage -b ${sample}.tmp.bam -o ${sample}_rvs.bw -of bigwig  \
      --filterRNAstrand reverse --binSize ${bs} --normalizeUsing CPM --effectiveGenomeSize 2864785220 \
      --extendReads 150 -p ${threads} 2> ../log/${sample}_rvs.log
    rm -f ${sample}.tmp.bam ${sample}.tmp.bam.bai
done

得到的BW文件你可以在IGV上初步看看,比如说检查下文章Figure 1(E)提到的CIRH1A基因

CIRH1A

发表文章时肯定不能用上图,我们可以用R的Gviz进行展示下

library(Gviz)

#下面将scale等track写入tracklist
tracklist<-list()
itrack <- IdeogramTrack(genome = "hg19", chromosome = 'chr16',outline=T)
tracklist[["itrack"]]<-itrack

# 读取BigWig
bw_file_path <- "C:/Users/DELL/Desktop/FigureYa/R-ChIP/"
bw_file_names <- list.files(bw_file_path, "*.bw")
bw_files <- file.path("C:/Users/DELL/Desktop/FigureYa/R-ChIP/",
                      bw_file_names)

tracklist[['D210-fwd']] <- DataTrack(range = bw_files[3],
                              genome="hg19",
                              type="histogram",
                              name='D210 + ',
                              ylim=c(0,4),
                              col.histogram="#2167a4",
                              fill.histogram="#2167a4")
tracklist[['D210-rvs']] <- DataTrack(range = bw_files[4],
                                     genome="hg19",
                                     type="histogram",
                                     name='D210 - ',
                                     ylim=c(4,0),
                                     col.histogram="#eb1700",
                                     fill.histogram="#eb1700")

tracklist[['WKDD-fwd']] <- DataTrack(range = bw_files[9],
                                     genome="hg19",
                                     type="histogram",
                                     name='WKDD + ',
                                     ylim=c(0,4),
                                     ylab=2,
                                     col.histogram="#2167a4",
                                     fill.histogram="#2167a4")
tracklist[['WKDD-rvs']] <- DataTrack(range = bw_files[10],
                                     genome="hg19",
                                     type="histogram",
                                     name=' WKDD -',
                                     ylim=c(4,0),
                                     col.histogram="#eb1700",
                                     fill.histogram="#eb1700",
                                     showAxis=TRUE)

#写入比例尺
scalebar <- GenomeAxisTrack(scale=0.25,
                            col="black",
                            fontcolor="black",
                            name="Scale",
                            labelPos="above",showTitle=F)
tracklist[["scalebar"]]<-scalebar

# 画图
plotTracks(trackList = tracklist,
           chromosome = "chr16",
           from =  69141913, to= 69205033,
           background.panel = "#f6f6f6",
           background.title = "white",
           col.title="black",col.axis="black",
           rot.title=0,cex.title=0.5,margin=10,title.width=1.75,
           cex.axis=1
           )

原文Fig1E

后续用AI修改下坐标轴,就几乎和原图差不多了。此外可能还要调整之前脚本的bin size, 使得整体更加平滑。

看图说话: 由于WKKD在D210N的基础上继续突变了几个位点,使得原本只丧失了RNASEH1的催化活性的D210N进一步丧失了结合到RNA/DNA杂合体的能力,在实验中就可以作为 负对照。上图就是其中一个有代表性的区间。

Peak Calling

关于MACS2的使用方法, 我写了如何使用MACS进行peak calling详细地介绍了它的参数,在用MACS2之前尽量去阅读下。

尽管 文章说他按照默认参数分别找narrow peak 和 broad peak, 即"We used MACS2 with default settings to call narrow (or broad when necessary) R-loop peaks",但是 MACS2的默认参数一开始会根据reads在正反链的分布建立双峰模型,确定偏移模型(shifting model),也就是它会认为示例CHTF8和CIRH1A位于正反链的信号视作一个IP结果的信号,因此用默认参数绝对有问题,所以 必须要增加--nomodel取消建模,且增加--shift 0 --extsize 150按照实验的条带长度对片段进行延长。

cd analysis
# HKE293 D210N
macs2 callpeak --nomodel --shift 0 --extsize 150 -g hs --keep-dup all -f BAM -t 2-read-align/HKE293-D210N-V5ChIP-Rep*.flt.bam -c 2-read-align/HKE293-D210N-Input-Rep*.flt.bam --outdir 5-peak-calling/narrow -n HKE293-D210 2> log/HKE293-D210.macs2.narrow.log &
macs2 callpeak --nomodel --shift 0 --extsize 150 -g hs --keep-dup all --broad -f BAM -t 2-read-align/HKE293-D210N-V5ChIP-Rep*.flt.bam -c 2-read-align/HKE293-D210N-Input-Rep*.flt.bam --outdir 5-peak-calling/broad -n HKE293-D210 2> log/HKE293-D210.macs2.broad.log &
# HEK293 WKKD
macs2 callpeak --nomodel --shift 0 --extsize 150  -g hs --keep-dup all -f BAM -t 2-read-align/HKE293-WKKD-V5ChIP.flt.bam -c 2-read-align/HKE293-WKKD-Input.flt.bam --outdir 5-peak-calling/narrow/ -n HKE293-WKKD 2> log/HKE293-WKKD.macs2.narrow.log &
macs2 callpeak --nomodel --shift 0 --extsize 150  -g hs --keep-dup all --broad -f BAM -t 2-read-align/HKE293-WKKD-V5ChIP.flt.bam -c 2-read-align/HKE293-WKKD-Input.flt.bam --outdir 5-peak-calling/broad/ -n HKE293-WKKD 2> log/HKE293-WKKD.macs2.broad.log &

可以将建模和不建模的narrowPeak结果在IGV进行比较,你会发现之前的CHTF8和CIRH1A上的两个信号峰在默认参数下就被认为是成一个。

是否建模

文章中对找到peak进行了一次筛选,标准是大于5倍富集和q-value 小于或等于0.001(broad peak则是0.0001),最后文章写着在D210N有12,906peak,然后剔除WKKD里的peak,还有12,507个。

我找到的HKE293-D210的原始narrowPeak数为17,558, 按照作者的标准筛选后只剩下9,552,。对于HKE2930-D210的原始broadPeak数为42,912,过滤之后只剩2,998了。隐隐觉得peak有点太少了,于是我的标准是4倍变化。

负对照的WKKD无论是narrowPeak还是broadPeak都是0

cd analysis/5-peak-calling/
fc=4
# narrow peak
awk -v fc=$fc '$7 >= fc && $9 >=3' narrow/HKE293-D210_peaks.narrowPeak > HKE293-D210_flt.narrowPeak
# broad peak
awk -v fc=$fc '$7 >= fc && $9 >=4' broad/HKE293-D210_peaks.broadPeak > HKE293-D210_flt.broadPeak

之后可以用过滤后的D210N的narrowPeak和broadPeak的peak长度进行描述性统计分析,然后用箱线图展示其大小分布。

library(data.table)
library(ggplot2)

narrowPeak <- fread(file="HKE293-D210_flt.narrowPeak",
                   sep="\t", header = F)
broadPeak <- fread(file="HKE293-D210_flt.broadPeak",
                    sep="\t", header = F)
peak_size <- log10(c(narrowPeak$V3 - narrowPeak$V2, broadPeak$V3 - broadPeak$V2 ))

peak_from <- factor(rep(c('Narrow','Broad'), times=c(nrow(narrowPeak),nrow(broadPeak)) ),
                    levels=c("Narrow","Broad"))

peak_df <- data.frame(size=peak_size, from=peak_from)

my_clear_theme = theme_bw() + 
  theme(panel.grid.major = element_line(colour="NA"),
        panel.grid.minor = element_line(colour="NA"),
        panel.background = element_rect(fill="NA"),
        panel.border = element_rect(colour="black", fill=NA),
        legend.background = element_blank())

ggplot(peak_df,aes(x=from,y=size,col=from)) + 
  geom_boxplot(notch = T,outlier.size = .5) +
  scale_y_continuous(breaks=c(log10(100),log10(300),log10(400),log10(450),log10(500),log10(1000),log10(2000)),
                     labels = c(100,300,400,450,500,1000,2000)) +
  coord_cartesian(ylim=c(2,3.5)) + labs(col="Peak Size") +
  my_clear_theme + xlab("") + ylab("Peak Size (bp)")
ggsave("Fig2A_boxplot.pdf", width=4,height=6,units = "in")

boxplot of peak width

原文说自己的narrow peak 长度的中位数是199bp, broad peak的长度中位数是318 bp,和电镜观察的150–500 bp一致。我过滤后的peak的中位数是208,broad peak的中位数是581。

如果你无脑用MACS2的参数话,就会得到右边的图,peak的长度明显都偏大了。

还可以对Broad peak 和Narrow peak进行比较,看看有多少共同peak和特异性peak。

#!/bin/bash

peak1=${1?first peak}
peak2=${2?second peak}
outdir=${3?output dir}

mkdir -p ${outdir}

bedtools intersect -a $peak1 -b $peak2 > ${outdir}/$(basename ${peak1%%.*}).common.peak
common=$(wc -l ${outdir}/$(basename ${peak1%%.*}).common.peak)
echo "$common"

bedtools subtract -A -a $peak1 -b $peak2 > ${outdir}/$(basename ${peak1}).only.bed
left=$(wc -l ${outdir}/$(basename ${peak1}).only.bed)

echo "$left"

bedtools subtract -A -b $peak1 -a $peak2 > ${outdir}/$(basename ${peak2}).only.bed
right=$(wc -l ${outdir}/$(basename ${peak2}).only.bed)

echo "$right"

运行:bash scripts/09.peak_comparison.sh analysis/5-peak-calling/HKE293-D210_flt.narrowPeak analysis/5-peak-calling/HKE293-D210_flt.broadPeak analysis/5-peak-calling/peak_compare > results/narrow_vs_broad.txt

然后得到的数值就可以丢到R语言画图了,这个结果和Figure S2A一致。

library(VennDiagram)
grid.newpage()
venn.plot <- VennDiagram::draw.pairwise.venn(area1=6401 + 7165,
                                area2=286 + 7165,
                                cross.area = 7165,
                                category = c("Narrow specific","Broad specific"),
                                scaled = F,
                                fill=c("#c7d0e7","#f4babf"),
                                lty='blank',
                                cat.pos = c(180,0),#360度划分
                                rotation.degree = 90 #整体旋转90
                                )
grid.draw(venn.plot)

venn plot

我们可以对这三类peak对应区间内的信号进行一下比较。统计信号强度的工具是bigwigSummary,来自于ucscGenomeBrowser工具集。

脚本为scripts/10.peak_signal_summary.sh

#!/bin/bash

bed=${1?bed file}
fwd=${2?forwad bigwig}
rvs=${3?reverse bigwig}

exec 0< $bed

while read region
do
    chr=$( echo $region | cut -d ' ' -f 1)
    sta=$( echo $region | cut -d ' ' -f 2)
    end=$( echo $region | cut -d ' ' -f 3)
    (bigWigSummary $fwd $chr $sta $end 1 ; bigWigSummary $rvs $chr $sta $end 1 )| awk -v out=0 '{out=out+$1} END{print out/2}'
done

分别统计三类peak的信号的信号

bash scripts/10.peak_signal_summary.sh analysis/5-peak-calling/peak_compare/HKE293-D210_flt.broadPeak.only.bed analysis/4-normliazed-bw/HKE293-D210N-V5ChIP_fwd.bw analysis/4-normliazed-bw/HKE293-D210N-V5ChIP_rvs.bw > results/HKE293-D210N-V5ChIP.broadSignal
bash scripts/10.peak_signal_summary.sh analysis/5-peak-calling/peak_compare/HKE293-D210_flt.narrowPeak.only.bed analysis/4-normliazed-bw/HKE293-D210N-V5ChIP_fwd.bw analysis/4-normliazed-bw/HKE293-D210N-V5ChIP_rvs.bw > results/HKE293-D210N-V5ChIP.narrowSignal
bash scripts/10.peak_signal_summary.sh analysis/5-peak-calling/peak_compare/HKE293-D210_flt.common.peak analysis/4-normliazed-bw/HKE293-D210N-V5ChIP_fwd.bw analysis/4-normliazed-bw/HKE293-D210N-V5ChIP_rvs.bw > results/HKE293-D210N-V5ChIP.commonSignal

在R语言中绘图展示

# peak signal
commonSignal <- fread("./HKE293-D210N-V5ChIP.commonSignal")
narrowSignal <- fread("./HKE293-D210N-V5ChIP.narrowSignal")
broadSignal <-  fread("./HKE293-D210N-V5ChIP.broadSignal")

data <- data.frame(signal=c(commonSignal$V1, narrowSignal$V1, broadSignal$V1),
                   type=factor(rep(c("common","narrow","broad"),
                            times=c(nrow(commonSignal),nrow(narrowSignal), nrow(broadSignal)))) )

wilcox.test(data[data$type=="common",1],data[data$type=="broad",1])
wilcox.test(data[data$type=="common",1],data[data$type=="narrow",1])


p <- ggplot(data,aes(x=type,y=signal,col=type)) + 
  geom_boxplot(outlier.colour = "NA") +
  coord_cartesian(ylim=c(0,3.5)) +
  theme(panel.grid.major = element_line(colour="NA"),
        panel.grid.minor = element_line(colour="NA"),
        panel.background = element_rect(fill="NA"),
        panel.border = element_rect(colour="black", fill=NA)) +
  theme(axis.text.x = element_blank()) +
  xlab("") + ylab("R-loop Signal") + labs(col="") 


p1 <- p + annotate("segment", x=1,xend=1,y=0.75,yend=2,size=0.5) + 
  annotate("segment", x=2,xend=2,y=1.25,yend=2,size=0.5) +
  annotate("segment", x=1,xend=2,y=2,yend=2,size=0.5) +
  annotate("text", x= 1.5, y=2.1, label="***") 

p2 <- p1 + annotate("segment", x=3,xend=3,y=0.65,yend=3,size=0.5) + 
  annotate("segment", x=2,xend=2,y=2.2,yend=3,size=0.5) +
  annotate("segment", x=2,xend=3,y=3,yend=3,size=0.5) +
  annotate("text", x= 2.5, y=3.2, label="***") 

p2

signal comparison

看图说话: 无论是narrow peak 特异区间的信号,还是broad peak 特异区间的信号都显著性低于其共有区间的信号。

r-chip-data-analysis's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.