前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >表观调控13张图之四,peaks区域注释分类比例

表观调控13张图之四,peaks区域注释分类比例

作者头像
生信技能树
发布2019-12-30 14:56:32
3.8K0
发布2019-12-30 14:56:32
举报
文章被收录于专栏:生信技能树

我们已经公布了:6个小时的表观调控13张图视频课程免费大放送哦 其实很多朋友并没有留意到我们不仅仅是有视频,还有配套的学徒解读:

我把表观调控数据分析,拆分成为了13张图,分别录制为13个视频,即将免费发布在B站,这个期间我们的视频编辑师还在兢兢业业的奋斗,希望这13张图能带领大家学会表观调控数据分析的一般流程, 然后应用到自己的课题哈!同时我也招募了4位视频审查员和细节知识补充员。接下来我们就连载第一位视频审查员的13个笔记:

第一位视频审查员大家也许并不陌生了,早在2018-08-29我发布给学徒的ATAC-seq数据实战(附上收费视频) 他就学完了全部课程内容,还写了笔记在简书,大家搜索二货潜,就可以看到。

以下是正文

本文目录:

  1. 批量对Peak进行注释 01:环境准备 02:Peak注释
  2. 注释Peak函数编写
  3. 批量进行注释

本章节我们的视频审查员(刘博-二货潜)将继续带领大家学习视频,并且复现附件中Figure S1b的一张图,如下:

这里我们是下载文章附件中的 Peak 文件。

批量对Peak进行注释

"我们要学会变通,不要只会 copy 代码,要学会举一反三。不是背代码,而是去探寻规律。"因为文章当时做的时候是采用d3版的注释信息,而我们是下载了文章附件提供的Peak文件,所以我们这里分析要用d3版本的注释信息。

文章 ChIP-seq 分析方法:ChIP-Seq data were first processed using Trim Galore, then aligned to reference genome (dm3, BDGP Release 5) using Bowtie v1.1.2, 可以看到基因版本为d3.

01

环境准备

由于国内镜像网速普遍不好,所以我们在进行相关R包安装之前需要指定镜像源。

代码语言:javascript
复制
# 运行
file.edit("~/.Rprofile")

# 然后再打开的命令中设置清华源信息
options("repos" = c(CRAN="https://mirrors.tuna.tsinghua.edu.cn/CRAN/"))
options(BioC_mirror = "https://mirrors.tuna.tsinghua.edu.cn/bioconductor")

# 然后点击 Rstudio 右上角的 source 即可

02

Peak注释

代码语言:javascript
复制
# 放在前面的话:一般要安装什么包直接搜索包名,对应的包的 manual 说怎么装就怎么装
BiocManager::install("TxDb.Dmelanogaster.UCSC.dm3.ensGene")
BiocManager::install("org.Dm.eg.db")
BiocManager::install("ChIPseeker")
BiocManager::install("clusterProfiler")

# 加载包
require(ChIPseeker)
require(TxDb.Dmelanogaster.UCSC.dm3.ensGene)
require(clusterProfiler) 

txdb <- TxDb.Dmelanogaster.UCSC.dm3.ensGene

# 读取当前目录 oldBedFiles 文件夹下的 Peak 文件
bedPeaksFile = './oldBedFiles/Cg_WT.narrowPeak.bed'; 
bedPeaksFile
# [1] "./oldBedFiles/Cg_WT.narrowPeak.bed"
peak <- readPeakFile( bedPeaksFile) 

# 查看 Peak 文件中染色体信息
seqlevels(peak)
# [1] "chr2L"    "chr2LHet" "chr2R"    "chr2RHet" "chr3L"    "chr3LHet" "chr3R"    "chr3RHet" "chr4"     "chrM"     "chrX" "chrXHet"  "chrYHet"

# 过滤掉带有 Het 字眼的染色体
# 请留意 `grepl()` 函数
keepChr = !grepl('Het',seqlevels(peak)) 
seqlevels(peak, pruning.mode = "coarse") <- seqlevels(peak)[keepChr]

插播知识点

pruning.mode 参数有几种选项:c("error", "coarse", "fine", "tidy")

代码语言:javascript
复制
# 默认是 "error" 
# 大致说一下每个参数对应的意思(实际上我就是翻译 manual 哈)
# "error":没有修剪(pruning),并且引发错误
# "coarse": 删除 x 中正在使用的要删除的 seqlevel 的元素
# "fine": 支持 `list` 格式,删除要删除的序列上的范围,不影响原来文件的长度和排序,修剪后的对象与原始对象一样。
# "tidy": 
# emmm, 解释的过为牵强,还是有需要的看原文吧。
# https://web.mit.edu/~r/current/arch/i386_linux26/lib/R/library/GenomeInfoDb/html/seqinfo.html

## ---------------------------------------------------------------------
## 重命名 TxDb 对象的染色体信息
## ---------------------------------------------------------------------
# 比如
library(TxDb.Dmelanogaster.UCSC.dm3.ensGene)
txdb <- TxDb.Dmelanogaster.UCSC.dm3.ensGene
seqlevels(txdb)
# "chr2L"     "chr2R"     "chr3L"     "chr3R"     "chr4"      "chrX"      "chrU"      "chrM"      "chr2LHet"  "chr2RHet" "chr3LHet"  "chr3RHet"  "chrXHet"   "chrYHet"   "chrUextra"

# 使用 `sub()` 函数将染色体前缀 `chr` 替换为空,即 `chr1` 变成 `1`
seqlevels(txdb) <- sub("chr", "", seqlevels(txdb))
seqlevels(txdb)
#  [1] "2L"     "2R"     "3L"     "3R"     "4"      "X"      "U"      "M"      "2LHet"  "2RHet"  "3LHet"  "3RHet"  "XHet"   "YHet"  "Uextra"

# 使用 `paste0` 函数体加前缀,即 `1`变成 `CH1`
seqlevels(txdb) <- paste0("CH", seqlevels(txdb))
seqlevels(txdb)
#  [1] "CH2L"     "CH2R"     "CH3L"     "CH3R"     "CH4"      "CHX"      "CHU"      "CHM"      "CH2LHet"  "CH2RHet"  "CH3LHet" "CH3RHet"  "CHXHet"   "CHYHet"   "CHUextra"

# 修改某一条染色体名称,比如这里将染色体 `CHM` 改为 `M`
seqlevels(txdb)[seqlevels(txdb) == "CHM"] <- "M"
seqlevels(txdb)
#  [1] "CH2L"     "CH2R"     "CH3L"     "CH3R"     "CH4"      "CHX"      "CHU"      "M"        "CH2LHet"  "CH2RHet"  "CH3LHet" "CH3RHet"  "CHXHet"   "CHYHet"   "CHUextra"

# 使用 `seqlevels0()` 函数恢复原来的染色体水平
seqlevels(txdb) <- seqlevels0(txdb)
seqlevels(txdb)
# [1] "chr2L"     "chr2R"     "chr3L"     "chr3R"     "chr4"      "chrX"      "chrU"      "chrM"      "chr2LHet"  "chr2RHet" "chr3LHet"  "chr3RHet"  "chrXHet"   "chrYHet"   "chrUextra"

## ---------------------------------------------------------------------
## 
## ---------------------------------------------------------------------
tx <- transcripts(txdb)
seqlevels(tx)
# [1] "chr2L"     "chr2R"     "chr3L"     "chr3R"     "chr4"      "chrX"      "chrU"      "chrM"      "chr2LHet"  "chr2RHet" "chr3LHet"  "chr3RHet"  "chrXHet"   "chrYHet"   "chrUextra"

# 丢弃 `chrM` 染色体,保留其它的染色体
seqlevels(tx, pruning.mode="coarse") <- seqlevels(tx)[seqlevels(tx) != "chrM"]
seqlevels(tx)
#  [1] "chr2L"     "chr2R"     "chr3L"     "chr3R"     "chr4"      "chrX"      "chrU"      "chr2LHet"  "chr2RHet"  "chr3LHet"  "chr3RHet"  "chrXHet"   "chrYHet"   "chrUextra"

