GDAS008-IRanges和GRanges


title: GDAS008-IRanges和GRanges
date: 2019-09-078 12:0:00
type: "tags"
tags:

  • Bioconductor
    categories:
  • Genomics Data Analysis Series

前言

原始的Rmd文档可以参考Github上。

IRangesGRanges 对象是Bioconductor基础数据类型的核心成员,其中 IRanges 定义了 integer ranges ,它用于解决基因组上的位置问题,而 GRanges 则包含了染色体和DNA链的信息。这里我们简介绍一下这两个对象,以及如何操作 IRangesGRanges

IRanges

第一步是加载IRanges包,如下所示:

library(IRanges)

IRanges 函数定义了区间范围(interval ranges)。如果你输入2个数据,那么就表示一个区间,例如 [5,10]={5,6,7,8,9,10},它的宽度是6。另外,如果我们要查看一个 IRanges 定义的区间宽度,我们使用的width()函数,而非 length()函数,如下所示:

ir <- IRanges(5,10)
ir
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         5        10         6
start(ir)
## [1] 5
end(ir)
## [1] 10
width(ir)
## [1] 6
# for detailed information on the IRanges class:
# ?IRanges
length(ir)
# [1] 1

一个单独的IRanges对象可以含有多个范围。现在我们可以在一个向量中指定start,在另外一个向量中指定end,如下所示:

IRanges(start=c(3,5,17), end=c(10,8,20))
## IRanges object with 3 ranges and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         3        10         8
##   [2]         5         8         4
##   [3]        17        20         4

内部范围(Intra-range)操作

现在我们继续使用单个范围[5,10],我们查看内部范围(intra-range){…,−2,−1,0,1,2,…}的一个数,如下所示:

# full details on the intra-range methods:
# ?"intra-range-methods"
ir
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         5        10         6
shift(ir, -2)
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         3         8         6

这里我们展示了应用于ir的多个不同操作的结果,结果如下所示:

ir
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         5        10         6
narrow(ir, start=2)
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         6        10         5
narrow(ir, end=5)
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         5         9         5
flank(ir, width=3, start=TRUE, both=FALSE)
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         2         4         3
flank(ir, width=3, start=FALSE, both=FALSE)
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]        11        13         3
flank(ir, width=3, start=TRUE, both=TRUE)
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         2         7         6
ir * 2
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         6         8         3
ir * -2
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         2        13        12
ir + 2
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         3        12        10
ir - 2
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         7         8         2
resize(ir, 1)
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         5         5         1

我们使用下图展示了上面操作的结果。红色柱状部分显示了最初的ir范围。掌握这些操作的最好方法是在自己定义的范围内在控制台中亲自操作一下。

plot of chunk unnamed-chunk-6

内部范围方法

针对intra-range有着一系列的方法。还有一些方法是针对一系列范围的操作,它的输出取决于所有的范围,因此这些方法与intra-range方法不同,后者不会改变输出。现在我们一些案例来说明一下。range()函数提供了从最左侧到最右侧的整数输出,如下所示:

注:原文我不太理解,翻译的不精准,原文如下:

There are also a set of inter-range methods. These are
operations which work on a set of ranges, and the output depends on all
the ranges, thus distinguishes these methods from the intra-range methods, for which the other ranges in the set do not change the output. This is best explained with some examples. The range function gives the integer range from the start of the leftmost range to the end of the rightmost range:

# full details on the inter-range methods:
# ?"inter-range-methods"
(ir <- IRanges(start=c(3,5,17), end=c(10,8,20)))
## IRanges object with 3 ranges and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         3        10         8
##   [2]         5         8         4
##   [3]        17        20         4
range(ir)
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         3        20        18

reduce 函数能折叠这些范围,以便于整个可以只被输出范围中的一个范围覆盖,如下所示:

reduce(ir)
## IRanges object with 2 ranges and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         3        10         8
##   [2]        17        20         4

注:ir原来有3个范围,其中[5,8]范围是在[3,10]之间,因此前者被折叠到了后者之中。

gaps 函数能够给出上面两个范围的区间,但是它不覆盖任何ir中的范围,如下所示:

gaps(ir)
## IRanges object with 1 range and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]        11        16         6

disjoin 会打断 ir的范围,并它们分成不同的范围,如下所示:

disjoin返回一个disjoint对象,它会查看参数中端点的并集,返回不相交的对象。换话句讲,结果中由区间的最大长度范围组成,在该范围上,对象x中的重叠范围集合是相同的,并且至少为1。

disjoin(ir)
## IRanges object with 4 ranges and 0 metadata columns:
##           start       end     width
##       <integer> <integer> <integer>
##   [1]         3         4         2
##   [2]         5         8         4
##   [3]         9        10         2
##   [4]        17        20         4

现在我们使用示意图来说明一下:

image

第一二行是原始的范围,第四行是经过disjoin处理后的范围。

GRanges

GRanges对象包含了Iranges,它含有2个方面的重要信息:

  • 染色体信息(Bioconductor称为 seqnames)。
  • DNA链。

链的信息可以指定为 + 号或 - ,或者是保留未指定的 * 。正义链的特征则是在编号线上从左到右的生物学方面,而负链特征则是从右到左。就IRanges而言,正链特征是从startend ,负链则是从 endstart 。这初看起来比较混乱,但这是必需的,因此 width 被定义为 end - start + 1,并且不允许有负的宽度范围。因为DNA有两条链,这两条链具有相反的方向性,因此当我们说DNA时,可以只指明其中的一条链。

通过IRnage、染色体名称和一条链,我们可以确定我们与另外一个研究人员所指的DNA分子具有相同的区域和链,因为我们使用的相同的基因组构建的。GRanges对象中还可以包括其它部分的信息,不过上述的两个信息则是最重要的 。

library(GenomicRanges)

现在我们创建一个虚构染色体chrZ 上的两个范围。我们会说这两个范围指的基因组hg19上的范围。因为我们没有将我们的基因组链接到数据库,因此我们可以指定一个在hg19中并不存在的染色体,如下所示:

gr <- GRanges("chrZ", IRanges(start=c(5,10),end=c(35,45)),
              strand="+", seqlengths=c(chrZ=100L))
gr
## GRanges object with 2 ranges and 0 metadata columns:
##       seqnames    ranges strand
##          <Rle> <IRanges>  <Rle>
##   [1]     chrZ  [ 5, 35]      +
##   [2]     chrZ  [10, 45]      +
##   -------
##   seqinfo: 1 sequence from an unspecified genome
genome(gr) <- "hg19"
gr
## GRanges object with 2 ranges and 0 metadata columns:
##       seqnames    ranges strand
##          <Rle> <IRanges>  <Rle>
##   [1]     chrZ  [ 5, 35]      +
##   [2]     chrZ  [10, 45]      +
##   -------
##   seqinfo: 1 sequence from hg19 genome

我们可以调用 seqnamesseqlengths 来查看上面的信息:

seqnames(gr)
## factor-Rle of length 2 with 1 run
##   Lengths:    2
##   Values : chrZ
## Levels(1): chrZ
seqlengths(gr)
## chrZ 
##  100

我们可以使用 shift 函数(就像在IRanges中使用的一样)来处理GRanges。但是,当我们尝试超过染色体长度之外的范围时,就会出现警告信息,如下所示:

shift(gr, 10)
## GRanges object with 2 ranges and 0 metadata columns:
##       seqnames    ranges strand
##          <Rle> <IRanges>  <Rle>
##   [1]     chrZ  [15, 45]      +
##   [2]     chrZ  [20, 55]      +
##   -------
##   seqinfo: 1 sequence from hg19 genome
shift(gr, 80)
## Warning in valid.GenomicRanges.seqinfo(x, suggest.trim = TRUE): GRanges object contains 2 out-of-bound ranges located on sequence
##   chrZ. Note that only ranges located on a non-circular sequence
##   whose length is not NA can be considered out-of-bound (use
##   seqlengths() and isCircular() to get the lengths and circularity
##   flags of the underlying sequences). You can use trim() to trim
##   these ranges. See ?`trim,GenomicRanges-method` for more
##   information.
## GRanges object with 2 ranges and 0 metadata columns:
##       seqnames    ranges strand
##          <Rle> <IRanges>  <Rle>
##   [1]     chrZ [85, 115]      +
##   [2]     chrZ [90, 125]      +
##   -------
##   seqinfo: 1 sequence from hg19 genome

如果我们使用 trim 处理这个范围,我们就能获取剩下的范围,而不考虑超出染色体长的部分:

