% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/faov.R
\name{f_aov}
\alias{f_aov}
\title{Perform multiple \code{aov()} functions with optional data transformation, inspection and Post Hoc test.}
\usage{
f_aov(
  formula,
  data = NULL,
  norm_plots = TRUE,
  interaction_plots = TRUE,
  ANCOVA = FALSE,
  transformation = TRUE,
  force_transformation = NULL,
  force_aov = FALSE,
  alpha = 0.05,
  adjust = "sidak",
  intro_text = TRUE,
  close_generated_files = FALSE,
  open_generated_files = interactive(),
  output_type = "default",
  save_as = NULL,
  save_in_wdir = FALSE,
  ...
)
}
\arguments{
\item{formula}{A formula specifying the model to be fitted. More response variables can be added using \code{-} or \code{+} (e.g., \code{response1 + response2 ~ predictor}) to do a sequential \code{aov()} for each response parameter.}

\item{data}{A data frame containing the variables in the model.}

\item{norm_plots}{Logical. If \code{TRUE}, diagnostic residual plots are included in the output files. Default is \code{TRUE}.}

\item{interaction_plots}{Logical. If \code{TRUE}, estimated means / interaction plots are included in the output files after the post hoc table. Default is \code{TRUE}.}

\item{ANCOVA}{Logical. If \code{TRUE}, prevents automatic conversion of predictors to factors, allowing for Analysis of Covariance (ANCOVA). Default is \code{FALSE}.}

\item{transformation}{Logical or character string. If \code{TRUE}, or if \code{"boxcox"} applies a \code{f_boxcox()} transformation if residuals are not normal. If \code{"bestnormalize"}, applies \code{f_bestNormalize()} transformation. If \code{FALSE} no transformation will be applied. Default is \code{TRUE}.}

\item{force_transformation}{Character string. A vector containing the names of response variables that should be transformed regardless of the normality test. Default is \code{NULL}}

\item{force_aov}{Logical. If \code{TRUE}, runs the ANOVA even when at least
one cell has \eqn{n = 1} (saturated model). By default (\code{FALSE}),
such responses are skipped with a warning because F-statistics and
p-values are undefined for saturated models. Set to \code{TRUE} only for
diagnostic purposes -- results should \strong{not} be reported or
interpreted as valid. Default is \code{FALSE}.}

\item{alpha}{Numeric. Significance level for ANOVA, post hoc tests, and Shapiro-Wilk test. Default is \code{0.05}.}

\item{adjust}{Character string specifying the method used to adjust p-values
for multiple comparisons. Available methods include:
\describe{
  \item{"tukey"}{Tukey's Honest Significant Difference method, appropriate for
                all pairwise comparisons. Controls family-wise error rate.}
  \item{"sidak"}{Sidak correction that controls the family-wise error rate.
                Less conservative than Bonferroni.}
  \item{"bonferroni"}{Conservative adjustment that multiplies p-values by
                     the number of comparisons.}
  \item{"none"}{No adjustment. Equivalent to Fisher's LSD method.}
  \item{"fdr"}{False Discovery Rate adjustment, controls the expected proportion
              of false positives among significant results.}
} Default is \code{"sidak"}.}

\item{intro_text}{Logical. If \code{TRUE}, includes a short explanation about ANOVA assumptions in the output file. Default is \code{TRUE}.}

\item{close_generated_files}{Logical. Closes open Excel or Word (NOT pdf) files before writing, depending on the output format. Works on Windows (taskkill), macOS (pkill) and Linux (pkill/soffice). Default \code{FALSE}. \strong{WARNING:} Always save your work before using this option!!}

\item{open_generated_files}{Logical. Whether to open the generated output
files after creation. Defaults to \code{TRUE} in an interactive R session
and \code{FALSE} otherwise (e.g. in scripts or automated pipelines).
Set to \code{TRUE} or \code{FALSE} to override this behaviour explicitly.}

\item{output_type}{Character string specifying the output format. Default is \code{"default"}.
\itemize{
  \item \code{"default"}: Returns the object and lets R decide whether
    to print; auto-prints if unassigned, silent if assigned to a variable.
    Use \code{print(result)} or \code{plot(result)} to display the
    returned object.
  \item \code{"console"}: Forces immediate printing to the console
    regardless of object assignment.
  \item \code{"pdf"}, \code{"word"}, \code{"excel"}: Saves results to a
    file of the corresponding format. See \code{save_as},
    \code{save_in_wdir}, and \code{open_generated_files} for file
    path and opening behavior.
  \item \code{"rmd"}: Stores the raw markdown string inside the returned
    object for use in R Markdown documents.
}}

\item{save_as}{Character string specifying the output file path (without extension).
If a full path is provided, output is saved to that location.
If only a filename is given, the file is saved in \code{tempdir()}.
If only a directory is specified (providing an existing directory with trailing slash),
the file is named "dataname_aov_output" in that directory. If an extension is provided the output format specified with option "output_type" will be overruled.
Defaults to \code{file.path(tempdir(), "dataname_summary.pdf")}.}

\item{save_in_wdir}{Logical. If \code{TRUE}, saves the file in the working directory. Default is \code{FALSE}, this avoid unintended changes to the global environment. If \code{save_as} location is specified \code{save_in_wdir} is overwritten by \code{save_as}.}

\item{...}{Additional arguments forwarded to \code{\link[stats]{aov}}.
The arguments \code{subset}, \code{na.action}, and \code{weights} are
handled specially: when supplied, they are applied via
\code{\link[stats]{model.frame}} so that the n=1 cell check,
Shapiro-Wilk test, Levene test, optional transformations, residual
diagnostics, and \code{emmeans} post hoc tests all see the exact
same row set as \code{aov()} itself. Any other \code{aov()}
arguments (e.g. \code{contrasts}, \code{projections},
\code{qr}, \code{contrasts.arg}) are passed through unchanged.}
}
\value{
An object of class 'f_aov' containing results from \code{aov()}, normality tests, transformations, and post hoc tests. Using the option "output_type", it can also generate output in the form of: R Markdown code, 'Word', 'pdf', or 'Excel' files. Includes print and plot methods for 'f_aov' objects.
}
\description{
Performs an Analysis of Variance (ANOVA) on a given dataset with options for (Box-Cox)
transformations, normality tests, and post hoc analysis. Several response parameters can be analysed in sequence and the generated output can be in various formats ('Word', 'pdf', 'Excel').
}
\details{
The function performs the following steps:
\itemize{
\item Check if all specified variables are present in the data.
\item Ensure that the response variable is numeric.
\item Perform Analysis of Variance (ANOVA) using the specified formula and data.
\item If \code{shapiro = TRUE}, check for normality of residuals using the Shapiro-Wilk test.
\item If residuals are not normal and \code{transformation = TRUE} apply a data transformation.
\item If significant differences are found in ANOVA, proceed with post hoc tests using estimated marginal means from \code{emmeans()} and Sidak adjustment (or another option of \code{adjust =}.
}

More response variables can be added using \code{-} or \code{+} (e.g., \code{response1 + response2 ~ predictor}) to do a sequential \code{aov()} for each response parameter captured in one output file.

Outputs can be generated in multiple formats ("pdf", "word", "excel" and "rmd") as specified by \code{output_type}. The function also closes any open 'Word' files to avoid conflicts when generating 'Word' documents. If \code{output_type = "rmd"} is used it is adviced to use it in a chunk with \{r, echo=FALSE, results='asis'\}

*Non-significant ANOVA results*: When the overall F-test is not significant, f_aov still reports the estimated marginal means table, but with all pairwise comparison letters replaced by *"ns"*. The numeric estimates (and their confidence intervals) are provided because they are often needed for manuscript tables, especially when the response was back-transformed from a Box-Cox or bestNormalize scale - the raw descriptive means and the emmeans values can differ, and it is the emmeans values that correspond to the actual model. The *"ns"* labels signal that pairwise differences should not be interpreted.

This function requires [Pandoc](https://github.com/jgm/pandoc/releases/tag) (version 1.12.3 or higher), a universal document converter.
\itemize{
\item \bold{Windows:} Install Pandoc and ensure the installation folder.
\cr (e.g., "C:/Users/your_username/AppData/Local/Pandoc") is added to your system PATH.
\item \bold{macOS:} If using Homebrew, Pandoc is typically installed in "/usr/local/bin". Alternatively, download the .pkg installer and verify that the binary's location is in your PATH.
\item \bold{Linux:} Install Pandoc through your distribution's package manager (commonly installed in "/usr/bin" or "/usr/local/bin") or manually, and ensure the directory containing Pandoc is in your PATH.

\item If Pandoc is not found, this function may not work as intended.
}
}
\section{Multiple Testing Across Response Variables}{

When several response variables are analysed in a single call
(e.g. \code{y1 + y2 + y3 ~ treatment}), each ANOVA is an independent
null-hypothesis test at level \code{alpha}. The post hoc adjustments
(\code{adjust = "sidak"}, \code{"tukey"}, etc.) only control the
family-wise error rate \strong{within} one ANOVA (across pairwise group
comparisons for that response). They do \strong{not} protect against
the inflation of Type I error \strong{across} the set of responses.

\strong{Practical implication:} With \eqn{k} independent response
variables all tested at \eqn{\alpha = 0.05}, the probability of
obtaining at least one false positive is
\eqn{1 - (1 - 0.05)^k}, which reaches ~40\% for \eqn{k = 10}.

\strong{When this matters:} The risk is highest in exploratory studies
where many responses are screened simultaneously without a clear
a priori hypothesis for each one. It is less of a concern when
each response is a pre-specified primary outcome with its own
biological rationale.

\strong{Possible remedies:}
\itemize{
  \item \strong{Bonferroni correction across responses:} use
    \code{alpha = 0.05 / k} where \code{k} is the number of
    response variables. Conservative but simple.
  \item \strong{False Discovery Rate (FDR):} apply
    \code{p.adjust(p_values, method = "fdr")} to the vector of
    per-response ANOVA p-values after the fact.
  \item \strong{MANOVA:} if the responses are correlated and you
    want a single omnibus test across all of them, use
    \code{manova()} before interpreting individual ANOVAs.
  \item \strong{Pre-registration:} declare primary vs. exploratory
    responses before data collection to justify differential
    correction thresholds.
}
}

\examples{
# Make a factor of Species.
iris$Species <- factor(iris$Species)

# The left hand side contains two response variables,
# so two aov's will be conducted, i.e. "Sepal.Width"
# and "Sepal.Length" in response to the explanatory variable: "Species".
f_aov_out <- f_aov(Sepal.Width + Sepal.Length ~ Species,
                   data = iris,
                   # Save output in MS Word file (Default is console)
                   output_type = "word",
                   # Do bestNormalize transformation for non-normal residual (Default is boxcox)
                   transformation = "bestnormalize"
                   )

# Print output to the console.
print(f_aov_out)

# Plot residual plots.
plot(f_aov_out)

#To print rmd output set chunck option to results = 'asis' and use cat().
f_aov_rmd_out <- f_aov(Sepal.Width ~ Species, data = iris, output_type = "rmd")
cat(f_aov_rmd_out$rmd)

}
\author{
Sander H. van Delden  \email{plantmind@proton.me} \cr
}
