# This file is automatically generated, you probably don't want to edit this
anovaOptions <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
"anovaOptions",
inherit = jmvcore::Options,
public = list(
initialize = function(
dep = NULL,
factors = NULL,
effectSize = NULL,
modelTest = FALSE,
modelTerms = NULL,
ss = "3",
homo = FALSE,
norm = FALSE,
qq = FALSE,
contrasts = NULL,
postHoc = NULL,
postHocCorr = list(
"tukey"),
postHocES = list(),
postHocEsCi = FALSE,
postHocEsCiWidth = 95,
emMeans = list(
list()),
emmPlots = TRUE,
emmPlotData = FALSE,
emmPlotError = "ci",
emmTables = FALSE,
emmWeights = TRUE,
ciWidthEmm = 95, ...) {
super$initialize(
package="jmv",
name="anova",
requiresData=TRUE,
...)
private$..dep <- jmvcore::OptionVariable$new(
"dep",
dep,
required=TRUE,
suggested=list(
"continuous"),
permitted=list(
"numeric"))
private$..factors <- jmvcore::OptionVariables$new(
"factors",
factors,
required=TRUE,
rejectUnusedLevels=TRUE,
suggested=list(
"nominal",
"ordinal"),
permitted=list(
"factor"),
default=NULL)
private$..effectSize <- jmvcore::OptionNMXList$new(
"effectSize",
effectSize,
options=list(
"eta",
"partEta",
"omega"),
default=NULL)
private$..modelTest <- jmvcore::OptionBool$new(
"modelTest",
modelTest,
default=FALSE)
private$..modelTerms <- jmvcore::OptionTerms$new(
"modelTerms",
modelTerms,
default=NULL)
private$..ss <- jmvcore::OptionList$new(
"ss",
ss,
options=list(
"1",
"2",
"3"),
default="3")
private$..homo <- jmvcore::OptionBool$new(
"homo",
homo,
default=FALSE)
private$..norm <- jmvcore::OptionBool$new(
"norm",
norm,
default=FALSE)
private$..qq <- jmvcore::OptionBool$new(
"qq",
qq,
default=FALSE)
private$..contrasts <- jmvcore::OptionArray$new(
"contrasts",
contrasts,
items="(factors)",
default=NULL,
template=jmvcore::OptionGroup$new(
"contrasts",
NULL,
elements=list(
jmvcore::OptionVariable$new(
"var",
NULL,
content="$key"),
jmvcore::OptionList$new(
"type",
NULL,
options=list(
"none",
"deviation",
"simple",
"difference",
"helmert",
"repeated",
"polynomial")))))
private$..postHoc <- jmvcore::OptionTerms$new(
"postHoc",
postHoc,
default=NULL)
private$..postHocCorr <- jmvcore::OptionNMXList$new(
"postHocCorr",
postHocCorr,
options=list(
"none",
"tukey",
"scheffe",
"bonf",
"holm"),
default=list(
"tukey"))
private$..postHocES <- jmvcore::OptionNMXList$new(
"postHocES",
postHocES,
options=list(
"d"),
default=list())
private$..postHocEsCi <- jmvcore::OptionBool$new(
"postHocEsCi",
postHocEsCi,
default=FALSE)
private$..postHocEsCiWidth <- jmvcore::OptionNumber$new(
"postHocEsCiWidth",
postHocEsCiWidth,
min=50,
max=99.9,
default=95)
private$..emMeans <- jmvcore::OptionArray$new(
"emMeans",
emMeans,
default=list(
list()),
template=jmvcore::OptionVariables$new(
"emMeans",
NULL))
private$..emmPlots <- jmvcore::OptionBool$new(
"emmPlots",
emmPlots,
default=TRUE)
private$..emmPlotData <- jmvcore::OptionBool$new(
"emmPlotData",
emmPlotData,
default=FALSE)
private$..emmPlotError <- jmvcore::OptionList$new(
"emmPlotError",
emmPlotError,
options=list(
"none",
"ci",
"se"),
default="ci")
private$..emmTables <- jmvcore::OptionBool$new(
"emmTables",
emmTables,
default=FALSE)
private$..emmWeights <- jmvcore::OptionBool$new(
"emmWeights",
emmWeights,
default=TRUE)
private$..ciWidthEmm <- jmvcore::OptionNumber$new(
"ciWidthEmm",
ciWidthEmm,
min=50,
max=99.9,
default=95)
private$..residsOV <- jmvcore::OptionOutput$new(
"residsOV")
self$.addOption(private$..dep)
self$.addOption(private$..factors)
self$.addOption(private$..effectSize)
self$.addOption(private$..modelTest)
self$.addOption(private$..modelTerms)
self$.addOption(private$..ss)
self$.addOption(private$..homo)
self$.addOption(private$..norm)
self$.addOption(private$..qq)
self$.addOption(private$..contrasts)
self$.addOption(private$..postHoc)
self$.addOption(private$..postHocCorr)
self$.addOption(private$..postHocES)
self$.addOption(private$..postHocEsCi)
self$.addOption(private$..postHocEsCiWidth)
self$.addOption(private$..emMeans)
self$.addOption(private$..emmPlots)
self$.addOption(private$..emmPlotData)
self$.addOption(private$..emmPlotError)
self$.addOption(private$..emmTables)
self$.addOption(private$..emmWeights)
self$.addOption(private$..ciWidthEmm)
self$.addOption(private$..residsOV)
}),
active = list(
dep = function() private$..dep$value,
factors = function() private$..factors$value,
effectSize = function() private$..effectSize$value,
modelTest = function() private$..modelTest$value,
modelTerms = function() private$..modelTerms$value,
ss = function() private$..ss$value,
homo = function() private$..homo$value,
norm = function() private$..norm$value,
qq = function() private$..qq$value,
contrasts = function() private$..contrasts$value,
postHoc = function() private$..postHoc$value,
postHocCorr = function() private$..postHocCorr$value,
postHocES = function() private$..postHocES$value,
postHocEsCi = function() private$..postHocEsCi$value,
postHocEsCiWidth = function() private$..postHocEsCiWidth$value,
emMeans = function() private$..emMeans$value,
emmPlots = function() private$..emmPlots$value,
emmPlotData = function() private$..emmPlotData$value,
emmPlotError = function() private$..emmPlotError$value,
emmTables = function() private$..emmTables$value,
emmWeights = function() private$..emmWeights$value,
ciWidthEmm = function() private$..ciWidthEmm$value,
residsOV = function() private$..residsOV$value),
private = list(
..dep = NA,
..factors = NA,
..effectSize = NA,
..modelTest = NA,
..modelTerms = NA,
..ss = NA,
..homo = NA,
..norm = NA,
..qq = NA,
..contrasts = NA,
..postHoc = NA,
..postHocCorr = NA,
..postHocES = NA,
..postHocEsCi = NA,
..postHocEsCiWidth = NA,
..emMeans = NA,
..emmPlots = NA,
..emmPlotData = NA,
..emmPlotError = NA,
..emmTables = NA,
..emmWeights = NA,
..ciWidthEmm = NA,
..residsOV = NA)
)
anovaResults <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
"anovaResults",
inherit = jmvcore::Group,
active = list(
main = function() private$.items[["main"]],
model = function() private$..model,
assump = function() private$.items[["assump"]],
contrasts = function() private$.items[["contrasts"]],
postHoc = function() private$.items[["postHoc"]],
emm = function() private$.items[["emm"]],
residsOV = function() private$.items[["residsOV"]]),
private = list(
..model = NA),
public=list(
initialize=function(options) {
super$initialize(
options=options,
name="",
title="ANOVA")
self$add(jmvcore::Table$new(
options=options,
name="main",
title="`ANOVA - ${dep}`",
columns=list()))
private$..model <- NULL
self$add(R6::R6Class(
inherit = jmvcore::Group,
active = list(
homo = function() private$.items[["homo"]],
norm = function() private$.items[["norm"]],
qq = function() private$.items[["qq"]]),
private = list(),
public=list(
initialize=function(options) {
super$initialize(
options=options,
name="assump",
title="Assumption Checks")
self$add(jmvcore::Table$new(
options=options,
name="homo",
title="Homogeneity of Variances Test (Levene's)",
columns=list()))
self$add(jmvcore::Table$new(
options=options,
name="norm",
title="Normality Test (Shapiro-Wilk)",
visible="(norm)",
rows=1,
columns=list()))
self$add(jmvcore::Image$new(
options=options,
name="qq",
title="Q-Q Plot"))}))$new(options=options))
self$add(jmvcore::Array$new(
options=options,
name="contrasts",
title="Contrasts",
template=jmvcore::Table$new(
options=options,
title="Contrasts - $key",
columns=list())))
self$add(jmvcore::Array$new(
options=options,
name="postHoc",
title="Post Hoc Tests",
template=jmvcore::Table$new(
options=options,
title="",
columns=list())))
self$add(jmvcore::Array$new(
options=options,
name="emm",
title="Estimated Marginal Means",
clearWith=list(
"dep",
"blocks",
"emMeans"),
template=R6::R6Class(
inherit = jmvcore::Group,
active = list(
emmPlot = function() private$.items[["emmPlot"]],
emmTable = function() private$.items[["emmTable"]]),
private = list(),
public=list(
initialize=function(options) {
super$initialize(
options=options,
name="undefined",
title="")
self$add(jmvcore::Image$new(
options=options,
name="emmPlot",
title="",
width=450,
height=400,
renderFun=".emmPlot",
visible="(emmPlots)",
clearWith=list(
"dep",
"blocks",
"refLevels",
"ciWidthEmm",
"emmWeights",
"emmPlotData",
"emmPlotError")))
self$add(jmvcore::Table$new(
options=options,
name="emmTable",
title="",
visible="(emmTables)",
columns=list(),
clearWith=list(
"dep",
"blocks",
"refLevels",
"ciWidthEmm",
"emmWeights")))}))$new(options=options)))
self$add(jmvcore::Output$new(
options=options,
name="residsOV",
title="Residuals",
varTitle="Residuals",
varDescription="Residuals from ANOVA",
measureType="continuous",
clearWith=list(
"dep",
"factors",
"modelTerms")))},
.setModel=function(x) private$..model <- x))
anovaBase <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
"anovaBase",
inherit = jmvcore::Analysis,
public = list(
initialize = function(options, data=NULL, datasetId="", analysisId="", revision=0) {
super$initialize(
package = "jmv",
name = "anova",
version = c(2,0,0),
options = options,
results = anovaResults$new(options=options),
data = data,
datasetId = datasetId,
analysisId = analysisId,
revision = revision,
pause = NULL,
completeWhenFilled = TRUE,
requiresMissings = FALSE,
weightsSupport = 'none')
}))
#' ANOVA
#'
#' The Analysis of Variance (ANOVA) is used to explore the relationship
#' between a continuous dependent variable, and one or more categorical
#' explanatory variables.
#'
#' ANOVA assumes that the residuals are normally distributed, and that the
#' variances of all groups are equal. If one is unwilling to assume that
#' the variances are equal, then a Welch's test can be used instead
#' (However, the Welch's test does not support more than one explanatory
#' factor). Alternatively, if one is unwilling to assume that the data is
#' normally distributed, a non-parametric approach (such as Kruskal-Wallis)
#' can be used.
#'
#'
#' @examples
#' data('ToothGrowth')
#'
#' ANOVA(formula = len ~ dose * supp, data = ToothGrowth)
#'
#' #
#' # ANOVA
#' #
#' # ANOVA
#' # -----------------------------------------------------------------------
#' # Sum of Squares df Mean Square F p
#' # -----------------------------------------------------------------------
#' # dose 2426 2 1213.2 92.00 < .001
#' # supp 205 1 205.4 15.57 < .001
#' # dose:supp 108 2 54.2 4.11 0.022
#' # Residuals 712 54 13.2
#' # -----------------------------------------------------------------------
#' #
#'
#' ANOVA(
#' formula = len ~ dose * supp,
#' data = ToothGrowth,
#' emMeans = ~ supp + dose:supp, # est. marginal means for supp and dose:supp
#' emmPlots = TRUE, # produce plots of those marginal means
#' emmTables = TRUE) # produce tables of those marginal means
#'
#' @param data the data as a data frame
#' @param dep the dependent variable from \code{data}, variable must be
#' numeric (not necessary when providing a formula, see examples)
#' @param factors the explanatory factors in \code{data} (not necessary when
#' providing a formula, see examples)
#' @param effectSize one or more of \code{'eta'}, \code{'partEta'}, or
#' \code{'omega'}; use eta², partial eta², and omega² effect sizes,
#' respectively
#' @param modelTest \code{TRUE} or \code{FALSE} (default); perform an overall
#' model test
#' @param modelTerms a formula describing the terms to go into the model (not
#' necessary when providing a formula, see examples)
#' @param ss \code{'1'}, \code{'2'} or \code{'3'} (default), the sum of
#' squares to use
#' @param homo \code{TRUE} or \code{FALSE} (default), perform homogeneity
#' tests
#' @param norm \code{TRUE} or \code{FALSE} (default), perform Shapiro-Wilk
#' tests of normality
#' @param qq \code{TRUE} or \code{FALSE} (default), provide a Q-Q plot of
#' residuals
#' @param contrasts a list of lists specifying the factor and type of contrast
#' to use, one of \code{'deviation'}, \code{'simple'}, \code{'difference'},
#' \code{'helmert'}, \code{'repeated'} or \code{'polynomial'}
#' @param postHoc a formula containing the terms to perform post-hoc tests on
#' (see the examples)
#' @param postHocCorr one or more of \code{'none'}, \code{'tukey'},
#' \code{'scheffe'}, \code{'bonf'}, or \code{'holm'}; provide no, Tukey,
#' Scheffe, Bonferroni, and Holm Post Hoc corrections respectively
#' @param postHocES a possible value of \code{'d'}; provide cohen's d measure
#' of effect size for the post-hoc tests
#' @param postHocEsCi \code{TRUE} or \code{FALSE} (default), provide
#' confidence intervals for the post-hoc effect sizes
#' @param postHocEsCiWidth a number between 50 and 99.9 (default: 95), the
#' width of confidence intervals for the post-hoc effect sizes
#' @param emMeans a formula containing the terms to estimate marginal means
#' for (see the examples)
#' @param emmPlots \code{TRUE} (default) or \code{FALSE}, provide estimated
#' marginal means plots
#' @param emmPlotData \code{TRUE} or \code{FALSE} (default), plot the data on
#' top of the marginal means
#' @param emmPlotError \code{'none'}, \code{'ci'} (default), or \code{'se'}.
#' Use no error bars, use confidence intervals, or use standard errors on the
#' marginal mean plots, respectively
#' @param emmTables \code{TRUE} or \code{FALSE} (default), provide estimated
#' marginal means tables
#' @param emmWeights \code{TRUE} (default) or \code{FALSE}, weigh each cell
#' equally or weigh them according to the cell frequency
#' @param ciWidthEmm a number between 50 and 99.9 (default: 95) specifying the
#' confidence interval width for the estimated marginal means
#' @param formula (optional) the formula to use, see the examples
#' @return A results object containing:
#' \tabular{llllll}{
#' \code{results$main} \tab \tab \tab \tab \tab a table of ANOVA results \cr
#' \code{results$model} \tab \tab \tab \tab \tab The underlying \code{aov} object \cr
#' \code{results$assump$homo} \tab \tab \tab \tab \tab a table of homogeneity tests \cr
#' \code{results$assump$norm} \tab \tab \tab \tab \tab a table of normality tests \cr
#' \code{results$assump$qq} \tab \tab \tab \tab \tab a q-q plot \cr
#' \code{results$contrasts} \tab \tab \tab \tab \tab an array of contrasts tables \cr
#' \code{results$postHoc} \tab \tab \tab \tab \tab an array of post-hoc tables \cr
#' \code{results$emm} \tab \tab \tab \tab \tab an array of the estimated marginal means plots + tables \cr
#' \code{results$residsOV} \tab \tab \tab \tab \tab an output \cr
#' }
#'
#' Tables can be converted to data frames with \code{asDF} or \code{\link{as.data.frame}}. For example:
#'
#' \code{results$main$asDF}
#'
#' \code{as.data.frame(results$main)}
#'
#' @export
ANOVA <- function(
data,
dep,
factors = NULL,
effectSize = NULL,
modelTest = FALSE,
modelTerms = NULL,
ss = "3",
homo = FALSE,
norm = FALSE,
qq = FALSE,
contrasts = NULL,
postHoc = NULL,
postHocCorr = list(
"tukey"),
postHocES = list(),
postHocEsCi = FALSE,
postHocEsCiWidth = 95,
emMeans = list(
list()),
emmPlots = TRUE,
emmPlotData = FALSE,
emmPlotError = "ci",
emmTables = FALSE,
emmWeights = TRUE,
ciWidthEmm = 95,
formula) {
if ( ! requireNamespace("jmvcore", quietly=TRUE))
stop("ANOVA requires jmvcore to be installed (restart may be required)")
if ( ! missing(formula)) {
if (missing(dep))
dep <- jmvcore::marshalFormula(
formula=formula,
data=`if`( ! missing(data), data, NULL),
from="lhs",
subset="1",
required=TRUE)
if (missing(factors))
factors <- jmvcore::marshalFormula(
formula=formula,
data=`if`( ! missing(data), data, NULL),
from="rhs",
type="vars")
if (missing(modelTerms))
modelTerms <- jmvcore::marshalFormula(
formula=formula,
data=`if`( ! missing(data), data, NULL),
from="rhs",
type="terms")
}
if ( ! missing(dep)) dep <- jmvcore::resolveQuo(jmvcore::enquo(dep))
if ( ! missing(factors)) factors <- jmvcore::resolveQuo(jmvcore::enquo(factors))
if (missing(data))
data <- jmvcore::marshalData(
parent.frame(),
`if`( ! missing(dep), dep, NULL),
`if`( ! missing(factors), factors, NULL))
for (v in factors) if (v %in% names(data)) data[[v]] <- as.factor(data[[v]])
if (inherits(modelTerms, "formula")) modelTerms <- jmvcore::decomposeFormula(modelTerms)
if (inherits(postHoc, "formula")) postHoc <- jmvcore::decomposeFormula(postHoc)
if (inherits(emMeans, "formula")) emMeans <- jmvcore::decomposeFormula(emMeans)
options <- anovaOptions$new(
dep = dep,
factors = factors,
effectSize = effectSize,
modelTest = modelTest,
modelTerms = modelTerms,
ss = ss,
homo = homo,
norm = norm,
qq = qq,
contrasts = contrasts,
postHoc = postHoc,
postHocCorr = postHocCorr,
postHocES = postHocES,
postHocEsCi = postHocEsCi,
postHocEsCiWidth = postHocEsCiWidth,
emMeans = emMeans,
emmPlots = emmPlots,
emmPlotData = emmPlotData,
emmPlotError = emmPlotError,
emmTables = emmTables,
emmWeights = emmWeights,
ciWidthEmm = ciWidthEmm)
analysis <- anovaClass$new(
options = options,
data = data)
analysis$run()
analysis$results
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.