plyranges
plyranges copied to clipboard
flip_strand() function?
Hello,
I was wondering if it would be useful to add a flip_strand() function to switch strand from "+" to "-" and viceversa, leaving "*" if unstranded. I am not aware of a function that does this in GenomicRanges.
I adapted the flip_strand_info() function from TranscriptomeReconstructoR. It does not cover the "*" case.
Probably there is a more elegant/efficient way of doing this:
#' Flip strand orientation of a GenomicRanges object
#'
#' @param gr \code{GRanges} or \code{GRangesList} object
#' @return Object of the same class as input with positive and negative strands flipped
#' @export
flip_strand <- function(gr) {
stopifnot(class(gr) == "GRanges" || BiocGenerics::grepl("GRangesList", class(gr)))
if (class(gr) == "GRanges") {
BiocGenerics::strand(gr) <- ifelse(BiocGenerics::strand(gr) == "*", "*",
ifelse(BiocGenerics::strand(gr) == "+", "-", "+"))
} else {
unl <- BiocGenerics::unlist(gr, use.names = FALSE)
BiocGenerics::strand(unl) <- ifelse(BiocGenerics::strand(unl) == "*", "*",
ifelse(BiocGenerics::strand(unl) == "+", "-", "+"))
gr <- BiocGenerics::relist(unl, gr)
}
return(gr)
}
This sounds like a useful feature. I've certainly hand-rolled this a few times.
Two use-cases come to mind for me:
- Wanting to flip an entire granges object, like
flip_strand(my_features)
- Wanting to flip the strand of a feature inside of a
mutate
conditional on some other element like:
my_features %>%
mutate(strand = ifelse(some_condition, flip_strand(strand), strand))
I think 1. is solved by an approach like you posted above (for plyranges we'd want to change the implementation to use method dispatch).
I am not certain, but I think 2. might be a bit more fiddly because I think it needs some plyranges::set_strand()
stuff in order to actually change the value in a mutate, but I might be wrong. If that's the case it could be that flip_strand
could work by taking a conditional function argument:
# Flips everything
my_features %>%
flip_strand()
# Flip only features with a score > 10
my_features %>%
flip_strand(~ .x$score > 10)