trim(shift(gr, 80))
## Warning in valid.GenomicRanges.seqinfo(x, suggest.trim = TRUE): GRanges object contains 2 out-of-bound ranges located on sequence
##   chrZ. Note that only ranges located on a non-circular sequence
##   whose length is not NA can be considered out-of-bound (use
##   seqlengths() and isCircular() to get the lengths and circularity
##   flags of the underlying sequences). You can use trim() to trim
##   these ranges. See ?`trim,GenomicRanges-method` for more
##   information.
## GRanges object with 2 ranges and 0 metadata columns:
##       seqnames    ranges strand
##          <Rle> <IRanges>  <Rle>
##   [1]     chrZ [85, 100]      +
##   [2]     chrZ [90, 100]      +
##   -------
##   seqinfo: 1 sequence from hg19 genome

我们可以使用 mcols 函数(链表示元数据列)向每个范围添加列信息。需要注意的是,这个操作对IRanges也是可行的。我们还可以通过指定 NULL 来移除列信息,如下所示:

mcols(gr)
## DataFrame with 2 rows and 0 columns
mcols(gr)$value <- c(-1,4)
gr
## GRanges object with 2 ranges and 1 metadata column:
##       seqnames    ranges strand |     value
##          <Rle> <IRanges>  <Rle> | <numeric>
##   [1]     chrZ  [ 5, 35]      + |        -1
##   [2]     chrZ  [10, 45]      + |         4
##   -------
##   seqinfo: 1 sequence from hg19 genome
mcols(gr)$value <- NULL
> gr
# GRanges object with 2 ranges and 0 metadata columns:
#      seqnames    ranges strand
#         <Rle> <IRanges>  <Rle>
#  [1]     chrZ      5-35      +
#  [2]     chrZ     10-45      +
#  -------
#  seqinfo: 1 sequence from hg19 genome

GRangesList

当我们涉及基因时,我们通过创建一个GRanges列表是很有用的,例如用于表示分组信息(比如每个基因的外显子)。该列表的元素是基因,并且在每个元素中,外显子的范围被定义为GRanges。

gr2 <- GRanges("chrZ",IRanges(11:13,51:53))
grl <- GRangesList(gr, gr2)
grl
## GRangesList object of length 2:
## [[1]] 
## GRanges object with 2 ranges and 0 metadata columns:
##       seqnames    ranges strand
##          <Rle> <IRanges>  <Rle>
##   [1]     chrZ  [ 5, 35]      +
##   [2]     chrZ  [10, 45]      +
## 
## [[2]] 
## GRanges object with 3 ranges and 0 metadata columns:
##       seqnames   ranges strand
##   [1]     chrZ [11, 51]      *
##   [2]     chrZ [12, 52]      *
##   [3]     chrZ [13, 53]      *
## 
## -------
## seqinfo: 1 sequence from hg19 genome

GRangesList 对象中的长度就是其中的GRanges 对象个数。为了获取每个GRanges的长度,我们可以调用 elementNROWS。我们可以通过两个方括号的典型列表索引方法来建立索引,如下所示:

length(grl)
## [1] 2
elementNROWS(grl)
## [1] 2 3
grl[[1]]
## GRanges object with 2 ranges and 0 metadata columns:
##       seqnames    ranges strand
##          <Rle> <IRanges>  <Rle>
##   [1]     chrZ  [ 5, 35]      +
##   [2]     chrZ  [10, 45]      +
##   -------
##   seqinfo: 1 sequence from hg19 genome

width函数会返回一个 integerList。如果使用sum,我们会得到列表中每个GRanges对象的宽度向量,如下所示:

width(grl)
## IntegerList of length 2
## [[1]] 31 36
## [[2]] 41 41 41
sum(width(grl))
## [1]  67 123

我们可以像以前那样添加元数据(metadata),现在每个GRange对象都有一行元数据。当我们输出GRangesList时它们并不业显示出来,但我们可以通过 mcols 进行访问,如下所示:

mcols(grl)$value <- c(5,7)
grl
## GRangesList object of length 2:
## [[1]] 
## GRanges object with 2 ranges and 0 metadata columns:
##       seqnames    ranges strand
##          <Rle> <IRanges>  <Rle>
##   [1]     chrZ  [ 5, 35]      +
##   [2]     chrZ  [10, 45]      +
## 
## [[2]] 
## GRanges object with 3 ranges and 0 metadata columns:
##       seqnames   ranges strand
##   [1]     chrZ [11, 51]      *
##   [2]     chrZ [12, 52]      *
##   [3]     chrZ [13, 53]      *
## 
## -------
## seqinfo: 1 sequence from hg19 genome
mcols(grl)
## DataFrame with 2 rows and 1 column
##       value
##   <numeric>
## 1         5
## 2         7

