| Title: | Stagewise Variable Selection for Joint Models of Semi-Competing Risks |
|---|---|
| Description: | Implements stagewise regression for variable selection in joint models of recurrent events and terminal events (semi-competing risks). Supports two model frameworks: the joint frailty model (Cox-type) and the joint scale-change model (AFT-type). Provides cooperative lasso, lasso, and group lasso penalties with cross-validation for tuning parameter selection via cross-fitted estimating equations. |
| Authors: | Jared D. Huling [aut, cre], Lingfeng Huo [aut], Ziren Jiang [aut], Jue Hou [aut], Sy Han (Steven) Chiou [ctb], Chiung-Yu Huang [ctb] |
| Maintainer: | Jared D. Huling <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.1.1 |
| Built: | 2026-05-23 09:16:24 UTC |
| Source: | https://github.com/jaredhuling/swjm |
Implements stagewise regression for penalized variable selection in joint models of recurrent events and terminal events (semi-competing risks).
Two model frameworks are supported:
Joint Frailty Model (JFM): Cox-type model where
alpha = recurrence/readmission coefficients (first p elements of theta),
beta = terminal/death coefficients (second p elements).
Joint Scale-Change Model (JSCM): AFT-type model where
alpha = recurrence/readmission coefficients (first p elements of theta),
beta = terminal/death coefficients (second p elements).
Three penalty types are available:
"coop": Cooperative lasso, which encourages shared support
between the recurrence and terminal event coefficient vectors.
"lasso": Standard L1 penalty applied coordinate-wise.
"group": Group lasso, which selects variables jointly across
both processes.
All functions expect a recurrent-event data frame with the following columns:
Subject identifier (integer).
Interval start time.
Interval stop time.
1 for recurrent event, 0 for terminal/censoring row.
1 for death, 0 for alive/censored.
Covariate columns.
Maintainer: Jared D. Huling [email protected]
Authors:
Lingfeng Huo
Ziren Jiang
Jue Hou
Other contributors:
Sy Han (Steven) Chiou [contributor]
Chiung-Yu Huang [contributor]
Evaluates the cumulative baseline hazards for readmission and death at arbitrary time points. For JFM, Breslow-type estimators are used. For JSCM, Nelson-Aalen estimators on the accelerated time scale are used.
baseline_hazard( object, times = NULL, which = c("both", "readmission", "death") )baseline_hazard( object, times = NULL, which = c("both", "readmission", "death") )
object |
An object of class |
times |
Numeric vector of evaluation times. If |
which |
Character. Which baseline hazard(s) to return:
|
A data frame with column time and, depending on
which, cumhaz_readmission and/or cumhaz_death.
dat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") cv <- cv_stagewise(dat$data, model = "jfm", penalty = "coop", max_iter = 100) bh <- baseline_hazard(cv) head(bh)dat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") cv <- cv_stagewise(dat$data, model = "jfm", penalty = "coop", max_iter = 100) bh <- baseline_hazard(cv) head(bh)
Selects the optimal penalty parameter (lambda) along the stagewise path using K-fold cross-validation with cross-fitted estimating equations.
cv_stagewise( data, model = c("jfm", "jscm"), penalty = c("coop", "lasso", "group"), K = 5L, lambda_seq = NULL, eps = NULL, max_iter = NULL, pp = NULL, estimate_frailty = FALSE, ncores = 1L, standardize = TRUE )cv_stagewise( data, model = c("jfm", "jscm"), penalty = c("coop", "lasso", "group"), K = 5L, lambda_seq = NULL, eps = NULL, max_iter = NULL, pp = NULL, estimate_frailty = FALSE, ncores = 1L, standardize = TRUE )
data |
A data frame in recurrent-event format. |
model |
Character. Either |
penalty |
Character. One of |
K |
Integer. Number of cross-validation folds (default 5). |
lambda_seq |
Numeric vector. The lambda sequence at which to
evaluate the cross-validation criterion. If |
eps |
Numeric. Step size (passed to |
max_iter |
Integer. Maximum iterations (passed to |
pp |
Integer. Early-stop block size (passed to |
estimate_frailty |
Logical. For JFM only: if |
ncores |
Integer. Number of cores for parallel fold training
(default 1, sequential). Uses |
standardize |
Logical. If |
An object of class "swjm_cv", a list with components:
Integer, position of best lambda by combined cross-fitted score norm.
Integer, position of best lambda by recurrence score norm.
Integer, position of best lambda by terminal score norm.
Numeric vector of lambda values evaluated.
Combined cross-fitted score norm path.
Recurrence score norm path.
Terminal score norm path.
The full-data stagewise fit (class "swjm_path").
Character.
Character.
dat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") fit <- stagewise_fit(dat$data, model = "jfm", penalty = "coop", max_iter = 100) cv_res <- cv_stagewise(dat$data, model = "jfm", penalty = "coop", lambda_seq = fit$lambda, max_iter = 100) cv_resdat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") fit <- stagewise_fit(dat$data, model = "jfm", penalty = "coop", max_iter = 100) cv_res <- cv_stagewise(dat$data, model = "jfm", penalty = "coop", lambda_seq = fit$lambda, max_iter = 100) cv_res
Unified interface that dispatches to model-specific data generation functions for the joint frailty model (JFM) or joint scale-change model (JSCM).
generate_data(n, p, scenario = 1, model = c("jfm", "jscm"), ...)generate_data(n, p, scenario = 1, model = c("jfm", "jscm"), ...)
n |
Integer. Number of subjects. |
p |
Integer. Number of covariates (should be a multiple of 10 for scenarios 1–3). |
scenario |
Integer. Scenario for true coefficient configuration (1, 2, 3, or other for a simple default). |
model |
Character. Either |
... |
Additional arguments passed to the model-specific function.
For JFM: |
A list with components:
A data frame in recurrent-event format with columns
id, t.start, t.stop, event,
status, and covariate columns x1, ..., xp.
Numeric vector of true alpha coefficients.
Numeric vector of true beta coefficients.
# JFM data with 30 subjects and 10 covariates dat_jfm <- generate_data(n = 30, p = 10, scenario = 1, model = "jfm") head(dat_jfm$data) # JSCM data with 30 subjects and 10 covariates dat_jscm <- generate_data(n = 30, p = 10, scenario = 1, model = "jscm") head(dat_jscm$data)# JFM data with 30 subjects and 10 covariates dat_jfm <- generate_data(n = 30, p = 10, scenario = 1, model = "jfm") head(dat_jfm$data) # JSCM data with 30 subjects and 10 covariates dat_jscm <- generate_data(n = 30, p = 10, scenario = 1, model = "jscm") head(dat_jscm$data)
Generates recurrent-event and terminal-event data under a Cox-type
joint frailty model. Ported from
Data_Generation_time_dependent_new().
generate_data_jfm( n, p, scenario = 1, b = 6.5, lambda0_d = 0.041, lambda0_r = 1, gamma_frailty = 0, cov_type = c("internal", "external", "fixed") )generate_data_jfm( n, p, scenario = 1, b = 6.5, lambda0_d = 0.041, lambda0_r = 1, gamma_frailty = 0, cov_type = c("internal", "external", "fixed") )
n |
Integer. Number of subjects. |
p |
Integer. Number of covariates. |
scenario |
Integer. Scenario (1, 2, 3, or other). |
b |
Numeric. Upper bound of the censoring uniform distribution (default 6.50). |
lambda0_d |
Numeric. Baseline hazard rate for the terminal event (default 0.041). |
lambda0_r |
Numeric. Baseline hazard rate for recurrent events (default 1). |
gamma_frailty |
Numeric. Frailty variance parameter. When positive,
a subject-specific frailty |
cov_type |
Character. How time-varying covariates are generated:
|
Internally the simulation uses the Rondeau et al. (2007) convention
where alpha governs death and beta governs recurrence.
The returned alpha_true and beta_true are relabelled to
match the package-wide convention:
alpha_true: recurrence (readmission) coefficients.
beta_true: terminal (death) coefficients.
Within each subject the covariates are regenerated at each gap time,
yielding time-dependent covariates. Censoring times are
Uniform(1, b).
A list with components:
Data frame with columns id, t.start,
t.stop, event, status, x1, ...,
xp.
True alpha (terminal) coefficients.
True beta (recurrence) coefficients.
dat <- generate_data_jfm(n = 30, p = 10, scenario = 1) head(dat$data) dat$alpha_true dat$beta_truedat <- generate_data_jfm(n = 30, p = 10, scenario = 1) head(dat$data) dat$alpha_true dat$beta_true
Generates recurrent-event and terminal-event data under an AFT-type
joint scale-change model using simGSC.
Ported from Data_gen_reReg().
generate_data_jscm(n, p, scenario = 1, b = 4)generate_data_jscm(n, p, scenario = 1, b = 4)
n |
Integer. Number of subjects. |
p |
Integer. Number of covariates. |
scenario |
Integer. Scenario (1, 2, 3, or other). |
b |
Numeric. Upper bound of the censoring uniform distribution (default 4). |
In the JSCM convention:
alpha governs the recurrence process.
beta governs the terminal (death) process.
Covariates are drawn from Uniform(-1, 1). A gamma frailty with
shape = 4, scale = 1/4 is used. Censoring times are
Uniform(0, b).
A list with components:
Object returned by simGSC (a
data frame with recurrent-event structure).
True alpha (recurrence) coefficients.
True beta (terminal) coefficients.
dat <- generate_data_jscm(n = 30, p = 10, scenario = 1) head(dat$data) dat$alpha_true dat$beta_truedat <- generate_data_jscm(n = 30, p = 10, scenario = 1) head(dat$data) dat$alpha_true dat$beta_true
Plots the cross-validated estimating-equation score norms versus
, with separate lines for the readmission and death
components. A vertical dashed line marks the lambda that minimizes the
combined norm. The top axis shows the total number of active variables
along the path.
## S3 method for class 'swjm_cv' plot(x, log_lambda = TRUE, ...)## S3 method for class 'swjm_cv' plot(x, log_lambda = TRUE, ...)
x |
An object of class |
log_lambda |
Logical. If |
... |
Currently unused. |
Invisibly returns x.
dat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") cv <- cv_stagewise(dat$data, model = "jfm", penalty = "coop", max_iter = 200) plot(cv)dat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") cv <- cv_stagewise(dat$data, model = "jfm", penalty = "coop", max_iter = 200) plot(cv)
Produces a glmnet-style plot of coefficient trajectories versus
along the stagewise regularization path.
Two panels are drawn by default: one for the readmission sub-model
(alpha) and one for the death sub-model (beta). The top axis of
each panel shows the number of active variables at that lambda.
## S3 method for class 'swjm_path' plot( x, log_lambda = TRUE, which = c("both", "readmission", "death"), col = NULL, ... )## S3 method for class 'swjm_path' plot( x, log_lambda = TRUE, which = c("both", "readmission", "death"), col = NULL, ... )
x |
An object of class |
log_lambda |
Logical. If |
which |
Character. Which sub-model(s) to plot:
|
col |
Optional vector of colors, one per covariate. Recycled if
shorter than |
... |
Currently unused. |
Invisibly returns x.
dat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") fit <- stagewise_fit(dat$data, model = "jfm", penalty = "coop", max_iter = 200) plot(fit)dat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") fit <- stagewise_fit(dat$data, model = "jfm", penalty = "coop", max_iter = 200) plot(fit)
Produces a figure for a "swjm_pred" object. The layout depends on
the model:
## S3 method for class 'swjm_pred' plot( x, which_subject = 1L, which_process = c("both", "readmission", "death"), threshold = 0, ... )## S3 method for class 'swjm_pred' plot( x, which_subject = 1L, which_process = c("both", "readmission", "death"), threshold = 0, ... )
x |
An object of class |
which_subject |
Integer. Index of the subject to highlight (default
|
which_process |
Character. Which sub-model(s) to plot:
|
threshold |
Non-negative numeric. Only predictors whose absolute
subject-specific contribution exceeds this value are shown in the bar
chart. The default |
... |
Currently unused. |
JFM (four panels):
Readmission-free survival curves for all subjects, with the selected subject highlighted.
Bar chart of readmission predictor contributions
(log-hazard scale).
Death-free survival curves with the selected subject highlighted.
Bar chart of death predictor contributions .
JSCM (four panels):
Recurrent-event survival curves (AFT model) with the selected
subject highlighted. The panel title shows the total acceleration
factor .
Bar chart of recurrence log time-acceleration contributions
: positive = events sooner, negative = later.
Death-free survival curves with the selected subject highlighted,
total acceleration factor in the title.
Bar chart of terminal-event log time-acceleration contributions
.
In all cases bars represent subject-specific contributions
(coefficient covariate value), not bare coefficients, so the
display correctly reflects how much each predictor shifts the log-hazard
(JFM) or log time-acceleration (JSCM) for this particular subject.
Invisibly returns x.
dat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") cv <- cv_stagewise(dat$data, model = "jfm", penalty = "coop", max_iter = 100) newz <- matrix(rnorm(30), nrow = 3, ncol = 10) pred <- predict(cv, newdata = newz) plot(pred, which_subject = 2) plot(pred, which_subject = 2, threshold = 0.05)dat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") cv <- cv_stagewise(dat$data, model = "jfm", penalty = "coop", max_iter = 100) newz <- matrix(rnorm(30), nrow = 3, ncol = 10) pred <- predict(cv, newdata = newz) plot(pred, which_subject = 2) plot(pred, which_subject = 2, threshold = 0.05)
Computes subject-specific predictions from a cross-validated swjm_cv
fit. The output differs by model:
## S3 method for class 'swjm_cv' predict(object, newdata, times = NULL, ...)## S3 method for class 'swjm_cv' predict(object, newdata, times = NULL, ...)
object |
An object of class |
newdata |
A numeric matrix or data frame of covariate values.
Must have |
times |
Numeric vector of evaluation times (JFM only). If
|
... |
Currently unused. |
JFM — returns survival curves for both processes using the Breslow
cumulative baseline hazards. For subject with covariate vector
:
JSCM — returns survival curves for both processes using a
Nelson-Aalen baseline on the accelerated time scale. For subject :
The linear predictor is a log time-acceleration
factor: the recurrence process for subject runs on a time axis
scaled by relative to the baseline. Each
predictor contributes to this log-scale factor,
so is the multiplicative factor on the time
scale attributable to predictor alone. Values greater than 1
accelerate events (shorter times); values less than 1 decelerate them
(longer times).
An object of class "swjm_pred", a list with:
Matrix of readmission-free survival probabilities
(rows = subjects, columns = times).
Matrix of death-free survival probabilities.
Numeric vector of evaluation times.
Linear predictors for readmission
(). For JSCM this is the log
time-acceleration for the recurrence process.
Linear predictors for death ().
For JSCM this is the log time-acceleration for the terminal process.
(JSCM only) : the
multiplicative factor by which the recurrence time axis is scaled
relative to baseline. NULL for JFM.
(JSCM only) Analogous time-acceleration factor
for the terminal process. NULL for JFM.
Matrix of per-predictor contributions
(rows = subjects, columns = covariates).
For JFM these are log-hazard contributions; for JSCM they are
log time-acceleration contributions.
Analogous matrix for the terminal process.
dat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") cv <- cv_stagewise(dat$data, model = "jfm", penalty = "coop", max_iter = 100) newz <- matrix(rnorm(30), nrow = 3, ncol = 10) pred <- predict(cv, newdata = newz) plot(pred) dat_jscm <- generate_data(n = 50, p = 10, scenario = 1, model = "jscm") cv_jscm <- cv_stagewise(dat_jscm$data, model = "jscm", penalty = "coop", max_iter = 500) pred_jscm <- predict(cv_jscm, newdata = newz) plot(pred_jscm)dat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") cv <- cv_stagewise(dat$data, model = "jfm", penalty = "coop", max_iter = 100) newz <- matrix(rnorm(30), nrow = 3, ncol = 10) pred <- predict(cv, newdata = newz) plot(pred) dat_jscm <- generate_data(n = 50, p = 10, scenario = 1, model = "jscm") cv_jscm <- cv_stagewise(dat_jscm$data, model = "jscm", penalty = "coop", max_iter = 500) pred_jscm <- predict(cv_jscm, newdata = newz) plot(pred_jscm)
Unified interface for stagewise variable selection in joint models of recurrent events and terminal events. Dispatches to model-specific implementations for the Joint Frailty Model (JFM) or Joint Scale-Change Model (JSCM).
stagewise_fit( data, model = c("jfm", "jscm"), penalty = c("coop", "lasso", "group"), eps = NULL, max_iter = NULL, pp = NULL, estimate_frailty = FALSE, standardize = TRUE )stagewise_fit( data, model = c("jfm", "jscm"), penalty = c("coop", "lasso", "group"), eps = NULL, max_iter = NULL, pp = NULL, estimate_frailty = FALSE, standardize = TRUE )
data |
A data frame in recurrent-event format with columns
|
model |
Character. Either |
penalty |
Character. One of |
eps |
Numeric. Step size for the stagewise update. If |
max_iter |
Integer. Maximum number of stagewise iterations. |
pp |
Integer. Early-stopping block size: algorithm checks every
|
estimate_frailty |
Logical. For JFM only: if |
standardize |
Logical. If |
An object of class "swjm_path", a list with components:
Number of iterations performed.
Matrix of coefficient paths (2p rows by
k+1 columns).
Numeric vector of penalty parameter approximations at each iteration.
Numeric vector of penalty norm values along the path.
Character, the model used.
Character, the penalty used.
dat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") fit <- stagewise_fit(dat$data, model = "jfm", penalty = "coop", max_iter = 100) fitdat <- generate_data(n = 50, p = 10, scenario = 1, model = "jfm") fit <- stagewise_fit(dat$data, model = "jfm", penalty = "coop", max_iter = 100) fit