# 除了 `ch3L` 和 `ch3R` 染色体保留,其余的都丢掉
seqlevels(tx, pruning.mode = "coarse") <- c("ch3L", "ch3R")
seqlevels(tx)
# [1] "ch3L" "ch3R"

## 番外详情见开始链接,这个知识点必须掌握,特别是有的是支持`chr1`类的,有的是支持`1`类的,就涉及要转换,当然其它方法也可以。

Peak 注释

代码语言:javascript
复制
# 查看有多少个peak
cat(paste0('there are ',length(peak),' peaks for this data' ))

# 使用 annotatPeak 进行注释,
peakAnno <- annotatePeak(peak, tssRegion = c(-3000, 3000), 
                         TxDb = txdb, annoDb = "org.Dm.eg.db") 

# 转变成 data.frame 格式文件,方便查看与后续操作
peakAnno_df <- as.data.frame(peakAnno)

# 获取样本名
sampleName = basename(strsplit(bedPeaksFile,'\\.')[[1]][1])
print(sampleName)
# [1] "Cg_WT"
## ---------------------------------------------------------------------
## 这里我拆开给大家一步一步看,大神可以直接跳过这里
## ---------------------------------------------------------------------
bedPeaksFile
# [1] "./oldBedFiles/Cg_WT.narrowPeak.bed"

# 使用 strsplit() 函数对 bedPeakFile 中的内容用 '.' 来切割
strsplit(bedPeaksFile,'\\.')
#[[1]]
#[1] ""                   "/oldBedFiles/Cg_WT" "narrowPeak"         "bed" 

# 然后我们要提取 "/oldBedFiles/Cg_WT" 信息
strsplit(bedPeaksFile,'\\.')[[1]][2]
# [1] "/oldBedFiles/Cg_WT"

# 然后通过 `basename()` 函数去掉前面的路径信息,即获得样本名
basename(strsplit(bedPeaksFile,'\\.')[[1]][2])
# [1] "Cg_WT"

peak 进行可视化,可以看到大部分 peak 都位于启动子区。

代码语言:javascript
复制
plotAnnoPie(peakAnno)
plotAnnoBar(peakAnno)

但是我们可以看到文章中的图是有好几个 sample 在一起的,而且注释的分布类也没这么细致,所以我们需要进行批量的 Peak 注释,并将其绘制出来

注释Peak函数编写

代码语言:javascript
复制
anno_bed <- function(bedPeaksFile){
  peak <- readPeakFile( bedPeaksFile )  # 第一步肯定是读取 peak 文件
  keepChr = !grepl('Het',seqlevels(peak)) # 提取不包含 Het 的染色体
  seqlevels(peak, pruning.mode="coarse") <- seqlevels(peak)[keepChr] # 第三步就是过滤包含 Het 的染色体
  cat(paste0('there are ',length(peak),' peaks for this data' )) # 第四步查看此 peak 文件有多少行
  peakAnno <- annotatePeak(peak, tssRegion = c(-3000, 3000), 
                           TxDb = txdb, annoDb = "org.Dm.eg.db")  # 第五步对 Peak 进行注释
  peakAnno_df <- as.data.frame(peakAnno) # 第六步将 peakAnno 文件转换为 dataframe 格式文件,方便操作
  sampleName = basename(strsplit(bedPeaksFile,'\\.')[[1]][1]) # 第七步提取此 peak 的样本信息
  return(peakAnno_df)
}

# 可以看到就是替换掉了前面所导入的 Peak 文件变量,比较知识换一下就好了

批量进行注释

代码语言:javascript
复制
require(ChIPseeker)
# BiocManager::install("TxDb.Dmelanogaster.UCSC.dm3.ensGene")
# BiocManager::install("org.Dm.eg.db")
require(TxDb.Dmelanogaster.UCSC.dm3.ensGene  )
txdb <- TxDb.Dmelanogaster.UCSC.dm3.ensGene
require(clusterProfiler) 

