Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion R/intra-range-methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ setMethod("flank", "GenomicRanges",


### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### promoters() and terminators()
### promoters(), terminators() and expand()
###

### Returns an IRanges **instance**.
Expand Down Expand Up @@ -155,6 +155,41 @@ setMethod("terminators", "GenomicRanges",
site="TES")
)

### Expand ranges in a GRanges object upstream and downstream by specified numbers of bases, taking account of strand.
### Unstranded ranges are treated like they on the "+" strand
.GenomicRanges_expand = function(x, upstream = 0, downstream = 0, trim_out_of_bounds = TRUE) {

# Check that upstream and downstream are vectors of either length 1 or with the same length as x
if(!length(upstream) %in% c(1, length(x))){
stop("upstream should be a vector of length 1 or the length of x")}
if(!length(downstream) %in% c(1, length(x))){
stop("downstream should be a vector of length 1 or the length of x")}

# Check if any regions would have negative widths after adjustment
if(any(width(x) + upstream + downstream < 0)){
stop("Some regions would have a negative width after adjustment. This is not permitted.")
}

# Shift genomic regions upstream either by upstream (strand is + or *) or downstream (strand is -)
x <- GenomicRanges::shift(x,
-ifelse(GenomicRanges::strand(x) == "-", downstream, upstream))

# Expand GRanges so that their width equals their original size plus upstream and downstream
x <- GenomicRanges::resize(x,
width = (GenomicRanges::width(x) + upstream + downstream), fix = "start", ignore.strand = T)

# Remove any out-of-bounds regions and return x
if(trim_out_of_bounds){
x <- GenomicRanges::trim(x)
}
return(x)
}

setMethod("expand", "GenomicRanges",
function(x, upstream=0, downstream=0, trim_out_of_bounds=TRUE)
.GenomicRanges_expand(x, upstream, downstream, trim_out_of_bounds)
)


### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### reflect()
Expand Down
28 changes: 28 additions & 0 deletions inst/unitTests/test_intra-range-methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,34 @@ test_promoters_GenomicRanges <- function()
checkIdentical(seqinfo(gr), seqinfo(current))
}

test_expand_GenomicRanges <- function()
{

# Test zero-length GRanges
gr0 <- GRanges(tx_id=integer(0))
checkIdentical(expand(gr0, 5, 2), gr0)

# Test that giving 0 for upstream and downstream returns original GRanges
gr <- setNames(GRanges(c("chr1:100-200:+", "chr1:100-200:*", "chr1:100-200:-"), tx_id=seq_len(3)), letters[1:3])
checkIdentical(expand(gr, 0, 0), gr)

# Test that expanding works in strand-wise manner
target <- setNames(GRanges(c("chr1:0-250:+", "chr1:0-250:*", "chr1:50-300:-"), tx_id=seq_len(3)), letters[1:3])
checkIdentical(expand(gr, 100, 50), target)

# Test that regions are contracted when negative values given to upstream or downstream
target <- setNames(GRanges(c("chr1:150-175:+", "chr1:150-175:*", "chr1:125-150:-"), tx_id=seq_len(3)), letters[1:3])
checkIdentical(expand(gr, -50, -25), target)

# Test providing vectors with length > 1 for upstream and downstream
target <- setNames(GRanges(c("chr1:75-250:+", "chr1:0-225:*", "chr1:0-250:-"), tx_id=seq_len(3)), letters[1:3])
checkIdentical(expand(gr, c(25, 100, 50), c(50, 25, 100)), target)

# Test that an error is thrown when upstream or downstream ahve length > 1, but not equal to the length of gr
testthat::expect_error(expand(gr, c(25, 100), c(50, 25, 100)))
testthat::expect_error(expand(gr, c(25, 100, 50), c(25, 100)))
}

test_restrict_GenomicRanges <- function()
{
gr <- make_test_GRanges()
Expand Down