10

「開始」列と「停止」列で示される、交差する範囲を持つ行を折りたたみ、折りたたまれた値を新しい列に記録する方法を見つけようとしています。たとえば、次のデータ フレームがあります。

my.df<- data.frame(chrom=c(1,1,1,1,14,16,16), name=c("a","b","c","d","e","f","g"), start=as.numeric(c(0,70001,70203,70060, 40004, 50000872, 50000872)), stop=as.numeric(c(71200,71200,80001,71051, 42004, 50000890, 51000952)))


chrom name  start   stop
 1    a        0    71200
 1    b    70001    71200
 1    c    70203    80001
 1    d    70060    71051
14    e    40004    42004
16    f 50000872 50000890
16    g 50000872 51000952

そして、重複する範囲を見つけて、「開始」と「停止」の折りたたまれた重複する行と折りたたまれた行の名前でカバーされる最大の範囲を記録しようとしているので、次のようになります。

chrom start   stop      name
 1    70001    80001    a,b,c,d
14    40004    42004    e
16    50000872 51000952 f,g

次のようにIRangesパッケージを使用できると思います:

library(IRanges)
ranges <- split(IRanges(my.df$start, my.df$stop), my.df$chrom)

しかし、折りたたまれた列を取得するのに問題があります。findOvarlaps で試しましたが、これは

ov <- findOverlaps(ranges, ranges, type="any")

しかし、これは正しくないと思います。

どんな助けでも大歓迎です。

4

2 に答える 2

12

IRangesそのような仕事の良い候補です。クロム変数を使用する必要はありません。

ir <- IRanges(my.df$start, my.df$stop)
## I create a new grouping variable Note the use of reduce here(performance issue)
my.df$group2 <- subjectHits(findOverlaps(ir, reduce(ir)))
# chrom name    start     stop group2
# 1     1    a    70001    71200      2
# 2     1    b    70203    80001      2
# 3     1    c    70060    71051      2
# 4    14    d    40004    42004      1
# 5    16    e 50000872 50000890      3
# 6    16    f 50000872 51000952      3

新しい group2 変数は範囲インジケーターです。今使用data.tableすると、データを目的の出力に変換できません。

library(data.table)
DT <- as.data.table(my.df)
DT[, list(start=min(start),stop=max(stop),
         name=list(name),chrom=unique(chrom)),
               by=group2]

# group2    start     stop  name chrom
# 1:      2    70001    80001 a,b,c     1
# 2:      1    40004    42004     d    14
# 3:      3 50000872 51000952   e,f    16

PS: ここで折りたたまれた変数名は文字列ではなく、要素のリストです。これは、たとえば貼り付けを使用して折りたたまれた文字よりも効率的で簡単にアクセスできます。

OPの明確化後にEDITして、chromeでグループ変数を作成します。Iranges コードが chrom グループごとに呼び出されるようになりました。あなたのデータを少し修正して、同じ染色体の間隔のグループを作成します。

my.df<- data.frame(chrom=c(1,1,1,1,14,16,16), 
                   name=c("a","b","c","d","e","f","g"),
                   start=as.numeric(c(0,3000,70203,70060, 40004, 50000872, 50000872)), 
                   stop=as.numeric(c(1,5000,80001,71051, 42004, 50000890, 51000952)))

library(data.table)
DT <- as.data.table(my.df)

## find interval for each chromsom
DT[,group := { 
      ir <-  IRanges(start, stop);
       subjectHits(findOverlaps(ir, reduce(ir)))
      },by=chrom]

## Now I group by group and chrom 
DT[, list(start=min(start),stop=max(stop),name=list(name),chrom=unique(chrom)),
   by=list(group,chrom)]

  group chrom    start     stop name chrom
1:     1     1        0        1    a     1
2:     2     1     3000     5000    b     1
3:     3     1    70060    80001  c,d     1
4:     1    14    40004    42004    e    14
5:     1    16 50000872 51000952  f,g    16
于 2013-06-06T09:19:06.923 に答える