% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/compfit.R
\name{compfit}
\alias{compfit}
\title{Compare Multiple Regression Models}
\usage{
compfit(
  data,
  outcome,
  model_list,
  model_names = NULL,
  interactions_list = NULL,
  random = NULL,
  model_type = "auto",
  family = "binomial",
  conf_level = 0.95,
  p_digits = 3,
  include_coefficients = FALSE,
  scoring_weights = NULL,
  labels = NULL,
  number_format = NULL,
  verbose = NULL,
  ...
)
}
\arguments{
\item{data}{Data frame or data.table containing the dataset.}

\item{outcome}{Character string specifying the outcome variable. For survival
analysis, use \code{Surv()} syntax (\emph{e.g.,} \code{"Surv(time, status)"}).}

\item{model_list}{List of character vectors, each containing predictor names
for one model. Can also be a single character vector to auto-generate nested models.}

\item{model_names}{Character vector of names for each model. If \code{NULL}, uses
"Model 1", "Model 2", \emph{etc.} Default is \code{NULL}.}

\item{interactions_list}{List of character vectors specifying interaction
terms for each model. Each element corresponds to one model in model_list.
Use \code{NULL} for models without interactions. Use colon notation for interactions
(\emph{e.g.,} \code{c("age:treatment")}). If \code{NULL}, no interactions are added to
any model. Default is \code{NULL}.}

\item{random}{Character string specifying the random-effects formula for 
mixed-effects models (\code{glmer}, \code{lmer}, \code{coxme}). Use standard
\code{lme4}/\code{coxme} syntax, \emph{e.g.,} \code{"(1|site)"} for random
intercepts by site. This random effects formula is applied to all models in the
comparison. Alternatively, random effects can be included directly in the predictor 
vectors within \code{model_list} using the same syntax, which allows
different random effects structures across models. Default is \code{NULL}.}

\item{model_type}{Character string specifying model type. If \code{"auto"}, detects
based on outcome. Options include:
\itemize{
  \item \code{"auto"} - Automatically detect based on outcome type (default)
  \item \code{"glm"} - Generalized linear model. Supports logistic, Poisson, 
    Gamma, Gaussian via \code{family} parameter.
  \item \code{"lm"} - Linear regression for continuous outcomes
  \item \code{"coxph"} - Cox proportional hazards for survival analysis
  \item \code{"negbin"} - Negative binomial regression for overdispersed counts 
    (requires MASS package)
  \item \code{"lmer"} - Mixed-effects linear regression for clustered continuous
    outcomes
  \item \code{"glmer"} - Mixed-effects logistic regression for clustered
    categorical outcomes
  \item \code{"coxme"} - Mixed-effects Cox regression for clustered time-to-event
    outcomes
}}

\item{family}{For GLM and GLMER models, specifies the error distribution and link function.
Common options include:
\itemize{
  \item \code{"binomial"} - Logistic regression for binary outcomes (default)
  \item \code{"poisson"} - Poisson regression for count data
  \item \code{"quasibinomial"} - Logistic with overdispersion
  \item \code{"quasipoisson"} - Poisson with overdispersion
  \item \code{"gaussian"} - Normal distribution (linear regression via GLM)
  \item \code{"Gamma"} - Gamma for positive continuous data
  \item \code{"inverse.gaussian"} - For positive, highly skewed data
}
For negative binomial, use \code{model_type = "negbin"} instead.
See \code{\link[stats]{family}} for all options.}

\item{conf_level}{Numeric confidence level for intervals. Default is 0.95.}

\item{p_digits}{Integer specifying the number of decimal places for
\emph{p}-values. Values smaller than \code{10^(-p_digits)} are displayed
as \code{"< 0.001"} (for \code{p_digits = 3}), \code{"< 0.0001"} (for
\code{p_digits = 4}), etc. Default is 3.}

\item{include_coefficients}{Logical. If TRUE, includes a second table with
coefficient estimates. Default is FALSE.}

\item{scoring_weights}{Named list of scoring weights. Each weight should be
between 0 and 1, and they should sum to 1. Available metrics depend on model
type. If \code{NULL}, uses sensible defaults. See Details for available metrics.}

\item{labels}{Named character vector providing custom display labels for
variables. Default is \code{NULL}.}

\item{number_format}{Character string or two-element character vector
  controlling thousand and decimal separators in formatted output. Named
  presets:
  \itemize{
    \item \code{"us"} - Comma thousands, period decimal: \code{1,234.56} [default]
    \item \code{"eu"} - Period thousands, comma decimal: \code{1.234,56}
    \item \code{"space"} - Thin-space thousands, period decimal: \code{1 234.56}
      (SI/ISO 31-0)
    \item \code{"none"} - No thousands separator: \code{1234.56}
  }
  Or provide a custom two-element vector \code{c(big.mark, decimal.mark)},
  \emph{e.g.}, \code{c("'", ".")} for Swiss-style: \verb{1'234.56}.

  When \code{NULL} (default), uses
  \code{getOption("summata.number_format", "us")}. Set the global option
  once per session to avoid passing this argument repeatedly:
  \preformatted{
    options(summata.number_format = "eu")
  }}

\item{verbose}{Logical. If \code{TRUE}, displays model fitting warnings
(\emph{e.g.,} singular fit, convergence issues). If \code{FALSE} (default),
routine fitting messages are suppressed while unexpected warnings are
preserved. When \code{NULL}, uses
\code{getOption("summata.verbose", FALSE)}.}

\item{...}{Additional arguments passed to model fitting functions.}
}
\value{
A data.table with class "compfit_result" containing:
  \describe{
    \item{Model}{Model name/identifier}
    \item{CMS}{Composite Model Score for model selection (higher is better)}
    \item{N}{Sample size}
    \item{Events}{Number of events (for survival/logistic)}
    \item{Predictors}{Number of predictors}
    \item{Converged}{Whether model converged properly}
    \item{AIC}{Akaike Information Criterion}
    \item{BIC}{Bayesian Information Criterion}
    \item{\emph{R}\eqn{^2} / Pseudo-\emph{R}\eqn{^2}}{McFadden pseudo-R-squared (GLM)}
    \item{Concordance}{C-statistic (logistic/survival)}
    \item{Brier Score}{Brier accuracy score (logistic)}
    \item{Global \emph{p}}{Overall model \emph{p}-value}
  }
  
  Attributes include:
  \describe{
    \item{models}{List of fitted model objects}
    \item{coefficients}{Coefficient comparison table (if requested)}
    \item{best_model}{Name of recommended model}
  }
}
\description{
Fits multiple regression models and provides a comprehensive comparison table
with model quality metrics, convergence diagnostics, and selection guidance.
Computes a composite score combining multiple quality metrics to facilitate 
rapid model comparison and selection.
}
\details{
This function fits all specified models and computes comprehensive quality
metrics for comparison. It generates a Composite Model Score (CMS) that 
combines multiple metrics: lower AIC/BIC (information criteria), higher 
concordance (discrimination), and model convergence status.

For GLMs, McFadden's pseudo-R-squared is calculated as 1 - (logLik/logLik_null).
For survival models, the global \emph{p}-value comes from the log-rank test.

Models that fail to converge are flagged and penalized in the composite score.

\strong{Interaction Terms:}

When \code{interactions_list} is provided, each element specifies the
interaction terms for the corresponding model in \code{model_list}. This is
particularly useful for testing whether adding interactions improves model fit:
\itemize{
  \item Use \code{NULL} for models without interactions
  \item Specify interactions using colon notation: \code{c("age:treatment", "sex:stage")}
  \item Main effects for all variables in interactions must be in the predictor list
  \item Common pattern: Compare main effects model vs model with interactions
}

Scoring weights can be customized based on model type:
\itemize{
  \item GLM: \code{"convergence"}, \code{"aic"}, \code{"concordance"}, \code{"pseudo_r2"}, \code{"brier"} 
  \item Cox: \code{"convergence"}, \code{"aic"}, \code{"concordance"}, \code{"global_p"}
  \item Linear: \code{"convergence"}, \code{"aic"}, \code{"pseudo_r2"}, \code{"rmse"}
}
Default weights emphasize discrimination (concordance) and model fit (AIC).

The composite score is designed as a tool to quickly rank models by their 
quality metrics. It should be used alongside traditional model selection 
criteria rather than as a definitive model selection method.
}
\examples{
# Load example data
data(clintrial)
data(clintrial_labels)

# Information criteria assume a common sample, so the candidate predictors
# are restricted to complete cases before any comparison
comparison_data <- na.omit(
    clintrial[, c("readmission_30d", "os_months", "os_status", "age", "sex",
                  "smoking", "diabetes", "stage", "ecog", "grade",
                  "treatment")]
)

# Example 1: Compare nested logistic regression models
models <- list(
    base = c("age", "sex"),
    clinical = c("age", "sex", "smoking", "diabetes"),
    full = c("age", "sex", "smoking", "diabetes", "stage", "ecog")
)

comparison <- compfit(
    data = comparison_data,
    outcome = "readmission_30d",
    model_list = models,
    model_names = c("Base", "Clinical", "Full")
)
comparison

\donttest{

# Example 2: Compare Cox survival models
surv_models <- list(
    simple = c("age", "sex"),
    clinical = c("age", "sex", "stage", "grade")
)

surv_comparison <- compfit(
    data = comparison_data,
    outcome = "Surv(os_months, os_status)",
    model_list = surv_models,
    model_type = "coxph"
)
surv_comparison

# Example 3: Test the effect of adding an interaction term.
# Treatment efficacy differs by disease stage in these data, so the
# interaction is expected to improve the fit.
interaction_models <- list(
    main = c("age", "treatment", "stage"),
    interact = c("age", "treatment", "stage")
)

interaction_comp <- compfit(
    data = comparison_data,
    outcome = "Surv(os_months, os_status)",
    model_list = interaction_models,
    model_type = "coxph",
    model_names = c("Main Effects", "With Interaction"),
    interactions_list = list(
        NULL,
        c("treatment:stage")
    )
)
interaction_comp

# Example 4: Include coefficient comparison table
detailed <- compfit(
    data = comparison_data,
    outcome = "readmission_30d",
    model_list = models,
    include_coefficients = TRUE,
    labels = clintrial_labels
)

# Access coefficient table
coef_table <- attr(detailed, "coefficients")
coef_table

# Example 5: Access fitted model objects
fitted_models <- attr(comparison, "models")
names(fitted_models)

# Example 6: Get best model recommendation
best <- attr(comparison, "best_model")
cat("Recommended model:", best, "\n")

}

}
\seealso{
\code{\link{fit}} for individual model fitting,
\code{\link{fullfit}} for automated variable selection,
\code{\link{tablesave}} for exporting tables

Other regression functions:
\code{\link[=fit]{fit()}},
\code{\link[=fullfit]{fullfit()}},
\code{\link[=multifit]{multifit()}},
\code{\link[=print.compfit_result]{print.compfit_result()}},
\code{\link[=print.fit_result]{print.fit_result()}},
\code{\link[=print.fullfit_result]{print.fullfit_result()}},
\code{\link[=print.multifit_result]{print.multifit_result()}},
\code{\link[=print.uniscreen_result]{print.uniscreen_result()}},
\code{\link[=uniscreen]{uniscreen()}}
}
\concept{regression functions}