findOverlaps与%over%

现在我们来看两个比较GRanges对象的常用方法,首先我们要创建两组范围如下所示:

(gr1 <- GRanges("chrZ",IRanges(c(1,11,21,31,41),width=5),strand="*"))
## GRanges object with 5 ranges and 0 metadata columns:
##       seqnames    ranges strand
##          <Rle> <IRanges>  <Rle>
##   [1]     chrZ  [ 1,  5]      *
##   [2]     chrZ  [11, 15]      *
##   [3]     chrZ  [21, 25]      *
##   [4]     chrZ  [31, 35]      *
##   [5]     chrZ  [41, 45]      *
##   -------
##   seqinfo: 1 sequence from an unspecified genome; no seqlengths
(gr2 <- GRanges("chrZ",IRanges(c(19,33),c(38,35)),strand="*"))
## GRanges object with 2 ranges and 0 metadata columns:
##       seqnames    ranges strand
##          <Rle> <IRanges>  <Rle>
##   [1]     chrZ  [19, 38]      *
##   [2]     chrZ  [33, 35]      *
##   -------
##   seqinfo: 1 sequence from an unspecified genome; no seqlengths

findOverlaps 会返回一个 Hits 对象,这个对象含有关于检索范围的信息(第一个参数),这个范围与主题(第二个参数)有哪些地方重叠。还有许多参数用于指定计算哪种类型的重叠,如下所示:

fo <- findOverlaps(gr1, gr2)
fo
## Hits object with 3 hits and 0 metadata columns:
##       queryHits subjectHits
##       <integer>   <integer>
##   [1]         3           1
##   [2]         4           1
##   [3]         4           2
##   -------
##   queryLength: 5 / subjectLength: 2
queryHits(fo)
## [1] 3 4 4
subjectHits(fo)
## [1] 1 1 2

得到重叠信息的另外一种方式就是使用 %over% ,它返回一个逻辑向量,这个向量表示了第一个参数中的范围与第二个参数中任何范围重叠的信息,如下所示:

gr1 %over% gr2
## [1] FALSE FALSE  TRUE  TRUE FALSE
gr1[gr1 %over% gr2]
## GRanges object with 2 ranges and 0 metadata columns:
##       seqnames    ranges strand
##          <Rle> <IRanges>  <Rle>
##   [1]     chrZ  [21, 25]      *
##   [2]     chrZ  [31, 35]      *
##   -------
##   seqinfo: 1 sequence from an unspecified genome; no seqlengths

需要注意的是,这两种操作方式都是链特异性的,虽然 findOverlaps 有一个 ignore.strand 选择参数,如下所示:

gr1 <- GRanges("chrZ",IRanges(1,10),strand="+")
gr2 <- GRanges("chrZ",IRanges(1,10),strand="-")
gr1 %over% gr2
## [1] FALSE

Rle 和Views

最后,我们来简单了解一下由IRanges定义的两个相关类,即Rle类和Views类。Rle全称为run-length encoding,它表示的是重复数据的压缩工,用于代替类似于[1, 1, 1, 1]这样的储存。

我们只用储存数据1,以及重复次数4即可。数据越重复,使用Rle对象的压缩效果就越明显。

我们使用 str 来查看 Rle的内部结构,用于显示它的储存数据和重复次数,如下所示:

(r <- Rle(c(1,1,1,0,0,-2,-2,-2,rep(-1,20))))
## numeric-Rle of length 28 with 4 runs
##   Lengths:  3  2  3 20
##   Values :  1  0 -2 -1
str(r)
## Formal class 'Rle' [package "S4Vectors"] with 4 slots
##   ..@ values         : num [1:4] 1 0 -2 -1
##   ..@ lengths        : int [1:4] 3 2 3 20
##   ..@ elementMetadata: NULL
##   ..@ metadata       : list()
as.numeric(r)
##  [1]  1  1  1  0  0 -2 -2 -2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
## [24] -1 -1 -1 -1 -1

Views对象可以被为一个“窗口”用于查看一个序列信息,如下所示:

A Views object can be thought of as “windows” looking into a sequence.

(v <- Views(r, start=c(4,2), end=c(7,6)))
## Views on a 28-length Rle subject
## 
## views:
##     start end width
## [1]     4   7     4 [ 0  0 -2 -2]
## [2]     2   6     5 [ 1  1  0  0 -2]

需要注意的是,Veiws对象的内部结构只是原始对象,以及指定窗口的IRangs。使用Views的最好好处就是,当原始对象没有储存在内存中时,在这种情况下,View对象就是一个轻量级的类,它能帮助我们引用子序列,而不必将整个序列都加载到内存中,如下所示:

str(v)
## Formal class 'RleViews' [package "IRanges"] with 5 slots
##   ..@ subject        :Formal class 'Rle' [package "S4Vectors"] with 4 slots
##   .. .. ..@ values         : num [1:4] 1 0 -2 -1
##   .. .. ..@ lengths        : int [1:4] 3 2 3 20
##   .. .. ..@ elementMetadata: NULL
##   .. .. ..@ metadata       : list()
##   ..@ ranges         :Formal class 'IRanges' [package "IRanges"] with 6 slots
##   .. .. ..@ start          : int [1:2] 4 2
##   .. .. ..@ width          : int [1:2] 4 5
##   .. .. ..@ NAMES          : NULL
##   .. .. ..@ elementType    : chr "integer"
##   .. .. ..@ elementMetadata: NULL
##   .. .. ..@ metadata       : list()
##   ..@ elementType    : chr "ANY"
##   ..@ elementMetadata: NULL
##   ..@ metadata       : list()

基因组元件的应用:链特异性操作

在这一部分,我们使用一个小型的范围来说明一下基因的范围内(intra-range)操作,包括reduce, disjoin与gaps。我们添加链和seqname信息,并显示如想调整大小和侧翼(flank)用于识别TSS和启动子区域,如下所示:

一组简单的范围

ir <- IRanges(c(3, 8, 14, 15, 19, 34, 40),
  width = c(12, 6, 6, 15, 6, 2, 7))

现在我们使用图片形式查看一下ir,以及内部范围(intra-range)操作,如下所示:

par(mfrow=c(4,1), mar=c(4,2,2,2))
plotRanges(ir, xlim=c(0,60))
plotRanges(reduce(ir), xlim=c(0,60))
plotRanges(disjoin(ir), xlim=c(0,60))
plotRanges(gaps(ir), xlim=c(0,60))
plot of chunk lkir

注:plotRange()函数似乎不在这个包中,网上找到了它的原代码,如下所示:

plotRanges <- function(x, xlim = x, main = deparse(substitute(x)),
                       col = "black", sep = 0.5, ...)
{
  height <- 1
  if (is(xlim, "Ranges"))
    xlim <- c(min(start(xlim)), max(end(xlim)))
  bins <- disjointBins(IRanges(start(x), end(x) + 1))
  plot.new()
  plot.window(xlim, c(0, max(bins)*(height + sep)))
  ybottom <- bins * (sep + height) - height
  rect(start(x)-0.5, ybottom, end(x)+0.5, ybottom + height, col = col, ...)
  title(main)
  axis(1)
}

reduce(x)函数生成一组不重叠的范围,它覆盖了x中的所有位点。这种操作用于生了你许多转录本的基因模式的复杂性,其中我们可能只想要转录出已知区间的地址,不考虑transcript of residence。

disjoin(x)生成一组覆盖x的所有位置的范围,使得分离输出中的任何范围都不会与x中的任何间隔的端点重叠。这为我们提供了连续间隔最大可能的集合,这些连续间隔在原始间隔集中具有端点的地方被分割开。

gaps(x)产生一组覆盖[start(X),end(X)]中未被x中任何范围覆盖的位置的范围。它能给出编码序列位置和外显子间隔,这可用于枚举内含子。

GRanges的扩展

现在我们添加上染色体与链信息,如下所示:

library(GenomicRanges)
gir = GRanges(seqnames="chr1", ir, strand=c(rep("+", 4), rep("-",3)))

让我们假设间隔代表基因。下图说明了转录起始位点(绿色)、上游启动子区域(紫色)、下游启动子区域(棕色)的位置,如下所示:

par(mfrow=c(4,1), mar=c(4,2,2,2))
plotGRanges(gir, xlim=c(0,60))
# 
plotGRanges(resize(gir,1), xlim=c(0,60),col="green")
plotGRanges(flank(gir,3), xlim=c(0,60), col="purple")
plotGRanges(flank(gir,2,start=FALSE), xlim=c(0,60), col="brown")
plot of chunk dopr

注:plotGRanges的源代码如下所示:

plotGRanges = function (x, xlim = x, col = "black", sep = 0.5, xlimits = c(0, 
    60), ...) 
{
    main = deparse(substitute(x))
    ch = as.character(seqnames(x)[1])
    x = ranges(x)
    height <- 1
    if (is(xlim, "Ranges")) 
        xlim <- c(min(start(xlim)), max(end(xlim)))
    bins <- disjointBins(IRanges(start(x), end(x) + 1))
    plot.new()
    plot.window(xlim = xlimits, c(0, max(bins) * (height + sep)))
    ybottom <- bins * (sep + height) - height
    rect(start(x) - 0.5, ybottom, end(x) + 0.5, ybottom + height, 
        col = col, ...)
    title(main, xlab = ch)
    axis(1)
}

请注意,我们不需要采取特殊步骤来处理链中的差异

甲基化微阵列数据的可视化

在我们讨论 SummarizedExperiment applications时,我们输入了由Illumina 450k甲基化微阵列生成的数据。

在这一部分中,我们将介绍如何使用GenomicRanges和Gviz来研究一下在基因水平注释下的甲基化模型。这个思路非常简单:只需从所有样本中提取M值(甲基化与总DNA 比值的基因座特定的估计的log转换),并在选定基因的基因模型中绘制出来,如下所示:

我们回顾一下数据是如何获取和导入的:

library(ArrayExpress)
if (!file.exists("E-MTAB-5797.sdrf.txt")) nano = getAE("E-MTAB-5797")
library(minfi)
pref = unique(substr(dir(patt="idat"),1,17)) # find the prefix strings
raw = read.metharray(pref)
glioMeth = preprocessQuantile(raw) # generate SummarizedExperiment
## [preprocessQuantile] Mapping to genome.
## [preprocessQuantile] Fixing outliers.
## [preprocessQuantile] Quantile normalizing.

这些步骤需要网联,并且需要花几分钟。

一旦我们的会话中有 glioMeth ,需要将以下代码添加到会话中。我们将会介绍它是如何工作的。

MbyGene = function(mset, symbol="TP53", rad=5000) {
# phase 1: annotated GRanges for the gene
 require(erma)
 require(Gviz)
 gmod = suppressMessages(genemodel(symbol))     # erma utility
 gseq = as.character(seqnames(gmod)[1])
 gmod$transcript = symbol
# phase 2: filter down to the region of interest
 mlim = mset[which(seqnames(mset)==gseq),] # restrict to chromosome
 # now focus the methylation data to vicinity of gene
 d1 = subsetByOverlaps(GRanges(rowRanges(mlim),,, getM(mlim)), 
         range(gmod)+rad)
# phase 3: use Gviz
 plotTracks(list(DataTrack(d1), 
              GeneRegionTrack(gmod, 
               transcriptAnnotation="transcript", name=gseq), 
              GenomeAxisTrack(name=gseq, showTitle=TRUE)))
}

代码表明了三个阶段:获取基因区域,并添加转录本(transcript)注释用于绘制所有外显子的结合;将GenomicRatioSet(继承自

对代码的注释表明了三个阶段:获取基因区并添加用于所有外显子联合的信息性绘图的转录注释;将GenomicRatioSet(继承自RangedSummarizedExperiment)缩小到感兴趣的间隔,这个间隔是由基因模式和rad参数确定;使用Gviz来构建可用于绘图的对象,并绘制出来。

Gviz的详细信息在该包的文档中。现在我们绘制出以基因为中心的图形,如下所示:

MbyGene(glioMeth, symbol="TERT")
image

从上图中我们可以发现这些信息:

  • 基因组背景(以兆(megabase)为单位的染色体和区域)。
  • 感兴趣的基因在单行中的结构,它们表示了表达间隔的联合。
  • 450k针近的位置(蓝色数据点的x坐标)。
  • 甲基化估计中的样本间变异。
  • 所选基因组区域的甲基化变异。

在6x模块中,我们将学习如何使用额外的软件包来创建这种类型的交互式展示,允许我们选择基因并随意放大感兴趣的区域。

脚注

更多的信息可以查看 GenomicRanges 包,以及查阅PLOS Comp Bio上的文献,它是GenomicRanges的作者写的:

http://www.ploscompbiol.org/article/info%3Adoi%2F10.1371%2Fjournal.pcbi.1003118

使用vignettes也能查看这个包的众多功能文档,如下所示:

browseVignettes("GenomicRanges")

或者是使用help函数:

help(package="GenomicRanges", help_type="html")

对于Bed Tools的用户来说,HelloRanges包对于在BEd和GRanges概念框架之间转换概念非常有用。

参考资料

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

推荐阅读更多精彩内容