R中的常见基因组间隔

时间:2014-04-15 12:53:08

标签: r overlap overlapping genome

我想推断不同样本之间的共享基因组间隔。

我的意见:

sample    chr start end
NE001      1   100  200
NE001      2   100  200
NE002      1   50   150
NE002      2   50   150
NE003      2   250  300

我的预期输出:

chr start end  freq
1    100  150   2
2    100  150   2

" freq"是有多少样本有助于推断共享区域。在上面的示例中,freq = 2(NE001和NE002)。

干杯!

3 个答案:

答案 0 :(得分:6)

如果您的数据位于data.frame中(请参见下文),请使用Bioconductor GenomicRanges包创建一个GRanges实例,同时保留非范围列

library(GenomicRanges)
gr <- makeGRangesFromDataFrame(df, TRUE)

由数据表示的离散范围由disjoin函数给出,并且不相交的范围(&#39;查询&#39;)与您的原始(&#39;主题&#39;是

d <- disjoin(gr)
olaps <- findOverlaps(d, gr)

使用相应的查询拆分与每个重叠主题相关联的样本信息,并将其与不相交的GRanges关联为

mcols(d) <- splitAsList(gr$sample[subjectHits(olaps)], queryHits(olaps))

导致例如

> d[elementLengths(d$value) > 1]
GRanges with 2 ranges and 1 metadata column:
      seqnames     ranges strand |           value
         <Rle>  <IRanges>  <Rle> | <CharacterList>
  [1]        1 [100, 150]      * |     NE001,NE002
  [2]        2 [100, 150]      * |     NE001,NE002
  ---
  seqlengths:
    1  2
   NA NA

以下是我输入数据的方式:

txt <- "sample    chr start end
NE001      1   100  200
NE001      2   100  200
NE002      1   50   150
NE002      2   50   150
NE003      2   250  300"
df <- read.table(textConnection(txt), header=TRUE, stringsAsFactors=FALSE)

答案 1 :(得分:3)

鉴于这个问题背后的背景,我怀疑你是否值得学习Bioconductor的GenomicRanges包。

library(GenomicRanges)
gr <- GRanges(seqnames=df$chr, ranges=IRanges(start=df$start, end=df$end))
ov <- findOverlaps(gr,gr, type="any")
ov <- ov[queryHits(ov) != subjectHits(ov)]
between <- pintersect(gr[subjectHits(ov)], gr[queryHits(ov)])

方法是:找到所有自我重叠,删除与自身比较间隔的平凡值(第4行),然后找到每对剩余间隔之间的交集。然后,您可以根据需要将结果制成表格。

答案 2 :(得分:1)

这肯定很长(并且在给定expand.grid.df的情况下对大型数据框架效率可能很低,但是,我希望它给你一个起点。作为一个警告,我没有基因组学背景(我是“肯定会来的。所以不知道这方面的常见方法。当然这是最好的方法。我只是觉得尝试解决方案会很有趣。

s<-"sample    chr start end
NE001      1   100  200
NE001      2   100  200
NE002      1   50   150
NE002      2   50   150
NE003      2   250  300"

dat<-read.table(text=s, header=T)

library(plyr)
between<-function(x,y,z) x<=y & y<=z
dat$id<-seq_along(dat[,1])
expand.grid.df <- function(...) Reduce(function(...) merge(..., by=NULL), list(...))
expdat<-ddply(dat, .(chr), function(x) expand.grid.df(x,x))
expdat<-subset(expdat, id.x!=id.y)
expdat$betweenL<-with(expdat, between(start.y, start.x, end.y))
expdat$betweenR<-with(expdat, between(start.x, start.y, end.x))
expdat<-subset(expdat, betweenL | betweenR)
expdat$commonstart<-with(expdat,ifelse(betweenL,start.x,start.y))
expdat$commonend<-with(expdat, ifelse(betweenL, end.y, end.x))
res<-ddply(expdat, .(chr, commonstart, commonend),summarize, freq=length(sample.x))
> res
  chr commonstart commonend freq
1   1         100       150    2
2   2         100       150    2