Nothing
#' boxplot with multcomp graphics
#'
#' Create boxplots with multcompTs and / or multcompLetters
#'
#' For formula = y~z, if 'sortFn' is a function or the name of a function,
#' 'multcompBoxplot' starts by applying sortFn to the subsets of y
#' corresponding to each level of z, and then sorting those summaries in
#' increasing or decreasing order, per 'decreasing'. If 'sortFn' is NULL or
#' NA, this sort step is skipped.
#'
#' 'multcompBoxplot' then creates 'boxplot' as specified in 'plotList'. Next,
#' 'compFn' is called to generate comparisons to feed to the functions
#' (\code{\link{multcompTs}} and / or \code{\link{multcompLetters}}, whose
#' output is then passed to (\code{\link{plot.multcomp}}) for plotting.
#' Components of the relevant sublists of 'plotList' are made available to
#' \code{\link{par}} or (for \code{\link{plot.multcompLetters}}) to
#' \code{\link[grid]{gpar}}.
#'
#' @param formula a two sided formula like "y~z", where both "y" and "z" are
#' columns of the data.frame "data", "y" is numeric, and "z" is a factor. This
#' will be passed as the first argument for both 'boxplot' and 'compFn', and so
#' must work in both contexts. NOTE: Any more complicated formula may produce
#' errors or unanticipated results.
#' @param data A data.frame for evaluating 'formula'.
#' @param horizontal TRUE for horizontal boxplots and vertical multcompTs and /
#' or multcompLetters; FALSE for the opposite.
#' @param compFn a function whose output will serve as the the only non-default
#' input to either 'multcompTs' or 'multcompLetters'. The default "TukeyHSD"
#' actually translates to 'TukeyHSD(aov(formula, data))[[1]][, "p adj"]'.
#' @param sortFn If sortFn is a function or a character string naming a
#' function, it is used to summarize the subset of y corresponding to each
#' level of z into a single number, which will then be used to sort the levels
#' of z according to the argument 'decreasing'. This step is skipped if
#' sortFn is NULL or NA or if it is neither a function nor a character string
#' that might name a function. If sortFn is a character string but a function
#' by that name is not found in the search path, multcompBoxplot stops with,
#' 'Error in do.call(sortFn, list(x = x)) : could not find function ...'.
#' @param decreasing If the levels of z are to be sorted using the output of
#' 'sortFn', this is uses as the 'decreasing' in 'order' to sort the levels of
#' z for plotting.
#' @param plotList A list with names in c("boxplot", "multcompTs",
#' "multcompLetters"). Replicates are allowed. If present, they produce,
#' e.g., multiple "multcompTs" side by side. This can be used to compare the
#' visual effects of different arguments to "plot.multcompTs". Each component
#' of 'plotList' is itself a list of arguments to pass to either "boxplot",
#' "plot.multcompTs" or "plot.multcompLetters". Placement can be controlled
#' via 'fig' arguments passed (indirectly) of the form 'c(x1, x2, y1, y2)'.
#' If(horizontal==TRUE), fig gives the coordinates of the figure region in the
#' display region of the plot device, as described on the \code{\link{par}}
#' help page; if(horizontal==FALSE), fig[c(3,4,1,2)] gives c(x1, x2, y1, y2)
#' for placement of that portion of the plot.
#' @return This function invisibly returns a list with one component for each
#' component of plotList containing the output of the appropriate
#' "plot.multcomp" call plus the output of "compFn".
#' @author Spencer Graves
#' @seealso \code{\link{boxplot}} \code{\link{multcompTs}}
#' \code{\link{multcompLetters}} \code{\link{plot.multcomp}}
#' \code{\link{TukeyHSD}} \code{\link{par}} \code{\link[grid]{gpar}}
#' @keywords aplot
#' @importFrom stats TukeyHSD aov model.frame terms
#' @importFrom graphics plot
#' @examples
#'
#' # Example from help("TukeyHSD")
#' multcompBoxplot(breaks~tension, data=warpbreaks)
#' # 'sortFn' can be either a function or a function name
#' # default order is 'decreasing=TRUE'
#' multcompBoxplot(breaks~tension, data=warpbreaks,
#' sortFn=median, decreasing=FALSE)
#'
#' ##################
#' library(multcomp)
#' data(recovery)
#' # Horizontal boxplots with both
#' # multcomp Ts and Letters on the right
#' # Using recovery{multcomp} data set
#' multcompBoxplot(minutes~blanket, recovery)
#'
#' # Plotting boxes rather than letters and Ts
#'
#' multcompBoxplot(minutes~blanket, recovery,
#' plotList=list(
#' boxplot=list(fig=c(0, 0.75, 0, 1), las=1,
#' cex.axis=1.5),
#' multcompTs=list(fig=c(0.7, 0.85, 0, 1),
#' type='boxes'),
#' multcompLetters=list(
#' fig=c(0.87, 0.97, 0.03, 0.98),
#' type='boxes') ) )
#'
#' ####################
#'
#' # Vertical boxplots with both
#' # multcomp Ts and Letters on the top
#' multcompBoxplot(minutes~blanket, recovery,
#' horizontal=FALSE)
#'
#' # Horizontal boxplots with 2 different
#' # displays of the "Ts" on the left
#' multcompBoxplot(minutes~blanket, recovery,
#' plotList=list(
#' boxplot=list(fig=c(0.3, 1, 0, 1)),
#' multcompTs=list(fig=c(0, 0.15, 0, 1),
#' orientation="reverse"),
#' multcompTs=list(fig=c(0.15, 0.3, 0, 1),
#' type="boxes", orientation="reverse",
#' mar=c(5,2, 4, 0)+.1) ) )
#'
#' library(MASS)
#' anorx <-
#' multcompBoxplot(Postwt~Treat, data=anorexia)
#'
#' \dontrun{
#' # Confirm than sortFn=NULL or NA
#' # leaves the order unchanged
#' library(multcomp)
#' data(cholesterol)
#' cholesterol$trt3 <- with(cholesterol, factor(
#' as.character(trt), levels=levels(trt)[c(5:4,1:3)]))
#' multcompBoxplot(response ~ trt3, cholesterol,
#' sortFn=NULL)
#' multcompBoxplot(response ~ trt3, cholesterol,
#' sortFn=NA)
#' }
#'
#' @export
"multcompBoxplot" <-
function(formula, data, horizontal=TRUE,
compFn="TukeyHSD", sortFn="mean",
decreasing=TRUE, plotList=list(
boxplot=list(fig=c(0, 0.75, 0, 1)),
multcompTs=list(fig=c(0.7, 0.85, 0, 1)),
multcompLetters=list(fig=c(0.87, 0.97, 0.03, 0.98),
fontsize=20, fontface="bold"))){
##
## 1. if(!horizontal)swap plotList$...$fig...
##
n.mc <- length(plotList)
if(!horizontal)
for(i in 1:n.mc)
if("fig" %in% names(plotList[[i]]))
plotList[[i]]$fig <-
plotList[[i]]$fig[c(3,4,1,2)]
##
## 2. Sort the levels of 'z' in the formula
##
if(!is.null(sortFn) && (is.function(sortFn) ||
((!is.na(sortFn)) && is.character(sortFn)))){
fm <- as.character(formula)
data <- data[, fm[-1]]
y.z <- tapply(data[, fm[2]], data[, fm[3]],
function(x)do.call(sortFn, list(x=x)))
oz <- order(y.z, decreasing=decreasing)
data[, fm[3]] <- factor(data[, fm[3]],
levels=names(y.z)[oz])
}
##
## 3. Create the desired boxplots
##
bpArgs <- plotList$boxplot
if("fig" %in% names(bpArgs)){
op <- par(fig=bpArgs$fig)
on.exit(par(op))
bpArgs$fig <- NULL
}
#
bpArgNames <- names(bpArgs)
nArgs.bp <- length(bpArgNames)
bpArg <- vector(3+nArgs.bp, mode="list")
names(bpArg) <- c("formula", "data",
"horizontal", bpArgNames)
bpArg[[1]] <- formula
bpArg[[2]] <- data
bpArg[[3]] <- horizontal
if(nArgs.bp>0)for(i in 1:nArgs.bp)
bpArg[[3+i]] <- bpArgs[[i]]
bp <- do.call("boxplot", bpArg)
# Create list "out" and save this.
out <- vector(n.mc+1, mode="list")
plotNames <- names(plotList)
names(out) <- c(plotNames[1], "compFn", plotNames[-1])
out[[1]] <- bp
par(op)
##
## 4. Call "compFn" for the other portions of the
## display.
##
Fn <- compFn
if(compFn=="TukeyHSD"){
TukeyHSD. <- function(formula, data){
TukeyHSD(aov(formula, data))[[1]][, "p adj"]
}
Fn <- "TukeyHSD."
}
if (compFn == "kruskalmc"){
kruskalmc. <- function(formula, data){
extract_p(pgirmess::kruskalmc(resp = formula, data = data))
}
Fn <- "kruskalmc."
}
fnValue <- do.call(Fn,
list(formula=formula, data=data))
Fn.v0 <- vec2mat(fnValue)
Lvls <- bp$names
if(horizontal)Lvls <- rev(Lvls)
FnValue <- Fn.v0[Lvls, Lvls]
out[["compFn"]] <- fnValue
##
## 5. Process the remaining components of plotList
##
if(n.mc>1){
mar2 <- (horizontal*c(5, 0, 4, 0)+
(!horizontal)*c(0, 4, 0, 2)+0.1)
mcNames <- plotNames[-1]
# plotNms <- paste("plot", mcNames, sep=".")
if("multcompTs" %in% mcNames)
mcTs <- multcompTs(FnValue)
if("multcompLetters" %in% mcNames)
mcLtrs <- multcompLetters(FnValue)
# Create the desired multcompViews
for(i in 1:(n.mc-1)){
pL.i <- plotList[[i+1]]
{
if("mar" %in% names(pL.i)){
mar <- pL.i$mar
pL.i$mar <- NULL
}
else
mar <- mar2
}
op.i <- par(mar=mar)
on.exit(par(op.i))
names.i <- names(pL.i)
nm.i <- length(names.i)
args.i <- vector(3+nm.i, mode="list")
names(args.i) <- c("x", "horizontal",
"add", names.i)
args.i[[1]] <- {
if(mcNames[i]=="multcompTs")
mcTs else mcLtrs
}
args.i[[2]] <- !horizontal
args.i[[3]] <- TRUE
if(nm.i>0)for(ji in 1:nm.i)
args.i[[3+ji]] <- pL.i[[ji]]
out[[2+i]] <- do.call(plot, args.i)
par(op.i)
}
}
invisible(out)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.