R/promex_feature_plot.R

Defines functions promex_feature_plot

Documented in promex_feature_plot

#' Generate a feature map from MS1FT data
#'
#' @description The feature map visualizes ProMex identified features (Monoiostopic
#'     Masses per Elution (Retention) Time window) colorized by relative abundance.
#'     This map is often used to compare one top-down analyses to another, as features
#'     are assigned to proteins downstream with MSPathFinderT.
#'
#' @param MS1FT An ms1ft object generated by get_ms1ft. Required.
#' @param Proteins Subset down to specific proteins if Ic_Targets file was provided. Default is NULL.
#' @param Interactive A logical to determine whether the plot should be interactive or not. Default is FALSE.
#'
#' @examples
#' \dontrun{
#'
#' # Use the ms1ft object outputted from get_ms1ft
#' promex_feature_plot(MS1FT = MS1FT)
#' promex_feature_plot(MS1FT = MS1FT, Proteins = c("SO_0239"), Interactive = FALSE)
#'
#' }
#' @export
promex_feature_plot <- function(MS1FT,
                                Proteins = NULL,
                                Interactive = FALSE) {


  # Assert that MS1FT is a ms1ft object from get_ms1ft
  if ("ms1ft" %in% class(MS1FT) == FALSE) {
    stop("MS1FT must be a ms1ft object generated by get_ms1ft.")
  }

  # If proteins is not NULL, let the user know if the protein name is in the MS1FT object.
  if (is.null(Proteins) == FALSE) {

    # Only character vectors are allowed
    if (is.character(Proteins) == FALSE) {stop("Proteins must be a vector of characters.")}

    # Ensure that there is at least one matching protein
    if (all(is.na(match(Proteins, unique(MS1FT$ProteinName))))) {

      message("No proteins found from protein list. Skipping the subset by protein step.")
      Proteins <- NULL

    }

  }

  # Assert that Interactive is a single logical
  if (is.logical(Interactive) == FALSE || length(Interactive) > 1) {
    stop("Interactive needs to be a single logical: a TRUE or FALSE.")
  }
  if (is.na(Interactive)) {Interactive <- FALSE}

  ###################
  ## GENERATE PLOT ##
  ###################

  # Pull out ProMex plot dataframe
  ProMexDF <- MS1FT

  # If no protein ID, add empty ID "Protein Not Found"
  if ("ProteinName" %in% colnames(ProMexDF) == FALSE) {
    ProMexDF$ProteinName <- "Protein Not Found"
  }

  # Subset down if Proteins is not NULL
  if (is.null(Proteins) == FALSE) {
    ProMexDF <- ProMexDF %>% subset(ProteinName %in% Proteins)
  }

  # Calculate log10 abundance
  ProMexDF$`Log10 Abundance` <- log10(ProMexDF$Abundance)

  # Make plot
  ProMexPlot <- ggplot2::ggplot(ProMexDF,
    ggplot2::aes(x = MinElutionTime, xend = MaxElutionTime, y = MonoMass,
      yend = MonoMass, color = `Log10 Abundance`, label = ProteinName)) +
    ggplot2::geom_segment() + ggplot2::theme_bw() + ggplot2::xlab("Elution Time [Minutes]") +
    ggplot2::ylab("Monoisotopic Mass [Da]") +
    ggplot2::scale_color_gradient2(low = "blue", mid = "grey", high = "red",
                                   midpoint = median(ProMexDF$`Log10 Abundance`))

  # Return interactive or not
  if (Interactive) {
    ProMexPlot %>% plotly::ggplotly()
  } else {
    ProMexPlot
  }

}
EMSL-Computing/pspecterlib documentation built on Jan. 28, 2024, 8:13 p.m.