#' Trim motifs.
#'
#' Remove edges of motifs with low information content. Currently does
#' not trim `multifreq` representations.
#'
#' @param motifs See [convert_motifs()] for acceptable formats.
#' @param min.ic `numeric(1)` Minimum allowed information content. See
#' [convert_type()] for a discussion on information content.
#' @param trim.from `character(1)` Control the direction of trimming.
#'
#' @return Motifs See [convert_motifs()] for available output
#' formats.
#'
#' @examples
#' jaspar <- read_jaspar(system.file("extdata", "jaspar.txt",
#' package = "universalmotif"))
#' jaspar.trimmed <- trim_motifs(jaspar)
#'
#' @seealso [create_motif()], [convert_type()]
#' @author Benjamin Jean-Marie Tremblay, \email{benjamin.tremblay@@uwaterloo.ca}
#' @export
trim_motifs <- function(motifs, min.ic = 0.25, trim.from = c("both", "left", "right")) {
# TODO:
# - manual trimming?
# param check --------------------------------------------
args <- as.list(environment())
num_check <- check_fun_params(list(min.ic = args$min.ic),
1, FALSE, TYPE_NUM)
all_checks <- c(num_check)
if (length(all_checks) > 0) stop(all_checks_collapse(all_checks))
#---------------------------------------------------------
trim.from <- match.arg(trim.from, c("both", "left", "right"))
trim.from <- switch(trim.from, "both" = 0, "left" = 1, "right" = 2)
if (is.list(motifs)) CLASS_IN <- vapply(motifs, .internal_convert, "character")
else CLASS_IN <- .internal_convert(motifs)
motifs <- convert_motifs(motifs)
if (!is.list(motifs)) motifs <- list(motifs)
mot.names <- vapply(motifs, function(x) x@name, character(1))
motifs <- lapply(motifs,
function(x) {
y <- x@nsites
if (length(y) == 0) x@nsites <- 100
x
})
mot.mats <- lapply(motifs, function(x) x@motif)
mot.mats.k <- lapply(motifs, function(x) x@multifreq)
mot.scores <- lapply(motifs,
function(x) {
apply(x@motif, 2, position_icscoreC,
bkg = x@bkg[rownames(x@motif)],
type = x@type,
pseudocount = x@pseudocount,
nsites = x@nsites)
})
new.mats <- mapply(function(x, y) trim_motif_internal(x, y, min.ic, trim.from),
mot.mats, mot.scores, SIMPLIFY = FALSE)
new.mats.k <- mapply(
function(x, y) {
if (length(x) > 0) {
lapply(x, function(z) trim_motif_internal(z, y, min.ic, trim.from))
} else list()
}, mot.mats.k, mot.scores,
SIMPLIFY = FALSE
)
motifs <- mapply(
function(x, y, z) {
if (length(x) == 0) return(NULL)
z@motif <- x
z@multifreq <- y
z
}, new.mats, new.mats.k, motifs,
SIMPLIFY = FALSE
)
dont_keep <- vapply(motifs, is.null, logical(1))
num_bar <- which(dont_keep)
if (length(num_bar) > 0) {
if (length(num_bar) == length(mot.names)) {
stop("All motifs were completely trimmed")
}
message("The following motifs were completely trimmed: ",
mot.names[num_bar])
return(invisible(NULL))
}
motifs <- motifs[!dont_keep]
motifs <- lapply(motifs,
function(x) {
alph <- x@alphabet
type <- x@type
pseudo <- x@pseudocount
mat <- x@motif
bkg <- x@bkg[rownames(mat)]
nsites <- x@nsites
ic <- sum(apply(mat, 2, position_icscoreC, bkg = bkg,
type = type, pseudocount = pseudo,
nsites = nsites))
x@icscore <- ic
if (alph %in% c("DNA", "RNA")) {
consensus <- apply(mat, 2, get_consensusC,
alphabet = alph, type = type,
pseudocount = pseudo)
colnames(mat) <- consensus
x@motif <- mat
x@consensus <- paste(consensus, collapse = "")
} else if (alph == "AA") {
consensus <- apply(mat, 2, get_consensusAAC,
type = type, pseudocount = pseudo)
colnames(mat) <- consensus
x@motif <- mat
x@consensus <- paste(consensus, collapse = "")
}
validObject_universalmotif(x)
x
})
if (length(motifs) == 1) motifs <- motifs[[1]]
motifs <- .internal_convert(motifs, unique(CLASS_IN))
motifs
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.