我想知道定义给定范围集未涵盖的所有范围的最佳方法是什么。例如,如果我有一组已知坐标的基因:
dtGenes <- fread(
"id,start,end
1,1000,1300
2,1200,1500
3,1600,2600
4,3000,4000
")
让我说我知道染色体的总长度(为简单起见,假设它们都在同一条染色体上)是10000.所以,最后我希望有以下基因间区域列表:
"startR,endR
0,1000
1500,1600
2600,3000
4000,10000
"
Bioconductor的IRange
在这里有用吗?还是有其他好方法可以解决这个问题?
答案 0 :(得分:4)
使用Bioconductor包GenomicRanges,将原始数据转换为GRanges
library(GenomicRanges)
gr <- with(dtGenes, GRanges("chr1", IRanges(start, end, names=id),
seqlengths=c(chr1=10000)))
然后找到基因之间的差距
gaps <- gaps(gr)
GRanges
知道链。您没有在GRanges
构造函数中指定链,因此已为链分配了*
。因此,+, - 和*链上存在“缺口”,而您只对*链上的那些感兴趣
> gaps[strand(gaps) == "*"]
GRanges with 4 ranges and 0 metadata columns:
seqnames ranges strand
<Rle> <IRanges> <Rle>
[1] chr1 [ 1, 999] *
[2] chr1 [1501, 1599] *
[3] chr1 [2601, 2999] *
[4] chr1 [4001, 10000] *
---
seqlengths:
chr1
10000
请注意Bioconductor约定,染色体从1开始,范围已关闭 - start
和end
坐标包含在范围内。在shift
上使用narrow
和gr
可使您的范围与Bioconductor约定一致。 GRanges操作在数百万个范围内都是有效的。
答案 1 :(得分:1)
您可以使用reduce
包
IRanges
首先从左到右依次对x中的范围进行排序,然后进行合并 重叠或相邻的。
library(IRanges)
dat <- read.csv(text="id,start,end
1,1000,1300
2,1200,1500
3,1600,2600
4,3000,4000
")
ir <- IRanges(dat$start,dat$end)
rir <- reduce(ir)
IRanges of length 3
start end width
[1] 1000 1500 501
[2] 1600 2600 1001
[3] 3000 4000 1001