# 得到 oldBedFiles 文件目录下所有 WT 的 peak 文件,构成一个 list
f = list.files(path = 'oldBedFiles/',pattern = 'WT',full.names = T)
f
[1] "oldBedFiles/Cg_WT.narrowPeak.bed"     "oldBedFiles/Ez_WT.narrowPeak.bed"     "oldBedFiles/Pc_WT.narrowPeak.bed"    "oldBedFiles/Ph_WT.narrowPeak.bed.bed" "oldBedFiles/Pho_WT.narrowPeak.bed"    "oldBedFiles/Psc_WT.narrowPeak.bed"   "oldBedFiles/Spps_WT.narrowPeak.bed"

# 结合上面我们编写的函数使用 lapply 进行批量注释
# 这里需要好好学习 apply() 家族函数的学习
# lapply 可以用 list
# 可以看到 Rstudio 右上方 tmp 文件是含有 7 的
tmp = lapply(f, anno_bed)

# 提取 list 中的第一个文件进行查看
# 我们可以清楚看到有 Peak 的坐标信息,以后注释到的基因的位置信息以及基因名,距离基因 TSS 有多远等。
head(tmp[[1]])
  seqnames start   end width strand           V4   V5 V6      V7        V8        V9 V10       annotation geneChr geneStart geneEnd
1    chr2L  5104  5375   272      * Cg_WT_peak_1   45  . 2.29299   5.95519   4.56517  19 Promoter (2-3kb)       1      7529    9484
2    chr2L  5544  5962   419      * Cg_WT_peak_2  268  . 3.91194  28.67657  26.81658 194 Promoter (1-2kb)       1      7529    9484
3    chr2L 16625 17115   491      * Cg_WT_peak_3  953  . 8.46518  97.93490  95.38403 171 Promoter (1-2kb)       1      9839   18570
4    chr2L 17743 19205  1463      * Cg_WT_peak_4 1011  . 6.21549 103.78052 101.17944 887 Promoter (<=1kb)       1      9839   18570
5    chr2L 19439 19789   351      * Cg_WT_peak_5  654  . 6.04155  67.72665  65.43917 208 Promoter (<=1kb)       1      9839   18570
6    chr2L 20538 21944  1407      * Cg_WT_peak_6 1413  . 9.20858 144.25723 141.30544 889 Promoter (<=1kb)       1      9839   21376
  geneLength geneStrand      geneId transcriptId distanceToTSS ENTREZID  SYMBOL                GENENAME
1       1956          1 FBgn0031208  FBtr0300689         -2154    33155 CG11023 uncharacterized protein
2       1956          1 FBgn0031208  FBtr0300689         -1567    33155 CG11023 uncharacterized protein
3       8732          2 FBgn0002121  FBtr0078170          1455    33156  l(2)gl lethal (2) giant larvae
4       8732          2 FBgn0002121  FBtr0078170             0    33156  l(2)gl lethal (2) giant larvae
5       8732          2 FBgn0002121  FBtr0078171          -869    33156  l(2)gl lethal (2) giant larvae
6      11538          2 FBgn0002121  FBtr0078166             0    33156  l(2)gl lethal (2) giant larvae
代码语言:javascript
复制
# 然而我们这里绘制此图可以看出只需要 annotation 那一列的信息。
# 首先我们来统计一个 Peak 的注释分布数目
test = tmp[[1]]
num1 = length(grep('Promoter', test$annotation))
num2 = length(grep("5' UTR", test$annotation))
num3 = length(grep('Exon', test$annotation))
num4 = length(grep('Intron', test$annotation))
num5 = length(grep("3' UTR", test$annotation))
num6 = length(grep('Intergenic', test$annotation))
c(num1,num2,num3,num4,num5,num6 )
# [1] 12250    32    99  3291   148  1999

# 我们可以看到对于不同的 Peak,只需要换一下名字即可,那么我们就可以写成函数
df = do.call(rbind,lapply(tmp, function(x){
  #table(x$annotation)
  num1 = length(grep('Promoter',x$annotation))
  num2 = length(grep("5' UTR",x$annotation))
  num3 = length(grep('Exon',x$annotation))
  num4 = length(grep('Intron',x$annotation))
  num5 = length(grep("3' UTR",x$annotation))
  num6 = length(grep('Intergenic',x$annotation))
  return(c(num1,num2,num3,num4,num5,num6 ))
}))

