% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/assoc.R
\name{assoc_competing}
\alias{assoc_competing}
\alias{assoc_fg}
\title{Fine-Gray competing risks association analysis}
\usage{
assoc_competing(
  data,
  outcome_col,
  time_col,
  exposure_col,
  compete_col = NULL,
  event_val = 1L,
  compete_val = 2L,
  covariates = NULL,
  base = TRUE,
  conf_level = 0.95
)

assoc_fg(
  data,
  outcome_col,
  time_col,
  exposure_col,
  compete_col = NULL,
  event_val = 1L,
  compete_val = 2L,
  covariates = NULL,
  base = TRUE,
  conf_level = 0.95
)
}
\arguments{
\item{data}{(data.frame or data.table) Analysis dataset.}

\item{outcome_col}{(character) Primary event column. In Mode A: a
multi-value column (any integer or character codes). In Mode B: a 0/1
binary column.}

\item{time_col}{(character) Follow-up time column (numeric, e.g. years).}

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

\item{compete_col}{(character or NULL) Mode B only: name of the 0/1
competing event column. When \code{NULL} (default), Mode A is used.}

\item{event_val}{Scalar value in \code{outcome_col} indicating the primary
event (Mode A only). Default: \code{1L}.}

\item{compete_val}{Scalar value in \code{outcome_col} indicating the
competing event (Mode A only). Default: \code{2L}.}

\item{covariates}{(character or NULL) Covariate names for the Fully
adjusted model. When \code{NULL}, only Unadjusted (and Age/sex adjusted
if \code{base = TRUE}) are run.}

\item{base}{(logical) Whether to auto-detect age and sex columns and include
an Age and sex adjusted model. Default: \code{TRUE}.}

\item{conf_level}{(numeric) Confidence level for SHR intervals.
Default: \code{0.95}.}
}
\value{
A \code{data.table} with one row per exposure \eqn{\times} term
\eqn{\times} model combination:
\describe{
\item{\code{exposure}}{Exposure variable name.}
\item{\code{term}}{Coefficient name as returned by \code{coxph}.}
\item{\code{model}}{Ordered factor: \code{Unadjusted} <
\code{Age and sex adjusted} < \code{Fully adjusted}.}
\item{\code{n}}{Participants in the model (after NA removal).}
\item{\code{n_events}}{Primary events in the analysis set.}
\item{\code{n_compete}}{Competing events in the analysis set.}
\item{\code{SHR}}{Subdistribution hazard ratio.}
\item{\code{CI_lower}}{Lower CI bound.}
\item{\code{CI_upper}}{Upper CI bound.}
\item{\code{p_value}}{Robust z-test p-value from weighted Cox.}
\item{\code{SHR_label}}{Formatted string, e.g. \code{"1.23 (1.05-1.44)"}.}
}
}
\description{
Fits a Fine-Gray subdistribution hazard model (via
\code{survival::finegray()} + weighted \code{coxph()}) for each exposure
variable and returns a tidy result table with subdistribution hazard ratios
(SHR).
}
\details{
Two input modes are supported depending on how the outcome is coded in your
dataset:

\describe{
\item{\strong{Mode A - single multi-value column}}{
\code{compete_col = NULL} (default). \code{outcome_col} contains all
event codes in one column (e.g. \code{0}/\code{1}/\code{2}/\code{3}).
Use \code{event_val} and \code{compete_val} to identify the event of
interest and the competing event; all other values are treated as
censored. Example: UKB \code{censoring_type} where 1 = event, 2 = death
(competing), 0/3 = censored.
}
\item{\strong{Mode B - dual binary columns}}{
\code{compete_col} is the name of a separate 0/1 column for the
competing event. \code{outcome_col} is a 0/1 column for the primary
event. When both are 1 for the same participant, the primary event takes
priority. Example: \code{outcome_col = "copd_status"},
\code{compete_col = "death_status"}.
}
}

Internally both modes are converted to a three-level factor
\code{c("censor", "event", "compete")} before being passed to
\code{finegray()}.

Three adjustment models are produced (where data allow):
\itemize{
\item \strong{Unadjusted} - always included.
\item \strong{Age and sex adjusted} - when \code{base = TRUE} and
age/sex columns are detected.
\item \strong{Fully adjusted} - when \code{covariates} is non-NULL.
}
}
\examples{
\donttest{
dt <- ops_toy(scenario = "association", n = 500)
dt <- dt[dm_timing != 1L & htn_timing != 1L]

res <- assoc_competing(
  data         = dt,
  outcome_col  = "dm_status",
  time_col     = "dm_followup_years",
  exposure_col = "p20116_i0",
  compete_col  = "htn_status",
  covariates   = c("bmi_cat", "tdi_cat")
)
}
}
