Revision 738b43f6dcce877b85c10f23dafc38e0098bd8fb authored by Daniel Luedecke on 19 February 2014, 11:32:18 UTC, committed by cran-robot on 19 February 2014, 11:32:18 UTC
1 parent 64f2fd6
Raw File
sjPlotAnova.R
# bind global variables
if(getRversion() >= "2.15.1") utils::globalVariables(c("xv", "lower", "upper", "pv", "p"))


#' @title Plot One-Way-Anova tables
#' @name sjp.aov1
#' 
#' @description Plot One-Way-Anova table sum of squares (SS) of each factor level (group) 
#'                against the dependent variable. The SS of the factor variable against the 
#'                dependent variable (variance within and between groups) is printed to
#'                the model summary.
#' @seealso \link{sju.aov1.levene}
#'                
#' @param depVar The dependent variable. Will be used with following formular:
#'          \code{aov(depVar ~ grpVar)}
#' @param grpVar The grouping variable, as unordered factor. Will be used with following formular:
#'          \code{aov(depVar ~ grpVar)}
#' @param meansums If \code{TRUE}, the values reported are the true group mean values. If \code{FALSE} (default),
#'          the values are reported in the standard way, i.e. the values indicate the difference of
#'          the group mean in relation to the intercept (reference group).
#' @param type Indicates Whether the group means should be plotted as \code{"dots"} (aka forest plots, default)
#'          or as \code{"bars"}.
#' @param hideErrorBars If \code{TRUE}, the error bars that indicate the confidence intervals of the group means are not
#'          shown. Only applies if parameter \code{type} is \code{"bars"}. Default value is \code{FALSE}.
#' @param title Diagram's title as string.
#'          Example: \code{title=c("my title")}
#' @param titleSize The size of the plot title. Default is 1.3.
#' @param titleColor The color of the plot title. Default is \code{"black"}.
#' @param axisLabels.y Value labels of the grouping variable \code{grpVar} that are used for labelling the
#'          grouping variable axis. Passed as vector of strings.
#'          Example: \code{axisLabels.y=c("Label1", "Label2", "Label3")}. \cr
#'          Note: If you use the \code{\link{sji.SPSS}} function and the \code{\link{sji.getValueLabels}} function, you receive a
#'          list object with label string. The labels may also be passed as list object. They will be unlisted and
#'          converted to character vector automatically. See examples below. \cr
#'          Note: In case \code{type} is \code{"bars"}, the \code{grpVar} will be plotted along
#'          the x-axis.
#' @param reverseOrder If \code{TRUE}, the order of the factor categories (groups) is reversed.
#'          Default is \code{FALSE}.
#' @param stringIntercept A string that indicates the reference group (intercept), that is appended to
#'          the value label of the grouping variable. Default is \code{"(Intercept)"}.
#' @param showAxisLabels.y Whether y axis text (category value) should be shown (use \code{TRUE})
#'          or not. Default is \code{TRUE}.
#' @param axisLabelSize The size of value labels in the diagram. Default is 4, recommended values range
#'          between 2 and 8.
#' @param axisLabelColor The color of the category labels (predictor labels). Default is a dark grey (grey30).
#' @param axisTitle.x A label for the x axis. Default is \code{NULL}, which means no x-axis title.
#' @param axisTitleColor The color of the x axis label.
#' @param axisTitleSize The size of the x axis label. Default is 1.2.
#' @param axisLimits Defines the range of the axis where the beta coefficients and their confidence intervalls
#'          are drawn. By default, the limits range from the lowest confidence interval to the highest one, so
#'          the diagram has maximum zoom. Use your own values as 2-value-vector, for instance: \code{limits=c(-0.8,0.8)}.
#' @param valueLabelColor Colour of the values inside the diagram. Only applies, when parameter
#'          \code{showValueLabels} is set to \code{TRUE}. Use any valid colour value, e.g. \code{valueLabelColor="grey50"} or
#'          \code{valueLabelColor=c("#cc3366")}. Default is \code{"grey20"}.
#' @param valueLabelColorNS Colour of the non significant values inside the diagram.
#'          Only applies, when parameter \code{showValueLabels} is set to \code{TRUE}. Use any valid colour value, e.g. 
#'          \code{valueLabelColor="grey50"} or \code{valueLabelColor=c("#cc3366")}. Default is \code{"grey50"}.
#' @param valueLabelSize Size of the value labels. Drfault is 4.5. Recommended Values range from
#'          2 to 8
#' @param valueLabelAlpha The alpha level (transparancy) of the value labels. Default is 0.8, use
#'          any value from 0 to 1.
#' @param axisLabelAngle.x Angle for x-axis-labels, passed as numeric value.
#' @param axisLabelAngle.y Angle for y-axis-labels, passed as numeric value.
#' @param errorBarColor The color of the error bars that indicate the confidence intervalls
#'          of the group means. Default is \code{NULL}, which means that if \code{type} is \code{"dots"},
#'          the \code{pointColors} value will be used as error bar color. In case \code{type} is \code{"bars"},
#'          \code{"black"} will be used as error bar color.
#' @param errorBarWidth The width of the error bar ends. Default is 0.
#' @param errorBarSize The size of the error bar. Default is 0.8.
#' @param errorBarLineType The linetype of error bars. Default is \code{1} (solid line).
#' @param pointColors The colours of the points that indicate the mean-value. \code{pointColors} is a 
#'          vector with two values: the first indicating groups with positive means and the second 
#'          indicating negative means. Default is \code{c("#3366a0", "#aa6633")}.
#' @param pointSize The size of the points that indicate the mean-value. Default is 3.
#' @param barColors The colors of the bars in bar charts. Only applies if parameter \code{type} is \code{"bars"}. \code{barColors} is a 
#'          vector with two values: the first indicating groups with positive means and the second 
#'          indicating negative means. Default is \code{c("#3366a0", "#aa6633")}.
#' @param barWidth The width of the bars in bar charts. Only applies if parameter \code{type} is \code{"bars"}. Default is 0.5
#' @param barAlpha The alpha value of the bars in bar charts. Only applies if parameter \code{type} is \code{"bars"}. Default is 1
#' @param barOutline If \code{TRUE}, each bar gets a colored outline. Only applies if parameter \code{type} is \code{bars}.
#'          Default is \code{FALSE}.
#' @param outlineColor The color of the bar outline. Only applies, if \code{barOutline} is set to \code{TRUE}.
#'          Default is black.
#' @param breakTitleAt Wordwrap for diagram title. Determines how many chars of the title are displayed in
#'          one line and when a line break is inserted into the title
#' @param breakLabelsAt Wordwrap for diagram labels. Determines how many chars of the category labels are displayed in 
#'          one line and when a line break is inserted
#' @param gridBreaksAt Sets the breaks on the y axis, i.e. at every n'th position a major
#'          grid is being printed. Default is \code{NULL}, so \link{pretty} gridbeaks will be used.
#' @param borderColor User defined color of whole diagram border (panel border).
#' @param axisColor User defined color of axis border (y- and x-axis, in case the axes should have different colors than
#'          the diagram border).
#' @param theme Specifies the diagram's background theme. Default (parameter \code{NULL}) is a gray 
#'          background with white grids.
#'          \itemize{
#'          \item Use \code{"bw"} for a white background with gray grids
#'          \item \code{"classic"} for a classic theme (black border, no grids)
#'          \item \code{"minimal"} for a minimalistic theme (no border,gray grids) or 
#'          \item \code{"none"} for no borders, grids and ticks.
#'          }
#'          The ggplot-object can be returned with \code{returnPlot} set to \code{TRUE} in order to further
#'          modify the plot's theme.
#' @param majorGridColor Specifies the color of the major grid lines of the diagram background.
#' @param minorGridColor Specifies the color of the minor grid lines of the diagram background.
#' @param hideGrid.x If \code{TRUE}, the x-axis-gridlines are hidden. Default if \code{FALSE}.
#' @param hideGrid.y If \code{TRUE}, the y-axis-gridlines are hidden. Default if \code{FALSE}.
#' @param showTickMarks Whether tick marks of axes should be shown or not
#' @param showValueLabels Whether the value labels (mean differences) should be plotted 
#'          to each dot or not.
#' @param labelDigits The amount of digits for rounding the estimations (see \code{showValueLabels}).
#'          Default is 2, i.e. estimators have 2 digits after decimal point.
#' @param showPValueLabels Whether the significance levels of each category/group should be appended
#'          to values or not.
#' @param showModelSummary If \code{TRUE} (default), a summary of the anova model with 
#'          Sum of Squares between groups (ssb), Sum of Squares within groups (ssw), multiple and adjusted 
#'          R-square and F-Test is printed to the lower right corner
#'          of the diagram. Default is \code{TRUE}.
#' @param returnPlot If \code{TRUE}, the ggplot-object with the complete plot will be returned (and not plotted).
#'          Default is \code{FALSE}, hence the ggplot object will be plotted, not returned.
#' @return The ggplot-object with the complete plot in case \code{returnPlot} is \code{TRUE}.
#' 
#' @examples
#' data(efc)
#' sjp.aov1(efc$c12hour, as.factor(efc$e42dep))
#' 
#' 
#' data(efc)
#' efc.val <- sji.getValueLabels(efc)
#' efc.var <- sji.getVariableLabels(efc)
#' sjp.aov1(efc$c12hour,
#'          as.factor(efc$e42dep),
#'          axisLabels.y=efc.val['e42dep'],
#'          axisTitle.x=efc.var[['c12hour']])
#'          
#' sjp.aov1(efc$c12hour,
#'          as.factor(efc$e42dep),
#'          axisLabels.y=efc.val['e42dep'],
#'          title=efc.var[['c12hour']],
#'          type="bars",
#'          meansums=TRUE,
#'          hideErrorBars=TRUE,
#'          theme="minimal",
#'          minorGridColor="white",
#'          showTickMarks=FALSE,
#'          showModelSummary=FALSE,
#'          hideGrid.x=TRUE)
#' 
#' sjp.aov1(efc$c12hour,
#'          as.factor(efc$c172code),
#'          axisLabels.y=efc.val['c172code'],
#'          title=efc.var[['c12hour']],
#'          type="bars",
#'          showTickMarks=FALSE,
#'          showModelSummary=FALSE,
#'          axisLabelAngle.x=90)
#'
#' @import ggplot2
#' @export
sjp.aov1 <- function(depVar,
                    grpVar,
                    meansums=FALSE,
                    type="dots",
                    hideErrorBars=FALSE,
                    title=NULL,
                    titleSize=1.3,
                    titleColor="black",
                    axisLabels.y=NULL, 
                    reverseOrder=FALSE,
                    stringIntercept="(Intercept)",
                    showAxisLabels.y=TRUE,
                    axisLabelSize=1.1,
                    axisLabelColor="gray30",
                    axisTitle.x=NULL,
                    axisTitleSize=1.2,
                    axisTitleColor=c("#444444"),
                    axisLimits=NULL,
                    valueLabelColor="grey20",
                    valueLabelColorNS="grey50",
                    valueLabelSize=4.5,
                    valueLabelAlpha=0.8,
                    axisLabelAngle.x=0, 
                    axisLabelAngle.y=0, 
                    errorBarColor=NULL,
                    errorBarWidth=0,
                    errorBarSize=0.8,
                    errorBarLineType=1,
                    pointColors=c("#3366a0", "#aa3333"),
                    pointSize=3,
                    barColors=c("#3366a0", "#aa3333"),
                    barWidth=0.5,
                    barAlpha=1,
                    barOutline=FALSE,
                    outlineColor="black",
                    breakTitleAt=50, 
                    breakLabelsAt=12, 
                    gridBreaksAt=NULL,
                    borderColor=NULL, 
                    axisColor=NULL, 
                    theme=NULL,
                    majorGridColor=NULL,
                    minorGridColor=NULL,
                    hideGrid.x=FALSE,
                    hideGrid.y=FALSE,
                    showTickMarks=TRUE,
                    showValueLabels=TRUE, 
                    labelDigits=2,
                    showPValueLabels=TRUE,
                    showModelSummary=TRUE,
                    returnPlot=FALSE) {
  # --------------------------------------------------------
  # unlist labels
  # --------------------------------------------------------
  # Help function that unlists a list into a vector
  unlistlabels <- function(lab) {
    dummy <- unlist(lab)
    labels <- c()
    for (i in 1:length(dummy)) {
      labels <- c(labels, as.character(dummy[i]))
    }
    return (labels)
  }
  if (!is.null(axisLabels.y)) {
    # if labels are lists, unlist
    if (is.list(axisLabels.y)) {
      axisLabels.y <- unlistlabels(axisLabels.y)
    }
    # append "intercept" string, to mark the reference category
    axisLabels.y[1] <- paste(axisLabels.y[1], stringIntercept)
  }
  

  # --------------------------------------------------------
  # Parameter check
  # --------------------------------------------------------
  
  # --------------------------------------------------------
  # Check if grpVar is factor. If not, convert to factor
  # --------------------------------------------------------
  if (!is.factor(grpVar)) {
    grpVar <- as.factor(grpVar)
  }
  # --------------------------------------------------------
  # Check spelling of type-param
  # --------------------------------------------------------
  if (type=="dot" || type=="d") {
    type <- "dots"
  }
  if (type=="bar" || type=="b") {
    type <- "bars"
  }
  # --------------------------------------------------------
  # set geom colors
  # --------------------------------------------------------
  if (type=="dots") {
    geomcols <- pointColors
  }
  else {
    geomcols <- barColors
  }
  # --------------------------------------------------------
  # check whether we colors for error bars. if not, use point color
  # in case of dots or "black" in case of bars.
  # --------------------------------------------------------
  if (is.null(errorBarColor)) {
    if (type=="dots") {
      errorBarColors <- geomcols
    }
    else {
      errorBarColors <- c("black", "black")
    }
  }
  else {
    errorBarColors <- c(errorBarColor, errorBarColor)
  }
  # --------------------------------------------------------
  # check whether we have x-axis title. if not, use standard
  # value
  # --------------------------------------------------------
  if (is.null(axisTitle.x)) {
    axisTitle.x <- c("")
  }
  # --------------------------------------------------------
  # check whether bars should have an outline
  # --------------------------------------------------------
  if (!barOutline) {
    outlineColor <- waiver()
  }  
  
  
  # check length of diagram title and split longer string at into new lines
  # every 50 chars
  if (!is.null(title)) {
    title <- sju.wordwrap(title, breakTitleAt)
  }
  # check length of x-axis title and split longer string at into new lines
  # every 50 chars
  if (!is.null(axisTitle.x)) {
    axisTitle.x <- sju.wordwrap(axisTitle.x, breakTitleAt)
  }
  # check length of x-axis-labels and split longer strings at into new lines
  # every 10 chars, so labels don't overlap
  if (!is.null(axisLabels.y)) {
    axisLabels.y <- sju.wordwrap(axisLabels.y, breakLabelsAt)
  }
  
  
  # ----------------------------
  # Calculate one-way-anova. Since we have
  # only one group variable, Type of SS does
  # not matter.
  # ----------------------------
  fit <- aov(depVar ~ grpVar)
  # coefficients (group mean)
  means <- summary.lm(fit)$coefficients[,1]
  # p-values of means
  means.p <- summary.lm(fit)$coefficients[,4]
  # lower confidence intervals of coefficients (group mean)
  means.lci <- confint(fit)[,1]
  # upper confidence intervals of coefficients (group mean)
  means.uci <- confint(fit)[,2]
  
  
  # ----------------------------
  # Check whether true group means should be reported
  # or the differences of group means in relation to the
  # intercept (reference group). The latter is the default.
  # ----------------------------
  if (meansums) {
    for (i in 2:length(means)) {
      means[i] <- means[i]+means[1]
      means.lci[i] <- means.lci[i]+means[1]
      means.uci[i] <- means.uci[i]+means[1]
    }
  }

  
  # ----------------------------
  # create expression with model summarys. used
  # for plotting in the diagram later
  # ----------------------------
  if (showModelSummary) {
    # sum of squares
    ss <- summary(fit)[[1]]['Sum Sq']
    # multiple r2
    r2 <- summary.lm(fit)$r.squared
    # adj. r2
    r2.adj <- summary.lm(fit)$adj.r.squared
    # get F-statistics
    fstat <- summary.lm(fit)$fstatistic[1]
    # p-value for F-test
    pval <- summary(fit)[[1]]['Pr(>F)'][1,1]
    # indicate significance level by stars
    pan <- c("")
    if (pval<=0.005) {
      pan <- c("***")
    }
    else  if (pval<=0.01) {
      pan <- c("**")
    }
    else  if (pval<=0.05) {
      pan <- c("*")
    }
    # create mathematical term
    modsum <- as.character(as.expression(
      substitute(italic(SS[B]) == ssb * "," ~~ italic(SS[W]) == ssw * "," ~~ R^2 == mr2 * "," ~~ "adj." * R^2 == ar2 * "," ~~ "F" == f * panval,
                 list(ssb=sprintf("%.2f", ss[1,]),
                      ssw=sprintf("%.2f", ss[2,]),
                      mr2=sprintf("%.3f", r2),
                      ar2=sprintf("%.3f", r2),
                      f=sprintf("%.2f", fstat),
                      panval=pan))))
  }
  
  
  # ----------------------------
  # print coefficients and p-values in plot
  # ----------------------------
  # init data column for p-values
  ps <- c(round(means,labelDigits))
  # if no values should be shown, clear
  # vector now
  if (!showValueLabels) {
    ps <- rep(c(""), length(ps))
  }

  
  # --------------------------------------------------------
  # copy p-values into data column
  # --------------------------------------------------------
  if (showPValueLabels) {
    for (i in 1:length(means.p)) {
      if (means.p[i]>=0.05) {
      }
      else if (means.p[i]>=0.01 && means.p[i]<0.05) {
        ps[i] <- paste(ps[i], "*")
      }
      else if (means.p[i]>=0.001 && means.p[i]<0.01) {
        ps[i] <- paste(ps[i], "**")
      }
      else {
        ps[i] <- paste(ps[i], "***")
      }
    }  
  }
  
  
  # --------------------------------------------------------
  # check whether order of category items should be reversed
  # or not
  # --------------------------------------------------------
  if (reverseOrder) {
    catorder <- c(length(means):1)
  }
  else {
    catorder <- c(1:length(means))
  }
  # --------------------------------------------------------
  # create new data.frame, since ggplot requires data.frame as parameter
  # The data frame contains means, CI and p-values
  # --------------------------------------------------------
  df <- data.frame(cbind(
    # Append coefficients
    means,
    # append CI
    means.lci,
    means.uci,
    # append p-value
    means.p,
    ps,
    catorder))
  
                    
  # --------------------------------------------------------
  # check if user defined labels have been supplied
  # if not, use variable names from data frame
  # --------------------------------------------------------
  if (is.null(axisLabels.y)) {
    axisLabels.y <- row.names(df)
  }
  # order labels
  axisLabels.y <- axisLabels.y[catorder]

  
  # give columns names
  names(df) <- c("means", "lower", "upper", "p", "pv", "xv")
  df$means <- as.numeric(as.character(df$means))
  df$lower <- as.numeric(as.character(df$lower))
  df$upper <- as.numeric(as.character(df$upper))
  df$p <- as.numeric(as.character(df$p))
  df$pv <- as.character(df$pv)
  # bind color values to data frame, because we cannot use several
  # different color aesthetics in ggplot
  df <- cbind(df,
              geocol=ifelse(df$means>=0, geomcols[1], geomcols[2]), 
              labcol=ifelse(df$p<0.05, valueLabelColor, valueLabelColorNS),
              errcol=ifelse(df$means>=0, errorBarColors[1], errorBarColors[2]))
  
  
  # --------------------------------------------------------
  # Calculate axis limits. The range is from lowest lower-CI
  # to highest upper-CI, or a user-defined range (if "axisLimits"
  # is not NULL)
  # --------------------------------------------------------
  if (is.null(axisLimits)) {
    # check whether we have bar chart and error bars hidden
    # in this case, the upper limit does not correspond to the
    # upper CI, but to the highest OR value
    if (type=="bars") {
      # if errorbars are hidden, the axis range is defined
      # by the mean values
      if (hideErrorBars) {
        maxval <- max(df$means)+10
        minval <- min(df$means)
      }
      # if errorbars are shown, axis range is defined
      # by confidence interval
      else {
        maxval <- max(df$upper)
        minval <- min(df$lower)
      }
      # if minval is > 0, set it to zero, so we have a proper baseline
      if (minval>0) minval <- 0
      # if maxval is < 0, set it to zero, so we have a proper baseline
      if (maxval<0) maxval <- 0
    }
    else {
      # else we have confindence intervals displayed, so
      # the range corresponds to the boundaries given by
      # the CI's
      maxval <- max(df$upper)
      minval <- min(df$lower)
    }
    if (maxval>0) limfac <- ifelse(abs(maxval)<5, 5, 10)
    else limfac <- ifelse(abs(minval)<5, 5, 10)
    upper_lim <- ifelse(maxval==0, 0, limfac*ceiling((maxval+1)/limfac))
    lower_lim <- ifelse(minval==0, 0, limfac*floor(minval/limfac))
  }
  else {
    lower_lim <- axisLimits[1]
    upper_lim <- axisLimits[2]
  }
  # determine gridbreaks
  if (is.null(gridBreaksAt)) {
#     gridBreaksAt <- 1
#     while ((upper_lim-lower_lim) > (10*gridBreaksAt)) {
#       gridBreaksAt <- gridBreaksAt*10
#     }
    ticks <- pretty(c(lower_lim, upper_lim))
  }
  else {
    ticks <- c(seq(lower_lim, upper_lim, by=gridBreaksAt))
  }
  
  
  # --------------------------------------------------------
  # Set theme and default grid colours. grid colours
  # might be adjusted later
  # --------------------------------------------------------
  hideGridColor <- c("white")
  if (is.null(theme)) {
    ggtheme <- theme_gray()
    hideGridColor <- c("gray90")
  }
  else if (theme=="bw") {
    ggtheme <- theme_bw()
  }
  else if (theme=="classic") {
    ggtheme <- theme_classic()
  }
  else if (theme=="minimal") {
    ggtheme <- theme_minimal()
  }
  else if (theme=="none") {
    ggtheme <- theme_minimal()
    majorGridColor <- c("white")
    minorGridColor <- c("white")
    showTickMarks <-FALSE
  }
  
  
  # --------------------------------------------------------
  # Set up grid colours
  # --------------------------------------------------------
  majorgrid <- NULL
  minorgrid <- NULL
  if (!is.null(majorGridColor)) {
    majorgrid <- element_line(colour=majorGridColor)
  }
  if (!is.null(minorGridColor)) {
    minorgrid <- element_line(colour=minorGridColor)
  }
  hidegrid <- element_line(colour=hideGridColor)
  
  
  # --------------------------------------------------------
  # Set up visibility of tick marks
  # --------------------------------------------------------
  if (!showTickMarks) {
    ggtheme <- ggtheme + theme(axis.ticks = element_blank())
  }
  if (!showAxisLabels.y) {
    axisLabels.y <- c("")
  }
  
  
  # --------------------------------------------------------
  # Set up plot padding (margins inside diagram). In case of
  # bars, we don't want margins.
  # --------------------------------------------------------
  if (type=="bars") {
    scaley <- scale_y_continuous(limits=c(lower_lim,upper_lim), expand=c(0,0), breaks=ticks, labels=ticks)    
  }
  else {
    scaley <- scale_y_continuous(limits=c(lower_lim,upper_lim), breaks=ticks, labels=ticks)    
  }
  
  
  # --------------------------------------------------------
  # Start plot here!
  # --------------------------------------------------------
  if (type=="dots") {
    anovaplot <- ggplot(df, aes(y=means, x=xv)) +
      # print point
      geom_point(size=pointSize, colour=df$geocol) +
      # and error bar
      geom_errorbar(aes(ymin=lower, ymax=upper), colour=df$errcol, size=errorBarSize, width=errorBarWidth, linetype=errorBarLineType) +
      # Print p-values. With vertical adjustment, so they don't overlap with the errorbars
      geom_text(aes(label=pv, y=means), colour=df$labcol, vjust=-0.8, size=valueLabelSize, alpha=valueLabelAlpha, show_guide=FALSE)
  }
  # --------------------------------------------------------
  # start with bar plots here
  # --------------------------------------------------------
  else if (type=="bars") {
    # check whether we have error bars. if yes, adjust horizontal
    # posizion of labels
    hlabj <- ifelse(hideErrorBars==FALSE, 1.3, 0.5)
    anovaplot <- ggplot(df, aes(y=means, x=xv)) +
      # stat-parameter indicates statistics
      # stat="bin": y-axis relates to count of variable
      # stat="identity": y-axis relates to value of variable
      geom_bar(fill=df$geocol, stat="identity", position="identity", width=barWidth, colour=outlineColor, alpha=barAlpha) +
      # print value labels and p-values
      geom_text(aes(label=pv, y=means), colour=df$labcol, vjust=ifelse(df$means>=0, -1, 1), hjust=hlabj, size=valueLabelSize, alpha=valueLabelAlpha, show_guide=FALSE)
    if (hideErrorBars==FALSE) {
      anovaplot <- anovaplot +
        # print confidence intervalls (error bars)
        geom_errorbar(aes(ymin=lower, ymax=upper), colour=df$errcol, width=errorBarWidth, size=errorBarSize, linetype=errorBarLineType)
    }
  }
  # --------------------------------------------------------
  # continue with other plot elements
  # --------------------------------------------------------
  anovaplot <- anovaplot +
    # set y-scale-limits, breaks and tick labels
    scaley +
    # set value labels to x-axis
    scale_x_discrete(labels=axisLabels.y, limits=c(1:nrow(df))) +
    # flip coordinates
    labs(title=title, x=NULL, y=axisTitle.x) +
    ggtheme +
    # set axes text and 
    theme(axis.text = element_text(size=rel(axisLabelSize), colour=axisLabelColor), 
          axis.title = element_text(size=rel(axisTitleSize), colour=axisTitleColor), 
          axis.text.y = element_text(angle=axisLabelAngle.y),
          axis.text.x = element_text(angle=axisLabelAngle.x),
          plot.title = element_text(size=rel(titleSize), colour=titleColor))
  # --------------------------------------------------------
  # Flip coordinates when we have dots
  # --------------------------------------------------------
  if (type=="dots") {
    anovaplot <- anovaplot + coord_flip()
  }
  # the panel-border-property can only be applied to the bw-theme
  if (!is.null(borderColor)) {
    if (!is.null(theme) && theme=="bw") {
      anovaplot <- anovaplot + 
        theme(panel.border = element_rect(colour=borderColor))
    }
    else {
      cat("\nParameter 'borderColor' can only be applied to 'bw' theme.\n")
    }
  }
  if (!is.null(axisColor)) {
    anovaplot <- anovaplot + 
      theme(axis.line = element_line(colour=axisColor))
  }
  if (!is.null(minorgrid)) {
    anovaplot <- anovaplot + 
      theme(panel.grid.minor = minorgrid)
  }
  if (!is.null(majorgrid)) {
    anovaplot <- anovaplot + 
      theme(panel.grid.major = majorgrid)
  }
  if (hideGrid.x) {
    anovaplot <- anovaplot + 
      theme(panel.grid.major.x = hidegrid,
            panel.grid.minor.x = hidegrid)
  }
  if (hideGrid.y) {
    anovaplot <- anovaplot + 
      theme(panel.grid.major.y = hidegrid,
            panel.grid.minor.y = hidegrid)
  }
  
  
  # check whether modelsummary should be printed
  if (showModelSummary) {
    # add annotations with model summary
    # annotations include intercept-value and model's r-square
    if (type=="dots") {
      anovaplot <- anovaplot + annotate("text", label=modsum, parse=TRUE, x=-Inf, y=Inf, colour=valueLabelColor, size=valueLabelSize, alpha=valueLabelAlpha, vjust=-0.5, hjust=1.1)
    }
    else {
      anovaplot <- anovaplot + annotate("text", label=modsum, parse=TRUE, x=-Inf, y=Inf, colour=valueLabelColor, size=valueLabelSize, alpha=valueLabelAlpha, vjust=1.2, hjust=-0.02)
    }
  }
  # ---------------------------------------------------------
  # Check whether ggplot object should be returned or plotted
  # ---------------------------------------------------------
  if (returnPlot) {
    return(anovaplot)
  }
  else {
    # print plot
    print(anovaplot)
  }
}



#' @title Plot Levene-Test for One-Way-Anova
#' @name sju.aov1.levene
#' 
#' @description Plot results of Levene's Test for Equality of Variances for One-Way-Anova.
#' @seealso \link{sjp.aov1}
#'                
#' @param depVar The dependent variable. Will be used with following formular:
#'          \code{aov(depVar ~ grpVar)}
#' @param grpVar The grouping variable, as unordered factor. Will be used with following formular:
#'          \code{aov(depVar ~ grpVar)}
#' 
#' @examples
#' data(efc)
#' sju.aov1.levene(efc$c12hour, as.factor(efc$e42dep))
#' 
#' @export
sju.aov1.levene <- function(depVar, grpVar) {
  means <- tapply(depVar, grpVar, mean)
  depVarNew <- abs(depVar - means[grpVar])
  cat("\nLevene's Test for Homogeneity of Variances\n---------------------------------------\n")
  fit <- aov(depVarNew ~ grpVar)
  print(summary(fit))
  pval <- summary(fit)[[1]]['Pr(>F)'][1,1]
  # print "summary" of test
  cat("\nConclusion:\n")
  if (pval>0.05) {
    cat("Groups are homogeneous. Everything's fine.\n")
  }
  else {
    cat("Groups are not homogeneous! Consider logarithmic transformation.\n")
  }
}
back to top