df
#      [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 12250   32   99 3291  148 1999
#[2,]  7057   15   63 1027   79 1113
#[3,]  3871   12   69  763   37 1110
#[4,] 10558   34   92 2819   67 1809
#[5,]  6776    9   55 1436   40 1343
#[6,] 10085   19   79 2255   46 1669
# [7,]  3691    5   18  507   11  410

# 赋值列名
colnames(df) = c('Promoter',"5' UTR",'Exon','Intron',"3' UTR",'Intergenic')

# 加上行名,即样本名
# 这里好好理解以下 unlist 函数
rownames(df) = unlist(lapply(f, function(x){
  basename(strsplit(x,'\\.')[[1]][1])
}))

df
#        Promoter 5' UTR Exon Intron 3' UTR Intergenic
#Cg_WT      12250     32   99   3291    148       1999
#Ez_WT       7057     15   63   1027     79       1113
#Pc_WT       3871     12   69    763     37       1110
#Ph_WT      10558     34   92   2819     67       1809
#Pho_WT      6776      9   55   1436     40       1343
#Psc_WT     10085     19   79   2255     46       1669
#Spps_WT     3691      5   18    507     11        410

# 由于是百分比,我们可以再转换成百分比数据,其实也可以不转
df1 <- apply(df, 1, function(x) x/sum(x))
df1
#                  Cg_WT       Ez_WT       Pc_WT       Ph_WT       Pho_WT      Psc_WT     Spps_WT
# Promoter   0.687468433 0.754436605 0.660354828 0.686520580 0.7015218967 0.712569773 0.795131409
# 5' UTR     0.001795836 0.001603592 0.002047083 0.002210807 0.0009317735 0.001342472 0.001077122
# Exon       0.005555867 0.006735087 0.011770727 0.005982183 0.0056941712 0.005581855 0.003877639
# Intron     0.184690499 0.109792602 0.130160355 0.183301905 0.1486696345 0.159330177 0.109220164
# 3' UTR     0.008305741 0.008445585 0.006311839 0.004356590 0.0041412154 0.003250194 0.002369668
# Intergenic 0.112183624 0.118986530 0.189355169 0.117627934 0.1390413086 0.117925528 0.088323998

好了,到目前位置,我们得到了绘制此图所需要的数据,接下来进行可视化

代码语言:javascript
复制
# 将数据转换成 ggpurb 所需要的格式
library(reshape2)
df2 = melt(df1)
colnames(df2) = c('dis','sample','fraction')
head(df2)
#         dis sample    fraction
#1   Promoter  Cg_WT 0.687468433
#2     5' UTR  Cg_WT 0.001795836
#3       Exon  Cg_WT 0.005555867
#4     Intron  Cg_WT 0.184690499
#5     3' UTR  Cg_WT 0.008305741
#6 Intergenic  Cg_WT 0.112183624

library(ggpubr)
ggbarplot(df2, "sample", "fraction",
          fill = "dis", color = "dis", palette = "jco" )

想和文章一样的配色?还记得在重复第一个图的时候提到的 Takecolor ? 直接吸就完事

代码语言:javascript
复制
# 吸到的颜色。。。
my_color = c("#DD2A18", # 红色
             "#41678B", # 蓝色
             "#42A441", # 绿色
             "#8C4498", # 紫色
             "#FE7400", # 橙色
             "#FEFE2D") # 黄色

ggbarplot(df2, "sample", "fraction",
          fill = "dis", color = "black", palette = my_color ) +
  guides(fill = guide_legend(nrow = 1))

最后的最后,虽然有些地方和文章不同,但是此文仅提供思想,比如这里的注释到底怎么划分是要按照大家各自的需求来的。所以参考就好。ggpurb 虽然便捷,但是如果你用 R 用的频繁,那么请您好好学习 ggplot2 或者 baseplot 等。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信技能树 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档