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

Initialise plotMediation method #165

Open
wants to merge 1 commit into
base: devel
Choose a base branch
from
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
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export(plotColTile)
export(plotDMNFit)
export(plotFeaturePrevalence)
export(plotLoadings)
export(plotMediation)
export(plotNMDS)
export(plotPrevalence)
export(plotPrevalentAbundance)
Expand All @@ -31,6 +32,7 @@ exportMethods(plotColTree)
exportMethods(plotDMNFit)
exportMethods(plotFeaturePrevalence)
exportMethods(plotLoadings)
exportMethods(plotMediation)
exportMethods(plotPrevalence)
exportMethods(plotPrevalentAbundance)
exportMethods(plotRDA)
Expand All @@ -55,6 +57,7 @@ importFrom(BiocParallel,bplapply)
importFrom(BiocParallel,bpmapply)
importFrom(BiocParallel,bpstart)
importFrom(BiocParallel,bpstop)
importFrom(ComplexHeatmap,Heatmap)
importFrom(DelayedArray,rowMeans)
importFrom(DelayedArray,rowSums)
importFrom(DirichletMultinomial,mixture)
Expand Down
125 changes: 125 additions & 0 deletions R/plotMediation.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#' Visualize mediation
#'
#' \code{plotMediation()} generates a heatmap from the results of mediation
#' analysis produced with \code{mia:getMediation()} or \code{mia:addMediation()}.
#' It displays effect size and significance of the Actual Causal Mediation
#' Effect (ACME) and the Actual Direct Effect (ADE) for each mediator included
#' in the object \code{x}.
#'
#' @param x a
#' \code{\link[SummarizedExperiment:SummarizedExperiment-class]{SummarizedExperiment}}
#' object or a data.frame, returned as output from
#' \code{\link[mia:getMediation]{addMediation}} or
#' \code{\link[mia:getMediation]{getMediation}}, respectively.
#'
#' @param med.name \code{Character scalar} value defining which mediation data
#' to use. (Default: \code{"mediation"})
#'
#' @param add.signif \code{Logical scalar}. Should the p-values in the plot be
#' displayed? (Default: \code{FALSE})
#'
#' @details
#' \code{plotMediation} creates a heatmap starting from the
#' output of the \code{\link[mia:getMediation]{mediation}} functions, which are
#' mia wrappers for the basic \code{\link[mediation:mediate]{mediate}} function.
#' Either a \code{\link[SummarizedExperiment:SummarizedExperiment-class]{SummarizedExperiment}}
#' or a data.frame object is supported as input. When the input is a
#' SummarizedExperiment, this should contain the output of addMediation
#' in the metadata slot and the argument \code{med.name} needs to be defined.
#' When the input is a data.frame, this should be returned as output from
#' getMediation.
#'
#' @return
#' a \code{\link[ComplexHeatmap:Heatmap-class]{Heatmap}} object
#'
#' @examples
#' library(mia)
#' library(scater)
#'
#' # Load dataset
#' data(hitchip1006, package = "miaTime")
#' tse <- hitchip1006
#'
#' # Agglomerate features by family (merely to speed up execution)
#' tse <- agglomerateByRank(tse, rank = "Phylum")
#' # Convert BMI variable to numeric
#' tse$bmi_group <- as.numeric(tse$bmi_group)
#'
#' # Apply clr transformation to counts assay
#' tse <- transformAssay(tse,
#' method = "clr",
#' pseudocount = 1)
#'
#' # Analyse mediated effect of nationality on BMI via clr-transformed features
#' # 100 permutations were done to speed up execution, but ~1000 are recommended
#' tse <- addMediation(tse, name = "assay_mediation",
#' outcome = "bmi_group",
#' treatment = "nationality",
#' assay.type = "clr",
#' covariates = c("sex", "age"),
#' treat.value = "Scandinavia",
#' control.value = "CentralEurope",
#' boot = TRUE, sims = 100,
#' p.adj.method = "fdr")

#' plotMediation(tse, "assay_mediation")
#'
#'@name plotMediation

#' @rdname plotMediation
#' @export
setGeneric("plotMediation", function(x, ...) standardGeneric("plotMediation"))

Comment on lines +69 to +72
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add generics to AllGenerics.R

#' @rdname plotMediation
#' @export
#' @importFrom ComplexHeatmap Heatmap
setMethod("plotMediation", signature = c(x = "data.frame"),

function(x, add.signif = TRUE) {

coef_mat <- as.matrix(x[ , c("ACME_estimate", "ADE_estimate")])

rownames(coef_mat) <- x[["Mediator"]]
colnames(coef_mat) <- gsub("_estimate", "", colnames(coef_mat))

if( add.signif ){

p_mat <- as.matrix(x[ , c("ACME_pval", "ADE_pval")])

cell_fun <- function(j, i, k, y, w, h, fill) {
if(p_mat[i, j] < 0.001) {
grid.text("***", k, y)
} else if(p_mat[i, j] < 0.01) {
grid.text("**", k, y)
} else if(p_mat[i, j] < 0.05) {
grid.text("*", k, y)
Comment on lines +90 to +95
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could / should these thresholds be something that the user could define? and these ones here could be the default values? It could be for instance one argument, like signif.threshold = c(0.001, 0.01, 0.05) or if it is just signif.threshold = c(0.01, 0.05) with two values, then only two levels of stars etc?

}
}

} else {
cell_fun <- NULL
}

p <- Heatmap(coef_mat, name = "Effect",
cluster_rows = FALSE, cluster_columns = FALSE,
row_names_side = "left", column_names_side = "top",
column_names_rot = 0, rect_gp = gpar(col = "white", lwd = 2),
cell_fun = cell_fun)
Comment on lines +103 to +107
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My impression is that it would be good if users can pass these arguments, so these would come via the "..." mechanism in the function call? And the manpage could mention that the ComplexHeatmap::Heatmap arguments are supported. Or at least some critical ones.


return(p)
}
)


#' @rdname plotMediation
#' @export
setMethod("plotMediation", signature = c(x = "SummarizedExperiment"),

function(x, med.name = "mediation", add.signif = TRUE){

med_df <- metadata(x)[[med.name]]
p <- plotMediation(med_df, add.signif)

return(p)
}
)
80 changes: 80 additions & 0 deletions man/plotMediation.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading