stacking (partially or completely overlapping) GRanges/IRanges
1
2
Entering edit mode
Johannes Rainer ★ 2.1k
@johannes-rainer-6987
Last seen 7 weeks ago
Italy

dear all!

I wrote a function to stack IRanges or GRanges but it is helplessly slow when it comes to "real life" data (i.e. reads from RNA-seq). I know I could use the coverage function, but I did really want to get the individual ranges stacked in different lines of non-overlapping ranges. The code and an example are shown below.

I would be grateful if someone knows a more efficient way to do this, but I'm afraid I'll have to use C code in the end...

thanks in advance!

 

require( IRanges )

stackRanges <- function( x ){
    x <- x[ order( start( x ) ) ]
    Overlaps <- as.matrix( findOverlaps( x, x ) )
    Index <- list()
    Which.ranges <- 1:length( x )
    ## repeatedly go through the ranges and determine those not directly
    ## overlapping, these are put into the "first line" and the   
    ##evaluation is repeated for all remaining ranges
    repeat{
        Which.ranges <- Which.ranges[ !( Which.ranges %in% unlist( Index ) ) ]
        if( length( Which.ranges )==0 ){
            ## nothing left...
            break
        }
        CurrentLine <- c()
        for( i in Which.ranges ){
            ## check if any subject for query i is smaller than i
            ## if yes: don't add, otherwise, add
            if( !( any( Overlaps[ Overlaps[ , 1 ]==i, 2 ] %in% CurrentLine ) ) )
                CurrentLine <- c( CurrentLine, i )
        }
        Index <- c( Index, list( CurrentLine ) )
    }
    res <- lapply( Index, function( z ){
        return( x[ z ] )
    } )
    return( res )
}

plotRangesList <- function( x, height=1, ybottom=0 ){
    X.l <- min( unlist( lapply( lapply( x, range ), start ) ) )
    X.u <- max( unlist( lapply( lapply( x, range ), end ) ) )+1
    plot( 3, 3, pch=NA, xlim=c( X.l, X.u ), ylim=c( ybottom, ( ybottom+length( x )*height) ) )
    for( i in 1:length( x ) ){
        ybot <- ybottom + ( i-1 ) * height
        rect( xleft=start( x[[ i ]] ), xright=end( x[[ i ]] )+1,
             ybottom=rep( ybot, length( x[[ i ]] ) ),
             ytop=rep( (ybot+height), length( x[[ i ]] ) ), col="grey" )
    }
}

IR2 <- IRanges( start=c( 8, 4, 9, 11, 16, 18, 19, 25 ), end=c( 10, 12, 10, 23, 18, 24, 23, 27 ) )
plotRangesList( stackRanges( IR2 ) )

 

granges iranges rnaseq • 1.2k views
ADD COMMENT
2
Entering edit mode
@martin-morgan-1513
Last seen 4 months ago
United States

Maybe

splitAsList(IR2, disjointBins(IR2))

?

ADD COMMENT
0
Entering edit mode

That's perfect!

In the meantime I've implemented it in C, but your call is faster! thanks!

ADD REPLY
0
Entering edit mode

Could just use `split` instead of `splitAsList`. Also, the OP might benefit from using an existing plotting package like ggbio or Gviz.
 

ADD REPLY

Login before adding your answer.

Traffic: 1245 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6