% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/fmodel_compare.R
\name{f_model_compare}
\alias{f_model_compare}
\title{Compare Two Statistical Models}
\usage{
f_model_compare(
  model1,
  model2,
  nested = NULL,
  model1_name = NULL,
  model2_name = NULL,
  digits = 3
)
}
\arguments{
\item{model1}{The first model object. Supported classes include: \code{"lm", "glm", "aov", "lmerMod", "glmerMod", and "nls"}.}

\item{model2}{The second model object. Supported classes include: \code{"lm", "glm", "aov", "lmerMod", "glmerMod", and "nls"}.}

\item{nested}{Logical. If \code{TRUE}, assumes the models are nested and performs an ANOVA comparison.
If \code{NULL} (default), the function attempts to automatically determine if the models are nested.}

\item{model1_name}{Optional character string. A custom name for model1 in the output. If \code{NULL} (default),
the function uses \code{deparse(substitute(model1))}.}

\item{model2_name}{Optional character string. A custom name for model2 in the output. If \code{NULL} (default),
the function uses \code{deparse(substitute(model2))}.}

\item{digits}{Integer. The number of decimal places to round the output metrics. Defaults to \code{3}.}
}
\value{
A list of class "f_model_comparison" containing:
  \item{model1_name}{The name of the first model (always the simpler model when nested).}
  \item{model2_name}{The name of the second model (always the more complex model when nested).}
  \item{model1_class}{The class of the first model.}
  \item{model2_class}{The class of the second model.}
  \item{metrics_table}{A data frame summarizing metrics for both models, their differences, and (if applicable) the ANOVA p-value.}
  \item{formatted_metrics_table}{A formatted version of the metrics table for printing.}
  \item{anova_comparison}{The ANOVA comparison results if the models are nested and an ANOVA test was performed.}
  \item{nested}{Logical indicating whether the models were treated as nested.}
  \item{swapped}{Logical indicating whether the model order was swapped to ensure model1 is the simpler model.}
}
\description{
Compares two statistical models by calculating key metrics such as AIC, BIC, log-likelihood, \eqn{R^2},
and others. Supports comparison of nested models using ANOVA tests.
}
\details{
Calculate various metrics to assess model fit:
  \itemize{
    \item \bold{AIC/BIC:} Lower values indicate better fit.
    \item \bold{Log-Likelihood:} Higher values (less negative) indicate better fit.
    \item \bold{\eqn{R^2}:} Proportion of variance explained by the model.
    \item \bold{Adjusted \eqn{R^2}:} \eqn{R^2} penalized for the number of parameters (for linear models).
    \item \bold{Nagelkerke \eqn{R^2}:} A pseudo-\eqn{R^2} for generalized linear models (GLMs).
    \item \bold{Marginal/Conditional \eqn{R^2}:} For mixed models, marginal \eqn{R^2} reflects fixed effects, while conditional \eqn{R^2} includes random effects.
    \item \bold{Sigma:} Residual standard error.
    \item \bold{Deviance:} Model deviance.
    \item \bold{SSE:} Sum of squared errors.
    \item \bold{Parameters (df):} Number of model parameters.
    \item \bold{Residual df:} Residual degrees of freedom.
  }

When nested models are detected or specified, model1 is always treated as the simpler
model (fewer parameters). If the user passes the complex model first, the function
automatically swaps them and issues a message.

If the models are nested, an ANOVA test is performed to compare them, and a p-value
is provided to assess whether the more complex model significantly improves fit.
}
\note{
\itemize{
    \item The function supports a variety of model types but may issue warnings if unsupported or partially supported classes are used.
    \item For GLMs, Nagelkerke's \eqn{R^2} is used as a pseudo-\eqn{R^2} approximation, computed
      from the model's null deviance to avoid refitting a null model.
    \item For mixed models, the function relies on the 'r.squaredGLMM' function from the 'MuMIn' package for \eqn{R^2} calculation.
    \item For NLS models, \eqn{R^2} is provided for convenience but should be interpreted with caution
      as it does not have the same statistical properties as in linear models.
    \item The idea of this function (not the code), I got from Dustin Fife's function \href{https://github.com/dustinfife/flexplot/blob/master/R/model.comparison.R}{'model.comparison'} in the super cool \href{https://github.com/dustinfife/flexplot/}{'flexplot package'}.
  }
}
\section{Supported Model Classes}{

The function supports the following model classes:
  \itemize{
    \item Linear models ("lm")
    \item Generalized linear models ("glm")
    \item Analysis of variance models ("aov")
    \item Linear mixed models ("lmerMod")
    \item Generalized linear mixed models ("glmerMod")
    \item Nonlinear least squares models ("nls")
  }

Note: Multi-stratum AOV models (fitted with \code{Error()}) are not supported
and will produce a warning.
}

\examples{
# Example with linear models.
model1 <- lm(mpg ~ wt, data = mtcars)
model2 <- lm(mpg ~ wt + hp, data = mtcars)
comparison <- f_model_compare(model1, model2)
print(comparison)

# Example with GLMs.
\donttest{
model1 <- glm(am ~ wt, data = mtcars, family = binomial)
model2 <- glm(am ~ wt + hp, data = mtcars, family = binomial)
comparison <- f_model_compare(model1, model2)
print(comparison)
}

# Models can be passed in any order - the function auto-swaps if needed.
complex <- lm(mpg ~ wt + hp + qsec, data = mtcars)
simple  <- lm(mpg ~ wt, data = mtcars)
comparison <- f_model_compare(complex, simple)
# model1 will be "simple", model2 will be "complex" in the output

# Example with custom model names (useful when calling from wrapper functions).
comparison <- f_model_compare(model1, model2,
                              model1_name = "Weight only",
                              model2_name = "Weight + Horsepower")
print(comparison)

}
\seealso{
\code{\link{AIC}}, \code{\link{BIC}}, \code{\link{anova}}, \code{\link{logLik}}, \code{\link[MuMIn]{r.squaredGLMM}}
}
\author{
Sander H. van Delden  \email{plantmind@proton.me} \cr
}
