% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/assoc.R
\name{assoc_subgroup}
\alias{assoc_subgroup}
\alias{assoc_sub}
\title{Subgroup association analysis with optional interaction test}
\usage{
assoc_subgroup(
  data,
  outcome_col,
  time_col = NULL,
  exposure_col,
  by,
  method = c("coxph", "logistic", "linear"),
  covariates = NULL,
  interaction = TRUE,
  conf_level = 0.95
)

assoc_sub(
  data,
  outcome_col,
  time_col = NULL,
  exposure_col,
  by,
  method = c("coxph", "logistic", "linear"),
  covariates = NULL,
  interaction = TRUE,
  conf_level = 0.95
)
}
\arguments{
\item{data}{(data.frame or data.table) Analysis dataset.}

\item{outcome_col}{(character) Outcome column name.}

\item{time_col}{(character or NULL) Follow-up time column (required when
\code{method = "coxph"}).}

\item{exposure_col}{(character) One or more exposure variable names.}

\item{by}{(character) Single stratification variable name. Its unique
non-NA values (or factor levels, in order) define the subgroups.
Should be a categorical or binary variable with a small number of
levels (e.g. sex, smoking status). Continuous variables are technically
permitted and the interaction LRT will still run, but per-unique-value
subgrouping is rarely meaningful in practice — use a pre-categorised
version (e.g. via \code{\link{derive_cut}}) instead.}

\item{method}{(character) Regression method: \code{"coxph"} (default),
\code{"logistic"}, or \code{"linear"}.}

\item{covariates}{(character or NULL) Covariate column names for the Fully
adjusted model. When \code{NULL}, only the Unadjusted model is run.}

\item{interaction}{(logical) Compute the LRT p-value for the exposure
\eqn{\times} by interaction on the full dataset. Default: \code{TRUE}.}

\item{conf_level}{(numeric) Confidence level. Default: \code{0.95}.}
}
\value{
A \code{data.table} with one row per subgroup level \eqn{\times}
exposure \eqn{\times} term \eqn{\times} model, containing:
\describe{
\item{\code{subgroup}}{Name of the \code{by} variable.}
\item{\code{subgroup_level}}{Factor: level of the \code{by} variable
(ordered by original level / sort order).}
\item{\code{exposure}}{Exposure variable name.}
\item{\code{term}}{Coefficient name from the fitted model.}
\item{\code{model}}{Ordered factor: \code{Unadjusted} <
\code{Fully adjusted}.}
\item{\code{n}}{Participants in model (after NA removal).}
\item{...}{Effect estimate columns: \code{HR}/\code{OR}/\code{beta},
\code{CI_lower}, \code{CI_upper}, \code{p_value}, and a formatted
label column. Cox models additionally include \code{n_events} and
\code{person_years}; logistic models include \code{n_cases}; linear
models include \code{se}.}
\item{\code{p_interaction}}{LRT p-value for the exposure \eqn{\times}
by interaction on the full dataset. Shared across all subgroup levels
for the same exposure \eqn{\times} model. \code{NA} when the
interaction model fails. Only present when
\code{interaction = TRUE}.}
}
}
\description{
Stratifies the dataset by a single grouping variable (\code{by}) and runs
the specified association model (\code{coxph}, \code{logistic}, or
\code{linear}) within each subgroup. Unlike \code{\link{assoc_coxph}} and
its siblings, there is no automatic age-and-sex-adjusted model: at the
subgroup level the variable that defines the stratum would have zero
variance, making the auto-detected adjustment meaningless. Accordingly,
this function does not accept a \code{base} argument. Instead, two
models are available:
}
\details{
\itemize{
\item \strong{Unadjusted} - always run (no covariates).
\item \strong{Fully adjusted} - run when \code{covariates} is non-NULL.
Users are responsible for excluding the \code{by} variable from
\code{covariates} (a warning is issued if it is included).
}

\strong{Interaction test}: when \code{interaction = TRUE} (default), a
likelihood ratio test (LRT) for the exposure \eqn{\times} by interaction is
computed on the \emph{full} dataset for each exposure \eqn{\times} model
combination and appended as \code{p_interaction}. LRT is preferred over
Wald because it handles factor, binary, and continuous \code{by} variables
uniformly without requiring the user to recode the \code{by} variable.
}
\examples{
dt <- ops_toy(scenario = "association", n = 500)
dt <- dt[dm_timing != 1L]

res <- assoc_subgroup(
  data         = dt,
  outcome_col  = "dm_status",
  time_col     = "dm_followup_years",
  exposure_col = "p20116_i0",
  by           = "p31",
  method       = "coxph",
  covariates   = c("bmi_cat", "tdi_cat")
)
}
