
  # -------------------------------------------------------------------------------------------------------------------------  #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #           File Name              :  FullSummary.r                                                                          #
  #           Last Updated Funclist  :  08 Feb 2015,  5:12 AM (Sunday)                                                         #
  #                                                                                                                            #
  #           Author Name            :  Rick Saporta                                                                           #
  #           Author Email           :  RickSaporta@gmail.com                                                                  #
  #           Author URL             :  www.github.com/rsaporta                                                                #
  #                                                                                                                            #
  #           Packages Called        :  data.table, ggplot2, scales                                                            #
  #           Packages Used via NS   :  NA                                                                                     #
  #                                                                                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #   FullSummaryPlot    ( x, transform=c("identity", "sqrt", "log"), dontPrint=FALSE )                                        #
  #   FullSummary        ( x, transform=c("identity", "sqrt", "log"), round=NULL )                                             #
  #   plot.FullSummary   ( FS, dontPrint=FALSE, tit=capture.output(substitute(FS)) )                                           #
  #   append.value       ( txt, val )                                                                                          #
  #   pad.right          ( x, space=pasteR(" ", n=spaces), spaces=13 )                                                         #
  #   pad.left           ( x, space=pasteR(" ", n=spaces), spaces=13 )                                                         #
  #                                                                                                                            #
  #                                                                                                                            #
  #                                                     <END FUNCS>                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  # -------------------------------------------------------------------------------------------------------------------------  #

FullSummaryPlot <- function(x, transform=c("identity", "sqrt", "log"), dontPrint=FALSE) 
  plot(FullSummary(x, transform=transform), dontPrint=dontPrint, tit=capture.output(substitute(x)))  

FullSummary <- function(x, transform=c("identity", "sqrt", "log"), round=NULL) {
  transform <- match.arg(transform)
  x <- getFunction(transform)(x)

  mn <- mean(x)
  mdn <- median(x)
  sdx <- sd(x)
  madx <- mad(x)

  ret <- 
   list(
      Mean = c(
        `-2 SD` = ((-2) * sdx) + mn
      , `-1 SD` = ((-1) * sdx) + mn
      ,   mean  = mn
      , `+1 SD` = ((+1) * sdx) + mn
      , `+2 SD` = ((+2) * sdx) + mn
      )
      ,
      Median = c(
        `-2 MAD` = ((-2) * madx) + mdn
      , `-1 MAD` = ((-1) * madx) + mdn
      ,  median  = mdn
      , `+1 MAD` = ((+1) * madx) + mdn
      , `+2 MAD` = ((+2) * madx) + mdn
      )
      , 
      Summary=setNames(fivenum(x),  
        c("Min", "First", "Median", "Third", "Max")
        )
      , 
      data=sort(x)
    )

   if (!is.null(round) && !identical(round, FALSE))
      ret <- lapply(ret, round, round)

   class(ret) <- c(class(ret), "FullSummary")

   attr(ret, "transform") <- transform
   return(ret)
 }

