2015-05-06 27 views
6

Farklı kimlikler için bir grup aralık var. Örneğin: Her idBirimler ve aralıkların kesişimi

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)) 

aralıklar örtüşmeyen ancak farklı kimlikleri aralıkları çakışabilir. İşte bir örneği verilmiştir: 1. Bu aralıklardan birliği alacak bir fonksiyon:

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)) 

intervals Ne aradığım iki işleve içindir. Yukarıdaki örnekte , bu data.frame döndürür:

union.df <- data.frame(id=rep("a,b,c",4), start=c(100,400,600,700), end=c(325,550,675,725)) 
  1. tüm kimlikleri bu aralık için üst üste keşke bir dizi tutarak bu aralıkları kesişir edecek bir işlevi . Ben (her mesafeden başlangıcını içinde bulunduğunuz aralıklarla sayısını sayarak başlayacaktı, kavşak için

intersection.df <- data.frame(id="a,b,c", start=610, end=640)

+0

Sendikası'nın çalışmaz 'denemek kesişir ve birliği – Henk

+1

' intersect' ve? - onlar aralıkları, * * ayrık kümeler üzerinde çalışmaz. –

+2

"Bu aralıkların birleşimi ve kesişme noktalarına" nasıl sahip olduğunuzu açıklayabilir misiniz? Bu, kimliğinizle nasıl oynar? Bir aralıkta birden fazla örtüşmeyen aralık bulunduğuna göre, tüm aralıkların kesişimi boş olacaktır. Aynı şekilde, sendikanın nereden geldiğini anlamıyorum. –

cevap

2

. Ardından, bir seferde kaç aralığın açık olduğunu izlersiniz. Bu, her grubun herhangi bir örtüşen aralığı olmadığını varsayar.

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)) 


sets<-function(start, end, group, overlap=length(unique(group))) { 
    dd<-rbind(data.frame(pos=start, event=1), data.frame(pos=end, event=-1)) 
    dd<-aggregate(event~pos, dd, sum) 
    dd<-dd[order(dd$pos),] 
    dd$open <- cumsum(dd$event) 
    r<-rle(dd$open>=overlap) 
    ex<-cumsum(r$lengths-1 + rep(1, length(r$lengths))) 
    sx<-ex-r$lengths+1 
    cbind(dd$pos[sx[r$values]],dd$pos[ex[r$values]+1]) 

} 

#union 
with(df, sets(start, end, id,1)) 
#  [,1] [,2] 
# [1,] 100 325 
# [2,] 400 550 
# [3,] 600 675 
# [4,] 700 725 

#overlap 
with(df, sets(start, end, id,3)) 
#  [,1] [,2] 
# [1,] 610 640 
1

: Yukarıdaki Örneğin , bu data.frame dönecektir aralık) Bu kodda ord.dirs$x ile etiketlenmiş ve aralıkta aralık sayısı ord.dirs$z bulunmaktadır:

dirs <- data.frame(x=c(df$start, df$end), y=rep(c(1, -1), each=nrow(df))) 
ord.dirs <- dirs[order(dirs$x),] 
ord.dirs$z <- cumsum(ord.dirs$y) 
ord.dirs <- ord.dirs[!duplicated(ord.dirs$x, fromLast=T),] 
ord.dirs 
#  x y z 
# 1 100 1 1 
# 5 150 1 2 
# 10 200 -1 1 
# 2 250 1 2 
# 14 275 -1 2 
# 11 300 -1 1 
# 16 325 -1 0 
# 3 400 1 1 
# 12 550 -1 0 
# 8 600 1 2 
# 6 610 1 3 
# 15 640 -1 2 
# 13 650 -1 1 
# 17 675 -1 0 
# 9 700 1 1 
# 18 725 -1 0 

Şimdi sadece Bu durumda aralıklarla doğru sayıda (3 var aralıkları) kapmak gerekir:

pos.all <- which(ord.dirs$z == length(unique(df$id))) 
data.frame(start=ord.dirs$x[pos.all], end=ord.dirs$x[pos.all+1]) 
# start end 
# 1 610 640 
Sen benzer setleri birliği kapmak için ord.dirs kullanabilirsiniz

: Bu biraz garip, ama fikir açılış ve kapanış bir dizi etkinlik verileri göz önüne sermek olduğunu

zero.pos <- which(ord.dirs$z == 0) 
data.frame(start=c(ord.dirs$x[1], ord.dirs$x[head(zero.pos, -1)+1]), 
      end=ord.dirs$x[zero.pos]) 
# start end 
# 1 100 325 
# 2 400 550 
# 3 600 675 
# 4 700 725 
4

aralıkları paket söz birliği kısmını çözer:

require(intervals) 
idf <- Intervals(df[,2:3]) 
as.data.frame(interval_union(idf)) 

Ve kesiştiği kısmı için, aralıkları tanımlanmıştır şekline bağlı olarak:

idl <- lapply(unique(df$id),function(x){var <- as(Intervals(df[df$id==x,2:3]),"Intervals_full");closed(var)[,1]<- FALSE;return(var)}) 
idt <- idl[[1]] 
for(i in idl)idt <- interval_intersection(idt,i) 
res <- as.data.frame(idt) 
res 
    V1 V2 
1 610 640 
+0

Sadece 2. bölümle başa çıkmak için cevabı düzenledim. Biri, varsayılan kapalı aralıklarla gidebilir ve aynı girişlere sahip olan sonuçtaki satırları silebilir (bu durumda 275 275 olur). Tüm aralıkların açık veya kapalı olmasına bağlı olarak değişir. – Nightwriter

1

GenomicRanges paketi sunmak bazı kesiştiği ve örtüşme fonksiyonlar:

library(GenomicRanges) 
source("http://bioconductor.org/biocLite.R") 
biocLite("Gviz")  
library(Gviz) 

Şimdi de, Gviz paketiyle aralıkları çizebilirsiniz (bu önemli)

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)) 
gr <- GRanges(seqnames = rep(1,nrow(df)),IRanges(start = df$start,end =  df$end)) 

eşit seqnames ile Grange nesnesi yapmak.

d0 <- GenomeAxisTrack() 
d1 <- AnnotationTrack(gr,group = df$id,fill=df$id) 
plotTracks(c(d0,d1)) 

sendika aralıkları

as.data.frame(reduce(gr))[,2:3] 

kesiştiği findoverlaps yoluyla yapılır daraltılır azaltmak nereye aracılığıyla yapılır. Daha sonra 3 aralıkla çakışan aralıklar ile filtrelenir. ?

OL <- as.data.frame(findOverlaps(gr,type="within")) 
table(OL[,1]) 

df[as.numeric(names(which(table(OL[,1])==3))),]