在R中查找范围重叠

geo*_*try 13 r bioinformatics

我有两个data.frames,每个都有三列:chrom,start和stop,让我们称它们为rangesA和rangesB.对于每行rangeA,我想找到rangeB中哪一行(如果有的话)完全包含rangesA行 - 我的意思是rangesAChrom == rangesBChrom, rangesAStart >= rangesBStart and rangesAStop <= rangesBStop.

现在我正在做以下,我不太喜欢.请注意,由于其他原因,我正在循环遍历rangeA的行,但这些原因都不是什么大问题,它最终会让这些特定解决方案更具可读性.

rangesA:

chrom   start   stop
 5       100     105
 1       200     250
 9       275     300
Run Code Online (Sandbox Code Playgroud)

rangesB:

chrom    start    stop
  1       200      265
  5       99       106
  9       275      290
Run Code Online (Sandbox Code Playgroud)

对于范围A中的每一行:

matches <- which((rangesB[,'chrom']  == rangesA[row,'chrom']) &&
                 (rangesB[,'start'] <= rangesA[row, 'start']) &&
                 (rangesB[,'stop'] >= rangesA[row, 'stop']))
Run Code Online (Sandbox Code Playgroud)

我认为必须有一个更好的(并且更好,我的意思是比大范围A和rangeB的大型实例更快)这样做的方式比循环这个结构.有任何想法吗?

Aar*_*ham 20

使用Bioconductor提供的IRanges/GenomicRanges包装,用于处理这些确切的问题(并大规模扩展)

source("http://bioconductor.org/biocLite.R")
biocLite("IRanges")
Run Code Online (Sandbox Code Playgroud)

在不同的染色体上有一些适用于范围的容器,一个是RangesList

library(IRanges)
rangesA <- split(IRanges(rangesA$start, rangesA$stop), rangesA$chrom)
rangesB <- split(IRanges(rangesB$start, rangesB$stop), rangesB$chrom)
#which rangesB wholly contain at least one rangesA?
ov <- countOverlaps(rangesB, rangesA, type="within")>0
Run Code Online (Sandbox Code Playgroud)


Jos*_*ich 13

如果您可以先合并这两个对象,这将更容易/更快.

ranges <- merge(rangesA,rangesB,by="chrom",suffixes=c("A","B"))
ranges[with(ranges, startB <= startA & stopB >= stopA),]
#  chrom startA stopA startB stopB
#1     1    200   250    200   265
#2     5    100   105     99   106
Run Code Online (Sandbox Code Playgroud)


Aru*_*run 12

data.table软件包具有一个foverlaps()能够在v1.9.4之后合并区间范围的功能:

require(data.table)
setDT(rangesA)
setDT(rangesB)

setkey(rangesB)
foverlaps(rangesA, rangesB, type="within", nomatch=0L)
#    chrom start stop i.start i.stop
# 1:     5    99  106     100    105
# 2:     1   200  265     200    250
Run Code Online (Sandbox Code Playgroud)
  • setDT() 通过引用将data.frame转换为data.table

  • setkey() 通过提供的列对data.table进行排序(在本例中为所有列,因为我们没有提供任何列),并将这些列标记为已排序,我们稍后将使用它们来执行连接.

  • foverlaps()重叠连接是否有效.有关详细说明和与其他方法的比较,请参阅此答案.


mik*_*ope 5

RangesA 和 RangesB 显然是 BED 语法,这可以在 R 之外的命令行中使用 BEDtools 完成,非常快速且灵活,并具有十几个其他选项来处理基因组间隔。然后将结果再次放入 R 中。

https://code.google.com/p/bedtools/


Joe*_*Joe 5

我添加dplyr解决方案。

library(dplyr)
inner_join(rangesA, rangesB, by="chrom") %>% 
  filter(start.y < start.x | stop.y > stop.x)
Run Code Online (Sandbox Code Playgroud)

输出:

  chrom start.x stop.x start.y stop.y
1     5     100    105      99    106
2     1     200    250     200    265
Run Code Online (Sandbox Code Playgroud)