plot.FullSummary <- function(FS, dontPrint=FALSE, tit=capture.output(substitute(FS))) {
  x <- "TEST"
  cat("tit is ", tit, "\n")

  require(data.table)
  require(ggplot2)
  require(scales)

  {
  # Flatten Summary Stats into a DT
  DT.summary <- as.data.table(do.call(rbind, FS[3:1]), keep.rownames=TRUE)
  # Simply for the legend
  DT.summary[rn=="Summary", rn := "IQR"]
  # Summary has to be in the middle so that for "dodge" it stays in the middle
  DT.summary[, rn := factor(rn, levels=c("Mean", "IQR", "Median"))]

  # We dont want to plot these for summary, but need to keep them for "dodge" to allign
  DT.summary[rn=="IQR", c("Min", "Median", "Max") := NA]
  
  DT.summary[, First.char := c("25%",  "-1 MAD", "-1 SD")]
  DT.summary[, Third.char := c("75%",  "+1 MAD", "+1 SD")]
  DT.summary[, Min.char := c("Min",            "-2 MAD", "-2 SD")]
  DT.summary[, Max.char := c("Max",            "+2 MAD", "+2 SD")]
  DT.summary[, Median.char    := as.character(rn)]

  val.cols  <- c("First", "Third", "Min", "Max", "Median")
  char.cols <- c("First.char", "Third.char", "Min.char", "Max.char", "Median.char")

  append.value <- function(txt, val)
    apply(center(rbind(txt, formnumb(selfRound(val))), all.same=FALSE, trim=TRUE), 2, pasteC, C="\n")

  for (i in seq(char.cols))
    DT.summary[, c(char.cols[[i]]) := append.value(get(char.cols[[i]]), get(val.cols[[i]])) ]

  DT.summary[rn=="IQR",  c(char.cols) := lapply(char.cols, function(x) paste0(get(x), "\n\n")   )]
  DT.summary[rn=="Mean", c(char.cols) := lapply(char.cols, function(x) paste0(get(x), "\n\n\n") )]

  pad.right <- function(x, space=pasteR(" ", n=spaces), spaces=13)
    paste(gsub("\\n", paste0(space, "\n"), x), space)
  pad.left <- function(x, space=pasteR(" ", n=spaces), spaces=13)
    paste(space, gsub("\\n", paste0("\n", space), x))

  DT.summary[rn=="IQR", First.char := pad.right(First.char)]
  DT.summary[rn=="IQR", Third.char := pad.left (Third.char)]

  ## Find Outliers
  .IQR <- IQR(FS$data)
  outliers <- FS$data[FS$data > 1.5 * .IQR + FS$Summary[["Third"]] | FS$data < -1.5 * .IQR + FS$Summary[["First"]]]

  # --------------------------------- #
  #      Title for the graph          #
  # --------------------------------- #
  if (missing(tit) && grepl("FullSummary\\(", tit))  # <~~~ This paren throws off findFnsInFile()
    tit <- strsplit(tit, "FullSummary\\(|,|\\)")[[c(1,2)]]

  trfm <- attr(FS, "transform") 
  if (!is.null(trfm) && trfm != "identity") 
    tit <- paste0(tit, "\nTransformed via ", ifelse(trfm=="sqrt", "Square Root",ifelse(trfm=="log", "Log", trfm)))
  tit <- paste("Summary of", tit)
  # --------------------------------- #
  }

  # how much to dodge by
  d <- (- 0.25)

  P <- 
  {
  ggplot() + 
    geom_violin(aes(y=y, x=x), trim=TRUE, scale="width", alpha=0.3, color=NA, fill="blue", data=data.frame(y=FS$data, x="Data"), show_guide=FALSE) + 
    geom_point(aes(y=y, x=x), data=data.frame(x="Data", y=outliers), show_guide=FALSE) + 
    coord_flip() + 

    geom_errorbar(aes(x="Data", ymin=Median, ymax=Median, color=rn), data=DT.summary, width=0.20, size=rel(0.65), position=position_dodge(width = d)) +
    geom_errorbar(aes(x="Data", ymin=First,  ymax=Third,  color=rn), data=DT.summary, width=0.15, size=rel(0.50), position=position_dodge(width = d)) +
    geom_errorbar(aes(x="Data", ymin=Min,    ymax=Max,    color=rn), data=DT.summary, width=0.05, size=rel(0.25), position=position_dodge(width = d), alpha=0.8) +

    # Vertical Bar at Median / Mean
    geom_point (aes(x="Data", y=Median, color=rn), data=DT.summary, size=rel(4.0), position=position_dodge(width = d), show_guide=FALSE, shape=124L) +

    # # Dots at ±2 SD / MAD  (removed for now)
    # geom_point (aes(x="Data", y=Min,    color=rn), data=DT.summary, size=rel(1.8), position=position_dodge(width = d), show_guide=FALSE) +
    # geom_point (aes(x="Data", y=Max,    color=rn), data=DT.summary, size=rel(1.8), position=position_dodge(width = d), show_guide=FALSE) +

    geom_text (aes(x="Data", y=Median, color=rn, label=Median.char), data=DT.summary, size=rel(3.0), position=position_dodge(width = 2.10*d), vjust=0.8, show_guide=FALSE) +
    geom_text (aes(x="Data", y=First,  color=rn, label=First.char),  data=DT.summary, size=rel(2.4), position=position_dodge(width = 1.65*d), vjust=0.8, show_guide=FALSE) +
    geom_text (aes(x="Data", y=Third,  color=rn, label=Third.char),  data=DT.summary, size=rel(2.4), position=position_dodge(width = 1.65*d), vjust=0.8, show_guide=FALSE) +
    geom_text (aes(x="Data", y=Min,    color=rn, label=Min.char),    data=DT.summary, size=rel(2.2), position=position_dodge(width = 1.45*d), vjust=0.8, show_guide=FALSE) +
    geom_text (aes(x="Data", y=Max,    color=rn, label=Max.char),    data=DT.summary, size=rel(2.2), position=position_dodge(width = 1.45*d), vjust=0.8, show_guide=FALSE) +


    scale_y_continuous(labels=comma) + 
#    scale_colour_manual(breaks=c("Mean", "IQR", "Median"), values=c(Mean="red3", Median="darkgreen", IQR="blue4")) + 
    scale_colour_manual(breaks=c("Mean", "IQR", "Median"), values=c(Mean="blue4", Median="red3", IQR="darkgreen")) + 

    ggtitle(tit) + xlab("") + ylab("") + 
    theme(axis.ticks.y=element_blank(), axis.text.y=element_blank(), title=element_text(size=rel(0.8))
        , legend.title=element_blank(), legend.position="none")
  }

  if(!dontPrint)
    suppressWarnings(suppressMessages(print(P)) )

  return(invisible(P))
}
