我有一组不同id的区间。例如:
df <- data.frame(id=c(rep("a",4),rep("b",2),rep("c",3)), start=c(100,250,400,600,150,610,275,600,700), end=c(200,300,550,650,275,640,325,675,725))
每个id的间隔不重叠,但不同id的间隔可能重叠,如下图所示:
plot(range(df[,c(2,3)]),c(1,nrow(df)),type="n",xlab="",ylab="",yaxt="n")
for ( ii in 1:nrow(df) ) lines(c(df[ii,2],df[ii,3]),rep(nrow(df)-ii+1,2),col=as.numeric(df$id[ii]),lwd=2)
legend("bottomleft",lwd=2,col=seq_along(levels(df$id)),legend=levels(df$id))
我需要的是两个函数:1.一个函数,它将取这些间隔的并集。对于上面的例子,它将返回以下数据。帧:
union.df <- data.frame(id=rep("a,b,c",4), start=c(100,400,600,700), end=c(325,550,675,725))
1.一个函数,它将这些区间相交,只有当所有的id重叠时才保留一个范围。对于上面的例子,它将返回以下数据。frame:intersection.df <- data.frame(id="a,b,c", start=610, end=640)
5条答案
按热度按时间kx5bkwkv1#
interval包解决了问题的并集部分:
对于相交部分,取决于如何定义间隔:
rjee0c152#
这有点尴尬,但我们的想法是将数据展开成一系列的开始和结束事件,然后跟踪一次有多少个区间是打开的,这是假设每组没有任何重叠的区间。
9w11ddsr3#
对于交集,我将从计算每个区间的区间数开始(在此代码中,区间的起点标记为
ord.dirs$x
,区间数为ord.dirs$z
):现在,您只需要获取区间数正确的范围(本例中为3):
同样,您可以使用
ord.dirs
获取集合的并集:wlwcrazw4#
GenomicRanges包提供了一些交叉和重叠函数:
创建一个具有相同序列名的Grange对象(这很重要)
现在您也可以使用Gviz包绘制范围。
在间隔折叠的地方,通过reduce完成联合
通过findoverlaps完成交集。2然后,通过与3个范围重叠的范围过滤。
aurhwmvo5#
使用ivs和
iv_groups()
进行自并,并使用reduce()
div_set_intersect()
(在ivs 0.2.0中,或在0.1.0中,iv_intersect()
)进行交集: