% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/multifit.R
\name{multifit}
\alias{multifit}
\title{Multivariate Regression Analysis}
\usage{
multifit(
  data,
  outcomes,
  predictor,
  covariates = NULL,
  interactions = NULL,
  random = NULL,
  strata = NULL,
  cluster = NULL,
  model_type = "glm",
  family = "binomial",
  columns = "adjusted",
  p_threshold = 1,
  conf_level = 0.95,
  show_n = TRUE,
  show_events = TRUE,
  digits = 2,
  p_digits = 3,
  labels = NULL,
  predictor_label = NULL,
  include_predictor = TRUE,
  keep_models = FALSE,
  exponentiate = NULL,
  conf_method = NULL,
  parallel = TRUE,
  n_cores = NULL,
  number_format = NULL,
  verbose = NULL,
  ...
)
}
\arguments{
\item{data}{Data frame or data.table containing the analysis dataset. The 
function automatically converts data frames to data.tables for efficient 
processing.}

\item{outcomes}{Character vector of outcome variable names to analyze. Each 
outcome is tested in its own model with the predictor. For time-to-event
analysis, use \code{Surv()} syntax for the outcome variable
(\emph{e.g.,} \code{c("Surv(time1, status1)", "Surv(time2, status2)")}).}

\item{predictor}{Character string specifying the predictor (exposure) variable 
name. This variable is tested against each outcome. Can be continuous or 
categorical (factor).}

\item{covariates}{Optional character vector of covariate variable names to 
include in adjusted models. When specified, models are fit as 
\code{outcome ~ predictor + covariate1 + covariate2 + ...}, and only the 
predictor effect is reported. Default is \code{NULL} (unadjusted models).}

\item{interactions}{Optional character vector of interaction terms to include
in adjusted models, using colon notation (\emph{e.g.,} \code{c("predictor:sex")}).
Interactions involving the predictor will have their effects extracted and
reported. Default is \code{NULL}.}

\item{random}{Optional character string specifying random effects formula for
mixed effects models (\emph{e.g.,} \code{"(1|hospital)"} or \code{"(1|site/patient)"}).
Required when \code{model_type} is \code{"glmer"}, \code{"lmer"}, or 
\code{"coxme"} unless random effects are included in the \code{covariates}
vector. Alternatively, random effects can be included directly in the 
\code{covariates} vector using the same syntax (\emph{e.g.,} 
\code{covariates = c("age", "sex", "(1|site)")}). Default is \code{NULL}.}

\item{strata}{Optional character string naming the stratification variable for
Cox or conditional logistic models. Creates separate baseline hazards for 
each stratum. Default is \code{NULL}.}

\item{cluster}{Optional character string naming the clustering variable for
Cox models. Computes robust clustered standard errors. Default is \code{NULL}.}

\item{model_type}{Character string specifying the type of regression model to 
fit. Options include:
\itemize{
  \item \code{"glm"} - Generalized linear model (default). Supports multiple 
    distributions via the \code{family} parameter including logistic, Poisson, 
    Gamma, Gaussian, and quasi-likelihood models.
  \item \code{"lm"} - Linear regression for continuous outcomes with normally 
    distributed errors.
  \item \code{"coxph"} - Cox proportional hazards model for time-to-event 
    survival analysis. Requires \code{Surv()} outcome syntax.
  \item \code{"clogit"} - Conditional logistic regression for matched 
    case-control studies.
  \item \code{"negbin"} - Negative binomial regression for overdispersed count 
    data (requires MASS package). Estimates an additional dispersion parameter 
    compared to Poisson regression.
  \item \code{"glmer"} - Generalized linear mixed-effects model for hierarchical 
    or clustered data with non-normal outcomes (requires \pkg{lme4} package and 
    \code{random} parameter).
  \item \code{"lmer"} - Linear mixed-effects model for hierarchical or clustered 
    data with continuous outcomes (requires \pkg{lme4} package and \code{random} 
    parameter).
  \item \code{"coxme"} - Cox mixed-effects model for clustered survival data 
    (requires coxme package and \code{random} parameter).
}}

\item{family}{For GLM and GLMER models, specifies the error distribution and link 
function. Can be a character string, a family function, or a family object.
Ignored for non-GLM/GLMER models.

\strong{Binary/Binomial outcomes:}
\itemize{
  \item \code{"binomial"} or \code{binomial()} - Logistic regression for binary 
    outcomes (0/1, TRUE/FALSE). Returns odds ratios (OR). Default.
  \item \code{"quasibinomial"} or \code{quasibinomial()} - Logistic regression 
    with overdispersion. Use when residual deviance >> residual df.
  \item \code{binomial(link = "probit")} - Probit regression (normal CDF link).
  \item \code{binomial(link = "cloglog")} - Complementary log-log link for 
    asymmetric binary outcomes.
}

\strong{Count outcomes:}
\itemize{
  \item \code{"poisson"} or \code{poisson()} - Poisson regression for count 
    data. Returns rate ratios (RR). Assumes mean = variance.
  \item \code{"quasipoisson"} or \code{quasipoisson()} - Poisson regression 
    with overdispersion. Use when variance > mean.
}

\strong{Continuous outcomes:}
\itemize{
  \item \code{"gaussian"} or \code{gaussian()} - Normal/Gaussian distribution 
    for continuous outcomes. Equivalent to linear regression.
  \item \code{gaussian(link = "log")} - Log-linear model for positive continuous 
    outcomes. Returns multiplicative effects.
}

\strong{Positive continuous outcomes:}
\itemize{
  \item \code{"Gamma"} or \code{Gamma()} - Gamma distribution for positive, 
    right-skewed continuous data (\emph{e.g.,} costs, lengths of stay). When
    passed as a string, resolves to log link for interpretable multiplicative
    effects.
  \item \code{Gamma(link = "inverse")} - Gamma with inverse (canonical) link.
  \item \code{Gamma(link = "identity")} - Gamma with identity link for additive 
    effects on positive outcomes.
  \item \code{"inverse.gaussian"} or \code{inverse.gaussian()} - Inverse Gaussian 
    for positive, highly right-skewed data.
}

For negative binomial regression (overdispersed counts), use 
\code{model_type = "negbin"} instead of the \code{family} parameter.

See \code{\link[stats]{family}} for additional details and options.}

\item{columns}{Character string specifying which result columns to display when 
both unadjusted and adjusted models are fit (\emph{i.e.,} when \code{covariates} is 
specified):
\itemize{
  \item \code{"adjusted"} - Show only adjusted (covariate-controlled) results [default]
  \item \code{"unadjusted"} - Show only unadjusted (crude) results
  \item \code{"both"} - Show both unadjusted and adjusted results side-by-side
}
Ignored when \code{covariates = NULL}.}

\item{p_threshold}{Numeric value between 0 and 1 specifying a \emph{p}-value threshold 
for filtering results. Only outcomes with \emph{p}-value less than or equal to the
threshold are included in the output. Default is 1 (no filtering; all outcomes returned).}

\item{conf_level}{Numeric confidence level for confidence intervals. Must be 
between 0 and 1. Default is 0.95 (95\% confidence intervals).}

\item{show_n}{Logical. If \code{TRUE}, includes the sample size column in 
the output table. Default is \code{TRUE}.}

\item{show_events}{Logical. If \code{TRUE}, includes the events column in the 
output table (relevant for survival and logistic regression). Default is 
\code{TRUE}.}

\item{digits}{Integer specifying the number of decimal places for effect 
estimates (OR, HR, RR, coefficients). Default is 2.}

\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{labels}{Named character vector or list providing custom display 
labels for variables. Can include labels for outcomes, predictors, and 
covariates. Names should match variable names, values are the display labels.
Labels are applied to: (1) outcome names in the Outcome column, (2) predictor
variable name when displayed, and (3) variable names in formatted interaction
terms. Variables not in \code{labels} use their original names. 
Default is \code{NULL}.}

\item{predictor_label}{Optional character string providing a custom display 
label for the predictor variable. Takes precedence over \code{labels} for
the predictor. Default is \code{NULL} (uses label from \code{labels} or 
original name).}

\item{include_predictor}{Logical. If \code{TRUE} (default), includes the 
predictor column in the output table showing which level of a factor 
predictor is being compared. If \code{FALSE}, omits the predictor column,
which may be useful when the predictor information will be explained in 
a table caption or figure legend.}

\item{keep_models}{Logical. If \code{TRUE}, stores all fitted model objects 
in the output as an attribute. Models are accessible via 
\code{attr(result, "models")}. Default is \code{FALSE}.}

\item{exponentiate}{Logical. Whether to exponentiate coefficients (display
OR/HR/RR instead of log odds/log hazards). Default is \code{NULL}, which
automatically displays raw coefficients for linear models and
exponentiates for logistic, Poisson, and Cox models.}

\item{conf_method}{Character string controlling the confidence interval method.
If \code{NULL} (default), uses \code{getOption("summata.conf_method", "profile")}.
\itemize{
  \item \code{"profile"} - Profile likelihood intervals for GLM and negative
    binomial models (via \code{MASS::confint.glm()}), exact \emph{t}-distribution
    intervals for linear models. Falls back to Wald on profiling failure.
    Quasi-likelihood families always use Wald (no true likelihood).
  \item \code{"wald"} - Wald intervals (coefficient \eqn{\pm} \emph{z}
    \eqn{\times} SE) for all model types. Faster but less accurate near
    boundary conditions or with small subgroups.
}
Cox and mixed-effects models use Wald intervals regardless of this setting.
Set globally with \code{options(summata.conf_method = "wald")} to use Wald
throughout a session.}

\item{parallel}{Logical. If \code{TRUE} (default), fits models in parallel
for improved performance with many outcomes.}

\item{n_cores}{Integer specifying the number of CPU cores to use for
parallel processing. Default is \code{NULL} (auto-detect: uses
\code{detectCores() - 1}). Ignored when \code{parallel = FALSE}.}

\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 the underlying model fitting functions.}
}
\value{
A data.table with S3 class \code{"multifit_result"} containing formatted 
  multivariate regression results. The table structure includes:
  \describe{
    \item{Outcome}{Character. Outcome variable name or custom label}
    \item{Predictor}{Character. For factor predictors: formatted as 
      "Variable (Level)" showing the level being compared to reference.
      For binary variables where the non-reference level is an affirmative
      value (Yes, 1, True, Present, Positive, +), shows just "Variable".
      For continuous predictors: the variable name. For interactions: the
      formatted interaction term (\emph{e.g.,} "Treatment (Drug A) × Sex (Male)")}
    \item{n}{Integer. Sample size used in fitting (if \code{show_n = TRUE}).
      When both unadjusted and adjusted estimates are shown, this is the
      adjusted model's sample, which is the one behind the adjusted
      estimate on the same row}
    \item{Events}{Integer. Number of events (if \code{show_events = TRUE})}
    \item{OR/HR/RR/Coefficient (95\% CI)}{Character. Unadjusted effect 
      estimate with CI (if \code{columns = "unadjusted"} or \code{"both"})}
    \item{aOR/aHR/aRR/Adj. Coefficient (95\% CI)}{Character. Adjusted 
      effect estimate with CI (if \code{columns = "adjusted"} or \code{"both"})}
    \item{Uni \emph{p} / Multi \emph{p} / \emph{p}-value}{Character. Formatted \emph{p}-value(s). Column 
      names depend on \code{columns} setting}
  }
  
  The returned object includes the following attributes accessible via \code{attr()}:
  \describe{
    \item{raw_data}{data.table. Unformatted numeric results with separate 
      columns for effect estimates, standard errors, confidence intervals, 
      and \emph{p}-values. Suitable for custom analysis or visualization}
    \item{models}{list (if \code{keep_models = TRUE}). Named list of fitted 
      model objects, with outcome names as list names. Each element contains
      \code{$unadjusted} and/or \code{$adjusted} models depending on settings}
    \item{predictor}{Character. The predictor variable name}
    \item{outcomes}{Character vector. The outcome variable names}
    \item{covariates}{Character vector or \code{NULL}. The covariate variable names}
    \item{interactions}{Character vector or \code{NULL}. The interaction terms}
    \item{random}{Character or \code{NULL}. The random effects formula}
    \item{strata}{Character or \code{NULL}. The stratification variable}
    \item{cluster}{Character or \code{NULL}. The clustering variable}
    \item{model_type}{Character. The regression model type used}
    \item{columns}{Character. Which columns were displayed}
    \item{analysis_type}{Character. \code{"multi_outcome"} to identify analysis type}
    \item{significant}{Character vector. Names of outcomes with \emph{p} < 0.05
      for the predictor (uses adjusted \emph{p}-values when available)}
    \item{analysis_counts}{List. How much of the supplied data reached the
      models, with elements \code{n_supplied}, \code{n_analyzed},
      \code{n_missing_outcome} and \code{n_missing_predictor}. One model is
      fitted per outcome, so \code{n_analyzed} holds one value per outcome
      and the reported sample may be a range. Event counts are not
      included: each outcome has its own event total, so a single reported
      figure could not describe them all. The \code{print()} method always
      reports the analyzed sample}
  }
}
\description{
Performs regression analyses of a single predictor (exposure) across multiple 
outcomes. This function is designed for studies where a single exposure variable 
is tested against multiple endpoints, such as complication screening, biomarker 
associations, or phenome-wide association studies. Returns publication-ready 
formatted results with optional covariate adjustment. Supports interactions,
mixed-effects models, stratification, and clustered standard errors.
}
\details{
\strong{Analysis Approach:}

The function implements a multivariate (multi-outcome) screening workflow that
inverts the typical regression paradigm:
\enumerate{
  \item For each outcome in \code{outcomes}, fits a separate model with the 
    predictor as the main exposure
  \item If \code{covariates} specified, fits adjusted model: 
    \code{outcome ~ predictor + covariates + interactions}
  \item Extracts only the predictor effect(s) from each model, ignoring 
    covariate coefficients
  \item Combines results into a single table for comparison across outcomes
  \item Optionally filters by \emph{p}-value threshold
}

This is conceptually opposite to \code{uniscreen()}, which tests multiple 
predictors against a single outcome. \code{multifit()} applies where there is one 
exposure of interest and want to screen across multiple endpoints.

\strong{When to Use Multivariate Regression Analysis:}
\itemize{
  \item \strong{Complication screening}: Test one exposure (\emph{e.g.,} operative time, 
    BMI, biomarker level) against multiple postoperative complications
  \item \strong{Treatment effects}: Test one treatment against multiple efficacy 
    and safety endpoints simultaneously
  \item \strong{Biomarker studies}: Test one biomarker against multiple clinical 
    outcomes to understand its prognostic value
  \item \strong{Phenome-wide association studies (PheWAS)}: Test genetic variants 
    or exposures against many phenotypes
  \item \strong{Risk factor profiling}: Understand how one risk factor relates 
    to a spectrum of outcomes
}

\strong{Handling Categorical Predictors:}

When the predictor is a factor variable with multiple levels:
\itemize{
  \item Each non-reference level gets its own row for each outcome
  \item Reference category is determined by factor level ordering
  \item The Predictor column shows "Variable (Level)" format 
    (\emph{e.g.,} "Treatment (Drug A)", "Treatment (Drug B)")
  \item For binary variables with affirmative non-reference levels 
    (Yes, 1, True, Present, Positive, +), shows just "Variable" 
    (\emph{e.g.,} "Diabetes" instead of "Diabetes (Yes)")
  \item Effect estimates compare each level to the reference
}

\strong{Adjusted vs. Unadjusted Results:}

When \code{covariates} is specified, the function fits both models but only 
extracts predictor effects:
\itemize{
  \item \code{columns = "adjusted"}: Reports only covariate-adjusted effects.
    Column labeled "aOR/aHR," \emph{etc.}
  \item \code{columns = "unadjusted"}: Reports only crude effects. Column 
    labeled "OR/HR," \emph{etc.}
  \item \code{columns = "both"}: Reports both side-by-side. Useful for 
    identifying confounding (large change in effect) or independent effects 
    (similar estimates)
}

\strong{Interaction Terms:}

When \code{interactions} includes terms involving the predictor:
\itemize{
  \item Main effect of predictor is always reported
  \item Interaction effects are extracted and displayed with formatted names
  \item Format: \code{Variable (Level) × Variable (Level)} using multiplication sign notation
  \item Useful for testing effect modification (\emph{e.g.,} does treatment effect 
    differ by sex?)
}

\strong{Mixed-Effects Models:}

For clustered or hierarchical data (\emph{e.g.,} patients within hospitals):
\itemize{
  \item Use \code{model_type = "glmer"} with \code{random = "(1|cluster)"} for 
    random intercept models
  \item Nested random effects: \code{random = "(1|site/patient)"}
  \item Crossed random effects: \code{random = "(1|site) + (1|doctor)"}
  \item For survival outcomes, use \code{model_type = "coxme"}
}

\strong{Stratification and Clustering (Cox models):}

For Cox proportional hazards models:
\itemize{
  \item \code{strata}: Creates separate baseline hazards for each stratum level.
    Use when hazards are non-proportional across strata but stratum effects do
    not need to be estimated
  \item \code{cluster}: Computes robust (sandwich) standard errors accounting 
    for within-cluster correlation. Alternative to mixed effects when only 
    robust SEs are needed
}

\strong{Filtering based on \emph{p}-value:}

The \code{p_threshold} parameter filters results after fitting all models:
\itemize{
  \item Only outcomes with \emph{p} less than or equal to the threshold are retained in output
  \item For factor predictors, outcome is kept if any level is significant
  \item Useful for focusing on significant associations in exploratory analyses
  \item Default is 1 (no filtering) - recommended for confirmatory analyses
}

\strong{Outcome Homogeneity:}

All outcomes in a single \code{multifit()} call should be of the same type
(all binary, all continuous, or all survival). Mixing outcome types produces
tables with incompatible effect measures (\emph{e.g.,} odds ratios alongside regression
coefficients), which can mislead readers. The function validates outcome
compatibility and issues a warning when mixed types are detected.

For analyses involving multiple outcome types, run separate \code{multifit()}
calls for each type:

\preformatted{
# Binary outcomes
binary_results <- multifit(data, outcomes = c("death", "readmission"),
                           predictor = "treatment", model_type = "glm")

# Continuous outcomes
continuous_results <- multifit(data, outcomes = c("los_days", "cost"),
                               predictor = "treatment", model_type = "lm")
}

\strong{Effect Measures by Model Type:}
\itemize{
  \item \strong{Logistic} (\code{model_type = "glm"}, \code{family = "binomial"}): 
    Odds ratios (OR/aOR)
  \item \strong{Cox} (\code{model_type = "coxph"}): Hazard ratios (HR/aHR)
  \item \strong{Poisson} (\code{model_type = "glm"}, \code{family = "poisson"}): 
    Rate ratios (RR/aRR)
  \item \strong{Linear} (\code{model_type = "lm"}): Coefficient estimates
  \item \strong{Mixed effects}: Same as fixed-effects counterparts
}

\strong{Memory and Performance:}

\itemize{
  \item \code{parallel = TRUE} (default) uses multiple cores for faster fitting
  \item \code{keep_models = FALSE} (default) discards model objects to save memory
  \item For many outcomes, parallel processing provides substantial speedup
  \item Set \code{keep_models = TRUE} only when model diagnostics are required
}
}
\examples{
# Load example data
data(clintrial)
data(clintrial_labels)

# Example 1: Basic multivariate analysis (unadjusted)
result1 <- multifit(
    data = clintrial,
    outcomes = c("surgery", "pfs_status", "os_status"),
    predictor = "treatment",
    labels = clintrial_labels,
    parallel = FALSE
)
print(result1)

\donttest{

# Example 2: Adjusted analysis with covariates
result2 <- multifit(
    data = clintrial,
    outcomes = c("surgery", "pfs_status", "os_status"),
    predictor = "treatment",
    covariates = c("age", "sex", "stage"),
    labels = clintrial_labels,
    parallel = FALSE
)
print(result2)

# Example 3: Compare unadjusted and adjusted results
result3 <- multifit(
    data = clintrial,
    outcomes = c("surgery", "pfs_status", "os_status"),
    predictor = "treatment",
    covariates = c("age", "sex", "stage"),
    columns = "both",
    labels = clintrial_labels,
    parallel = FALSE
)
print(result3)

# Example 4: Continuous predictor across outcomes
result4 <- multifit(
    data = clintrial,
    outcomes = c("surgery", "pfs_status", "os_status"),
    predictor = "age",
    covariates = c("sex", "treatment", "stage"),
    labels = clintrial_labels,
    parallel = FALSE
)
print(result4)

# Example 5: Cox regression for survival outcomes
library(survival)
cox_result <- multifit(
    data = clintrial,
    outcomes = c("Surv(pfs_months, pfs_status)", 
                 "Surv(os_months, os_status)"),
    predictor = "treatment",
    covariates = c("age", "sex", "stage"),
    model_type = "coxph",
    labels = clintrial_labels,
    parallel = FALSE
)
print(cox_result)

# Example 6: Cox with stratification by site
cox_strat <- multifit(
    data = clintrial,
    outcomes = c("Surv(os_months, os_status)"),
    predictor = "treatment",
    covariates = c("age", "sex"),
    strata = "site",
    model_type = "coxph",
    labels = clintrial_labels,
    parallel = FALSE
)
print(cox_strat)

# Example 7: Cox with clustered standard errors
cox_cluster <- multifit(
    data = clintrial,
    outcomes = c("Surv(os_months, os_status)"),
    predictor = "treatment",
    covariates = c("age", "sex", "stage"),
    cluster = "site",
    model_type = "coxph",
    labels = clintrial_labels,
    parallel = FALSE
)
print(cox_cluster)

# Example 8: Interaction between predictor and covariate
result_int <- multifit(
    data = clintrial,
    outcomes = c("surgery", "os_status"),
    predictor = "treatment",
    covariates = c("age", "sex", "stage"),
    interactions = c("treatment:sex"),
    labels = clintrial_labels,
    parallel = FALSE
)
print(result_int)

# Example 9: Linear model for continuous outcomes
linear_result <- multifit(
    data = clintrial,
    outcomes = c("los_days", "biomarker_x"),
    predictor = "treatment",
    covariates = c("age", "sex"),
    model_type = "lm",
    labels = clintrial_labels,
    parallel = FALSE
)
print(linear_result)

# Example 10: Poisson regression for equidispersed count outcomes
# fu_count has variance ~= mean, appropriate for standard Poisson
poisson_result <- multifit(
    data = clintrial,
    outcomes = c("fu_count"),
    predictor = "treatment",
    covariates = c("age", "stage"),
    model_type = "glm",
    family = "poisson",
    labels = clintrial_labels,
    parallel = FALSE
)
print(poisson_result)

# Example 11: Filter to significant results only
sig_results <- multifit(
    data = clintrial,
    outcomes = c("surgery", "pfs_status", "os_status"),
    predictor = "stage",
    p_threshold = 0.05,
    labels = clintrial_labels,
    parallel = FALSE
)
print(sig_results)

# Example 12: Custom outcome labels
result_labeled <- multifit(
    data = clintrial,
    outcomes = c("surgery", "pfs_status", "os_status"),
    predictor = "treatment",
    labels = c(
        surgery = "Surgical Resection",
        pfs_status = "Disease Progression",
        os_status = "Death",
        treatment = "Treatment Group"
    ),
    parallel = FALSE
)
print(result_labeled)

# Example 13: Keep models for diagnostics
result_models <- multifit(
    data = clintrial,
    outcomes = c("surgery", "os_status"),
    predictor = "treatment",
    covariates = c("age", "sex"),
    keep_models = TRUE,
    parallel = FALSE
)

# Access stored models
models <- attr(result_models, "models")
names(models)

# Get adjusted model for surgery outcome
surgery_model <- models$surgery$adjusted
summary(surgery_model)

# Example 14: Access raw numeric data
result <- multifit(
    data = clintrial,
    outcomes = c("surgery", "os_status"),
    predictor = "age",
    parallel = FALSE
)

# Get unformatted results for custom analysis
raw_data <- attr(result, "raw_data")
print(raw_data)

# Example 15: Hide sample size and event columns
result_minimal <- multifit(
    data = clintrial,
    outcomes = c("surgery", "os_status"),
    predictor = "treatment",
    show_n = FALSE,
    show_events = FALSE,
    labels = clintrial_labels,
    parallel = FALSE
)
print(result_minimal)

# Example 16: Customize decimal places
result_digits <- multifit(
    data = clintrial,
    outcomes = c("surgery", "os_status"),
    predictor = "age",
    digits = 3,
    p_digits = 4,
    labels = clintrial_labels,
    parallel = FALSE
)
print(result_digits)

# Example 17: Force coefficient display (no exponentiation)
result_coef <- multifit(
    data = clintrial,
    outcomes = c("surgery"),
    predictor = "age",
    exponentiate = FALSE,
    labels = clintrial_labels,
    parallel = FALSE
)
print(result_coef)

# Example 18: Complete publication workflow
final_table <- multifit(
    data = clintrial,
    outcomes = c("surgery", "pfs_status", "os_status"),
    predictor = "treatment",
    covariates = c("age", "sex", "stage", "grade"),
    columns = "both",
    labels = clintrial_labels,
    digits = 2,
    p_digits = 3,
    parallel = FALSE
)
print(final_table)

# Example 19: Gamma regression for positive continuous outcomes
gamma_result <- multifit(
    data = clintrial,
    outcomes = c("los_days", "recovery_days"),
    predictor = "treatment",
    covariates = c("age", "surgery"),
    model_type = "glm",
    family = Gamma(link = "log"),
    labels = clintrial_labels,
    parallel = FALSE
)
print(gamma_result)

# Example 20: Quasipoisson for overdispersed counts
quasi_result <- multifit(
    data = clintrial,
    outcomes = c("ae_count"),
    predictor = "treatment",
    covariates = c("age", "diabetes"),
    model_type = "glm",
    family = "quasipoisson",
    labels = clintrial_labels,
    parallel = FALSE
)
print(quasi_result)

# Example 21: Generalized linear mixed effects (GLMER)
# Test treatment across outcomes with site clustering
if (requireNamespace("lme4", quietly = TRUE)) {
    glmer_result <- suppressWarnings(multifit(
        data = clintrial,
        outcomes = c("surgery", "pfs_status", "os_status"),
        predictor = "treatment",
        covariates = c("age", "sex"),
        random = "(1|site)",
        model_type = "glmer",
        family = "binomial",
        labels = clintrial_labels,
        parallel = FALSE
    ))
    print(glmer_result)
}

# Example 22: Cox mixed effects with random site effects
if (requireNamespace("coxme", quietly = TRUE)) {
    coxme_result <- multifit(
        data = clintrial,
        outcomes = c("Surv(pfs_months, pfs_status)", 
                     "Surv(os_months, os_status)"),
        predictor = "treatment",
        covariates = c("age", "sex", "stage"),
        random = "(1|site)",
        model_type = "coxme",
        labels = clintrial_labels,
        parallel = FALSE
    )
    print(coxme_result)
}

# Example 23: Multiple interactions across outcomes
multi_int <- multifit(
    data = clintrial,
    outcomes = c("surgery", "pfs_status", "os_status"),
    predictor = "treatment",
    covariates = c("age", "sex", "stage"),
    interactions = c("treatment:stage", "treatment:sex"),
    labels = clintrial_labels,
    parallel = FALSE
)
print(multi_int)

}

}
\seealso{
\code{\link{uniscreen}} for screening multiple predictors against one outcome,
\code{\link{multiforest}} for creating forest plots from multifit results,
\code{\link{fit}} for single-outcome regression with full coefficient output,
\code{\link{fullfit}} for complete univariable-to-multivariable workflow,
\code{\link{forestsave}} for saving the forest plot,
\code{\link{tablesave}} for exporting tables

Other regression functions:
\code{\link[=compfit]{compfit()}},
\code{\link[=fit]{fit()}},
\code{\link[=fullfit]{fullfit()}},
\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}
