13

それぞれ 3 つの列を持つ 2 つの data.frames があります: chrome、start & stop、それらを rangeA と rangeB と呼びましょう。rangeA の各行について、rangeB のどの行 (存在する場合) に rangeA 行が完全に含まれているかを探していますrangesAChrom == rangesBChrom, rangesAStart >= rangesBStart and rangesAStop <= rangesBStop

現在、私は次のことを行っていますが、これはあまり好きではありません。他の理由で rangeA の行をループしていることに注意してください。ただし、これらの理由はどれも大したことではありません。この特定のソリューションを考えると、物事が読みやすくなるだけです。

範囲A:

chrom   start   stop
 5       100     105
 1       200     250
 9       275     300

範囲B:

chrom    start    stop
  1       200      265
  5       99       106
  9       275      290

rangeA の各行について:

matches <- which((rangesB[,'chrom']  == rangesA[row,'chrom']) &&
                 (rangesB[,'start'] <= rangesA[row, 'start']) &&
                 (rangesB[,'stop'] >= rangesA[row, 'stop']))

この構成をループするよりも、これを行うためのより良い方法 (つまり、rangeA と rangeB の大きなインスタンスよりも高速であることを意味します) が必要だと思います。何か案は?

4

6 に答える 6

21

これらの正確な問題に対処するために作成された Bioconductor の IRanges/GenomicRanges パッケージを使用します (そして大規模にスケーリングします)。

source("http://bioconductor.org/biocLite.R")
biocLite("IRanges")

異なる染色体の範囲に適したコンテナがいくつかあります。1 つは 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
于 2010-10-13T00:54:08.020 に答える
14

最初に 2 つのオブジェクトをマージできれば、これははるかに簡単/高速になります。

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
于 2010-10-12T15:45:41.743 に答える
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
  • setDT()参照によって data.frame を data.table に変換します

  • setkey()提供された列 (この場合は何も提供していないため、すべての列) で data.table を並べ替え、それらの列を並べ替え済みとしてマークし、後で結合を実行するために使用します。

  • foverlaps()重複結合を効率的に行います。詳細な説明と他のアプローチとの比較については、この回答を参照してください。

于 2014-12-27T22:49:52.553 に答える
3

解決策を追加しdplyrます。

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

出力:

  chrom start.x stop.x start.y stop.y
1     5     100    105      99    106
2     1     200    250     200    265
于 2016-12-01T16:43:17.997 に答える
2

サンプルデータの場合:

rangesA <- data.frame(
    chrom = c(5, 1, 9),
    start = c(100, 200, 275),
    stop = c(105, 250, 300)
)
rangesB <- data.frame(
    chrom = c(1, 5, 9),
    start = c(200, 99, 275),
    stop = c(265, 106, 290)
)

これはsapply、各列がrangesAの1つの行であり、各行がrangesBの対応する行であるように、でそれを行います。

> sapply(rangesA$stop, '>=', rangesB$start) & sapply(rangesA$start, '<=', rangesB$stop)
      [,1]  [,2]  [,3]
[1,] FALSE  TRUE FALSE
[2,]  TRUE FALSE FALSE
[3,] FALSE FALSE  TRUE
于 2010-10-12T17:53:25.983 に答える