Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flip_strand() function? #100

Open
eggrandio opened this issue Feb 14, 2023 · 1 comment
Open

flip_strand() function? #100

eggrandio opened this issue Feb 14, 2023 · 1 comment

Comments

@eggrandio
Copy link

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)
}
@snystrom
Copy link
Contributor

This sounds like a useful feature. I've certainly hand-rolled this a few times.

Two use-cases come to mind for me:

  1. Wanting to flip an entire granges object, like flip_strand(my_features)
  2. 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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants