R/viz_rainforest.R

Defines functions viz_rainforest

Documented in viz_rainforest

#'Rainforest plots for meta-analyses
#'
#'Creates a rainforest plot, a novel variant of the forest plot.
#'
#'Rainforest plots were proposed by Schild and Voracek (2015) as a variant and
#'enhancement of classic forest plots. Rainforest plots use (log-)likelihood drops
#'to depict study level results (for details, see Barrowman &
#'Myers, 2003). \code{viz_rainforest} assumes normality of effect sizes to
#'construct these (log-)likelihood drops. The width of each such raindrop is identical to the
#'width of the confidence interval. For a given (log-)likelihood raindrop,
#'the height can be interpreted as the plausibility (i.e., (log-)likelihood value) for different true
#'values given the observed estimate. Moreover, the height of each raindrop is scaled with respect
#'to its relative meta-analytic weight considering all studies. Therefore, visually comparing heights of
#'different raindrops highlights the relative importance within the meta-analysis.
#'In addition, color shading is utilized to further visualize statistical uncertainty, as suggested by Jackson (2008).
#'Finally, study and summary level point estimates are depicted clearly by a specific symbol.
#'
#'Rainforest plots have the following advantages, as compared to classic forest plots:
#'
#'\enumerate{ \item The width of the likelihood raindrops corresponds to the
#'confidence intervals, as also shown in the classic forest plot. In addition,
#'for each likelihood drop the height (and color shading) visualizes the
#'plausibility of true values given the observed estimate.
#'
#'\item Low likelihood drops and light color shading causes small studies (with
#'wide confidence intervals and less weight in the meta-analysis) to be visually less
#'dominant.
#'
#'\item In classic forest plots, it is often hard to depict the magnitude of
#'point estimates to a reasonable degree of accuracy, especially for studies
#'with large meta-analytic weights and correspondingly large plotting symbols
#'(commonly squares). Specific symbols within the raindrops improve the
#'visualization of study point estimates. }
#'
#'Note that for subgroup analysis the height of each raindrop is scaled by the weight of each study within the subgroup divided by
#'the total weight sum of all studies irrespective of subgroup. Therefore, with subgroups present, the overall impression of raindrop
#'heights and color shading within a given subgroup compared to other subgroups conveys information about the relative precision of the meta-analytic
#'subgroup estimates.
#'
#'@param x data.frame or matrix with the effect sizes of all studies (e.g.,
#'  correlations, log odds ratios, or Cohen \emph{d}) in the first column and their
#'  respective standard errors in the second column. Alternatively, x can be the
#'  output object of function \code{\link[metafor]{rma.uni}} from package
#'  \pkg{metafor}; then effect sizes and standard errors are extracted from \code{x}.
#'@param group factor indicating the subgroup of each study to plot a subgroup forest plot. Has to be in the same order than \code{x}.
#'@param type character string indicating the type of forest plot to be plotted. Can be "standard" (default), "study_only",
#'  "summary_only", "cumulative", or "sensitivity". See 'Details'.
#'@param method character string indicating which method should be used to compute the study weights and summary effect(s).
#'  Can be any method argument from \code{\link[metafor]{rma.uni}}
#'  (e.g., "FE" for the fixed effect model, or "DL" for the random effects model using the
#'  DerSimonian-Laird method to estimate \eqn{\tau^2}{tau squared}).
#'  If input \code{x} is an output object of function \code{\link[metafor]{rma.uni}} from package \pkg{metafor}, then the method is extracted from \code{x}.
#'@param study_labels a character vector with names/identifiers to annotate each study in the forest plot.
#'  Has to be in the same order than \code{x}. Ignored if \code{study_table} and/or \code{summary_table} is supplied.
#'@param summary_label a character string specifying the name to annotate the summary effect. If a subgroup
#'  analysis is plotted, \code{summary_label} should be a character vector with a name for each
#'  subgroup summary effect, arranged in the order of the levels of \code{group}. Ignored if \code{study_table} and/or
#'  \code{summary_table} is supplied.
#'@param confidence_level numeric value. The confidence level for the plotted confidence intervals and likelihood raindrops.
#'@param detail_level numeric value. Values larger than 1 lead to a higher
#'  plotting detail (i.e., smoother likelihood raindrop polygons and more fluent
#'  color shading), values smaller than 1 to less plotting detail compared to
#'  the default plot.
#'@param col character string specifying the color palette for plotting study-level results from package \pkg{RColorBrewer}.
#'  Can be any of "Blues", "Greys", "Oranges", "Greens", "Reds", and "Purples".
#'@param summary_col character string specifying the color for plotting the summary effect(s). Can be any of "Blues", "Greys", "Oranges", "Greens", "Reds", and "Purples".
#'@param text_size numeric value. Size of text in the forest plot. Default is 3.
#'@param xlab character string specifying the label of the x axis. By default also used for the header of the aligned table if \code{annotate_CI} is \code{TRUE}.
#'@param x_limit numeric vector of length 2 with the limits (minimum, maximum) of the x axis.
#'@param x_trans_function function to transform the labels of the x axis. Common uses are to transform
#'  log-odds-ratios or log-risk-ratios with \code{exp} to their original scale (odds ratios and risk ratios), or Fisher's z values
#'  back to correlation coefficients using \code{tanh}.
#'@param x_breaks numeric vector of values for the breaks on the x-axis. When used in tandem with \code{x_trans_function}
#'  the supplied values should be not yet transformed.
#'@param annotate_CI logical scalar. Should the effect size and confidence interval values be shown as text in an aligned table on the right-hand side of the forest plot?
#'@param study_table a data.frame with additional study-level variables which should be shown in an aligned table.
#'  Has to be in the same order than \code{x}.
#'@param summary_table a data.frame with additional summary-level information shown in an aligned table.
#'  If \code{group} is supplied, \code{summary_table} must have a row for each subgroup
#'  summary effect, arranged in the order of the levels of \code{group}.
#'@param table_headers character vector. Headers for each column of aligned tables via \code{study_table}, \code{summary_table}, or \code{annotate_CI}.
#'@param table_layout numeric layout matrix passed to \code{layout_matrx} of \code{\link[gridExtra]{arrangeGrob}}. Can be used to overwrite the default spacing
#'  of the forest plot and aligned tables via \code{study_table}, \code{summary_table}, and \code{annotate_CI}.
#'@param ... deprecated argument names from earlier versions can still be passed to \code{viz_rainforest} via \code{...}.
#'@references Barrowman, N. J., & Myers, R. A. (2003). Raindrop plots: A new way
#'  to display collections of likelihoods and distributions. \emph{American
#'  Statistician}, \emph{57}, 268-274.
#'@references Jackson, C. H. (2008). Displaying uncertainty with shading.
#'  \emph{American Statistician}, \emph{62}, 340-347.
#'@references Schild, A. H., & Voracek, M. (2015). Finding your way out of the
#'  forest without a trail of bread crumbs: Development and evaluation of two
#'  novel displays of forest plots. \emph{Research Synthesis Methods}, \emph{6},
#'  74-86.
#'@return A Rainforest plot is created using ggplot2.
#'@author Michael Kossmeier* <michael.kossmeier@univie.ac.at>
#'@author Ulrich S. Tran* <ulrich.tran@univie.ac.at>
#'@author Martin Voracek* <martin.voracek@univie.ac.at>
#'@author *Department of Basic Psychological Research and Research Methods, School of Psychology, University of Vienna
#'@examples
#' library(metaviz)
#' # Plotting a rainforest plot using the mozart data
#' viz_rainforest(x = mozart[, c("d", "se")],
#' study_labels = mozart[, "study_name"], xlab = "Cohen d")
#'
#' # Visualizing a subgroup analysis of published and unpublished studies
#' viz_rainforest(x = mozart[, c("d", "se")], group = mozart[, "rr_lab"],
#' study_labels = mozart[, "study_name"], method = "REML",
#' summary_label = c("Summary (rr_lab = no)", "Summary (rr_lab = yes)"),
#' xlab = "Cohen d")
#'
#' # Showing additional information in aligned tables. Log risk ratios are labeled
#' # in their original metric (risk ratios) on the x axis.
#' viz_rainforest(x = exrehab[, c("logrr", "logrr_se")],
#' annotate_CI = TRUE, xlab = "RR", x_trans_function = exp,
#' study_table = data.frame(
#' Name = exrehab[, "study_name"],
#' eventsT = paste(exrehab$ai, "/", exrehab$ai + exrehab$bi, sep = ""),
#' eventsC = paste(exrehab$ci, "/", exrehab$ci + exrehab$di, sep = "")),
#' summary_table = data.frame(
#' Name = "Summary",
#' eventsT = paste(sum(exrehab$ai), "/", sum(exrehab$ai + exrehab$bi), sep = ""),
#' eventsC = paste(sum(exrehab$ci), "/", sum(exrehab$ci + exrehab$di), sep = "")))
#'@export
viz_rainforest <- function(x, group = NULL, type = "standard", method = "FE",
                       study_labels = NULL, summary_label = NULL,
                       confidence_level = 0.95, detail_level = 1, col = "Blues", summary_col = col,
                       text_size = 3, xlab = "Effect", x_limit = NULL,
                       x_trans_function = NULL, x_breaks = NULL, annotate_CI = FALSE,
                       study_table = NULL, summary_table = NULL,
                       table_headers = NULL, table_layout = NULL, ...) {

  # check if deprecated arguments were supplied
  add_arg <- list(...)
  if(!is.null(add_arg)) {
    if(is.null(study_labels) && "names" %in% names(add_arg)) {
      study_labels <- add_arg$names
    }
    if(is.null(summary_label) && "summary_name" %in% names(add_arg)) {
      summary_label <- add_arg$summary_name
    }
    if(type != "study_only" && "summary_symbol" %in% names(add_arg)) {
      type <- "study_only"
    }

    if(!is.null(names(add_arg)) & any(!(names(add_arg) %in% c("names", "summary_name", "summary_symbol")))) {
      warning(paste("unused arguments supplied to viz_rainforest:", paste(names(add_arg)[which(!(names(add_arg) %in% c("names", "summary_name", "summary_symbol")))], collapse = ", ")))
    }

  }

  viz_forest(x, group = group, type = type, variant = "rain", method = method,
             study_labels = study_labels, summary_label = summary_label,
             confidence_level = confidence_level, detail_level = detail_level, col = col, summary_col = summary_col,
             text_size = text_size, xlab = xlab, x_limit = x_limit,
             x_trans_function = x_trans_function, x_breaks = NULL,
             annotate_CI = annotate_CI, study_table = study_table,
             summary_table = summary_table,
             table_headers = table_headers,  table_layout = table_layout)
}

#' @export
#' @rdname viz_rainforest
rainforest <- viz_rainforest
Mkossmeier/metaviz documentation built on April 8, 2020, 2:30 a.m.