| Title: | Latency Analysis in Epidemiological Studies Using Weighted Cumulative Exposures |
|---|---|
| Description: | Implements weighted cumulative exposure Cox proportional hazards models for latency analysis with repeatedly measured, time-varying exposures. Instead of entering every lagged exposure as a separate and highly correlated covariate, the lag-specific log hazard ratios are constrained to follow a smooth function of the time since exposure, parameterized by natural cubic splines or polynomials, so that the susceptible window of an exposure can be identified from the estimated lag-risk curve. Functions are provided to fit models with a prespecified number of knots or polynomial degree, to select the number of knots by a grid search or the spline terms by a stepwise search using the Akaike or Bayesian information criterion, and to extract lag-specific log hazard ratios with their variances. For the data-driven model selection procedures, inference is based on a cluster bootstrap that resamples subjects, which can be run sequentially or in parallel. The methods are described in Guo, Qian, Wang, Wang, Rosner and Wang (2026) "Taking Into Account the Susceptible Window for Exposures in Cox Proportional Hazards Model: A Way Using Splines to Model the Lag-Risk Relationship" <doi:10.1002/sim.70755>. |
| Authors: | Fuyu Guo [aut, cre], Zihan Qian [aut], Molin Wang [aut] |
| Maintainer: | Fuyu Guo <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.0.2 |
| Built: | 2026-10-22 10:14:34 UTC |
| Source: | https://github.com/cran/LatencyA |
This function implments GridSearch of natural cubic splines in Cox regression for latency analysis This is GreadSearching by knots
CoxKnotsearch( data, time_start, time_end, status, exposure, knots_number, latency, adjusted_variable = NULL, adjusted_model = NULL, criteria = "AIC" )CoxKnotsearch( data, time_start, time_end, status, exposure, knots_number, latency, adjusted_variable = NULL, adjusted_model = NULL, criteria = "AIC" )
data |
A data frame containing the data |
time_start |
start time |
time_end |
end time |
status |
survival status. 1 for death and 0 for censored |
exposure |
Name of the time-varying exposure variable. From the most recent to the furthest in time. |
knots_number |
A vector of potential number of knots |
latency |
pre-specified latency |
adjusted_variable |
A vector of adjusted variables |
adjusted_model |
A vector of adjusted models |
criteria |
A string to specify the criteria for model selection. It can be either "AIC" or "BIC". The default is "AIC" |
A list. The first element is the best knots with the lowest AIC. The second element is a Cox model
time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) # knots can be set as as a vector of potential number of knots, here we use 3 to save time knots_number <- c(3) latency <- 20 fit <- CoxKnotsearch(sim_data, time_start, time_end, status, exposure, knots_number, latency)time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) # knots can be set as as a vector of potential number of knots, here we use 3 to save time knots_number <- c(3) latency <- 20 fit <- CoxKnotsearch(sim_data, time_start, time_end, status, exposure, knots_number, latency)
This function conduct bootstraps for @CoxKnotsearch
CoxKnotsearch_boot( data, time_start, time_end, status, exposure, knots_number, latency, adjusted_variable = NULL, adjusted_model = NULL, lag, parallel = FALSE, parallel_plan = c("multicore", "multisession"), boot_iter = 10, id = "id", criteria = "AIC" )CoxKnotsearch_boot( data, time_start, time_end, status, exposure, knots_number, latency, adjusted_variable = NULL, adjusted_model = NULL, lag, parallel = FALSE, parallel_plan = c("multicore", "multisession"), boot_iter = 10, id = "id", criteria = "AIC" )
data |
A data frame containing the data |
time_start |
start time |
time_end |
end time |
status |
survival status. 1 for death and 0 for censored |
exposure |
Name of the time-varying exposure variable. From the most recent to the furthest in time. |
knots_number |
A vector of prespecified knot number |
latency |
prespecified latency |
adjusted_variable |
A vector of adjusted variables |
adjusted_model |
A vector of adjusted models |
lag |
A value of lag time |
parallel |
A boolean numeric to indicate whether to run the function in parallel |
parallel_plan |
A string to specify the future plan used when parallel = TRUE. It can be either "multicore" or "multisession". The default is "multicore" |
boot_iter |
Number of bootstrap iterations |
id |
A string of the column name that contains the subject ID |
criteria |
A string to specify the criteria for model selection. It can be either "AIC" or "BIC". The default is "AIC" |
A data.frame. The first column is the mean of log HR. The second column is the variance of log HR, the third and fourth columns are the 2.5 and 97.5 percentiles of log HR if parallel = TRUE
time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:15) # knots can be set as as a vector of potential number of knots, here we use 3 to save time knots_number <- c(3) latency <- 16 adjusted_variable <- "L" adjusted_model <- "L" lag <- 2 boot_iter <- 2 id <- "id" # use a subset of subjects to keep the example fast ids <- unique(sim_data$id)[1:300] small_data <- sim_data[sim_data$id %in% ids, ] result <- CoxKnotsearch_boot(small_data, time_start, time_end, status, exposure, knots_number = knots_number, latency, lag = lag, parallel = FALSE, boot_iter = boot_iter, id = id) # the bootstrap can also be run in parallel result <- CoxKnotsearch_boot(small_data, time_start, time_end, status, exposure, knots_number = knots_number, latency, lag = lag, parallel = TRUE, boot_iter = boot_iter, id = id)time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:15) # knots can be set as as a vector of potential number of knots, here we use 3 to save time knots_number <- c(3) latency <- 16 adjusted_variable <- "L" adjusted_model <- "L" lag <- 2 boot_iter <- 2 id <- "id" # use a subset of subjects to keep the example fast ids <- unique(sim_data$id)[1:300] small_data <- sim_data[sim_data$id %in% ids, ] result <- CoxKnotsearch_boot(small_data, time_start, time_end, status, exposure, knots_number = knots_number, latency, lag = lag, parallel = FALSE, boot_iter = boot_iter, id = id) # the bootstrap can also be run in parallel result <- CoxKnotsearch_boot(small_data, time_start, time_end, status, exposure, knots_number = knots_number, latency, lag = lag, parallel = TRUE, boot_iter = boot_iter, id = id)
This function implments natural cubic splines in Cox regression for latency analysis
CoxNCSpline( data, time_start, time_end, status, exposure, knots_number, latency, adjusted_variable = NULL, adjusted_model = NULL, id = "id" )CoxNCSpline( data, time_start, time_end, status, exposure, knots_number, latency, adjusted_variable = NULL, adjusted_model = NULL, id = "id" )
data |
A data frame containing the data |
time_start |
start time |
time_end |
end time |
status |
survival status. 1 for death and 0 for censored |
exposure |
Name of the time-varying exposure variable. From the most recent to the furthest in time. |
knots_number |
Pre-specified number of knots |
latency |
prespecified latency |
adjusted_variable |
A vector of adjusted variables |
adjusted_model |
A vector of adjusted models |
id |
A string to specify the name of the id column |
A list. The first element is the best knots with the lowest AIC. The second element is a Cox model
time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) knots_number <- 3 latency <- 20 fit <- CoxNCSpline(sim_data, time_start, time_end, status, exposure, knots_number, latency)time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) knots_number <- 3 latency <- 20 fit <- CoxNCSpline(sim_data, time_start, time_end, status, exposure, knots_number, latency)
This is a function to implement polynomial Cox regression for latency analysis
CoxPoly( data, time_start, time_end, status, exposure, degree, latency, adjusted_variable = NULL, adjusted_model = NULL, id = "id" )CoxPoly( data, time_start, time_end, status, exposure, degree, latency, adjusted_variable = NULL, adjusted_model = NULL, id = "id" )
data |
A data frame containing the data |
time_start |
start time |
time_end |
end time |
status |
survival status. 1 for death and 0 for censored |
exposure |
Name of the time-varying exposure variable. From the most recent to the furthest in time. |
degree |
degree of the polynomial |
latency |
prespecified latency |
adjusted_variable |
A vector of adjusted variables |
adjusted_model |
A vector of adjusted models |
id |
A string to specify the name of the id column |
A Cox model object
time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) degree <- 3 latency <- 20 fit <- CoxPoly(sim_data, time_start, time_end, status, exposure, degree, latency) fittime_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) degree <- 3 latency <- 20 fit <- CoxPoly(sim_data, time_start, time_end, status, exposure, degree, latency) fit
This function implments Stepwise model selection by terms of natural cubic splines in Cox regression for latency analysis This is GreadSearching by knots
CoxTermsearch( data, time_start, time_end, status, exposure, knots, latency, adjusted_variable = NULL, adjusted_model = NULL, criteria = "AIC" )CoxTermsearch( data, time_start, time_end, status, exposure, knots, latency, adjusted_variable = NULL, adjusted_model = NULL, criteria = "AIC" )
data |
A data frame containing the data |
time_start |
start time |
time_end |
end time |
status |
survival status. 1 for death and 0 for censored |
exposure |
Name of the time-varying exposure variable. From the most recent to the furthest in time. |
knots |
A vector of prespecified knots |
latency |
prespecified latency |
adjusted_variable |
A vector of adjusted variables |
adjusted_model |
A vector of adjusted models |
criteria |
A string to specify the criteria for model selection. It can be either "AIC" or "BIC". The default is "AIC" |
A list. The first element is the best knots with the lowest AIC. The second element is a Cox model
time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:15) knots <- seq(0, 15, by = 3) latency <- 16 adjusted_variable <- "L" adjusted_model <- "L" fit <- CoxTermsearch(sim_data, time_start, time_end, status, exposure, knots = knots, latency) #In this example, we will generate a random covariate L and adjust for it in our model sim_data$L <- rbinom(nrow(sim_data), 1, 0.5) adjusted_variable <- "L" adjusted_model <- "L+I(L^2)" fit <- CoxTermsearch(sim_data, time_start, time_end, status, exposure, knots = knots, latency, adjusted_variable = adjusted_variable, adjusted_model = adjusted_model) #L is selected into the final model but L^2 was nottime_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:15) knots <- seq(0, 15, by = 3) latency <- 16 adjusted_variable <- "L" adjusted_model <- "L" fit <- CoxTermsearch(sim_data, time_start, time_end, status, exposure, knots = knots, latency) #In this example, we will generate a random covariate L and adjust for it in our model sim_data$L <- rbinom(nrow(sim_data), 1, 0.5) adjusted_variable <- "L" adjusted_model <- "L+I(L^2)" fit <- CoxTermsearch(sim_data, time_start, time_end, status, exposure, knots = knots, latency, adjusted_variable = adjusted_variable, adjusted_model = adjusted_model) #L is selected into the final model but L^2 was not
This function conduct bootstraps for @CoxTermsearch
CoxTermsearch_boot( data, time_start, time_end, status, exposure, knots, latency, adjusted_variable = NULL, adjusted_model = NULL, lag, parallel = FALSE, parallel_plan = c("multicore", "multisession"), boot_iter = 10, id = "id", criteria = "AIC" )CoxTermsearch_boot( data, time_start, time_end, status, exposure, knots, latency, adjusted_variable = NULL, adjusted_model = NULL, lag, parallel = FALSE, parallel_plan = c("multicore", "multisession"), boot_iter = 10, id = "id", criteria = "AIC" )
data |
A data frame containing the data |
time_start |
start time |
time_end |
end time |
status |
survival status. 1 for death and 0 for censored |
exposure |
Name of the time-varying exposure variable. From the most recent to the furthest in time. |
knots |
A vector of prespecified knots |
latency |
prespecified latency |
adjusted_variable |
A vector of adjusted variables |
adjusted_model |
A vector of adjusted models |
lag |
A value of lag time |
parallel |
A boolean numeric to indicate whether to run the function in parallel |
parallel_plan |
A string to specify the future plan used when parallel = TRUE. It can be either "multicore" or "multisession". The default is "multicore" |
boot_iter |
Number of bootstrap iterations |
id |
A string of the column name that contains the subject ID |
criteria |
A string to specify the criteria for model selection. It can be either "AIC" or "BIC". The default is "AIC" |
A data.frame. The first column is the mean of log HR. The second column is the variance of log HR, the third and fourth columns are the 2.5 and 97.5 percentiles of log HR if parallel = TRUE
time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:15) knots <- seq(0, 15, by = 3) latency <- 16 adjusted_variable <- "L" adjusted_model <- "L" lag <- 2 boot_iter <- 2 id <- "id" # use a subset of subjects to keep the example fast ids <- unique(sim_data$id)[1:300] small_data <- sim_data[sim_data$id %in% ids, ] result <- CoxTermsearch_boot(small_data, time_start, time_end, status, exposure, knots = knots, latency, lag = lag, parallel = FALSE, boot_iter = boot_iter, id = id) # the bootstrap can also be run in parallel result <- CoxTermsearch_boot(small_data, time_start, time_end, status, exposure, knots = knots, latency, lag = lag, parallel = TRUE, boot_iter = boot_iter, id = id)time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:15) knots <- seq(0, 15, by = 3) latency <- 16 adjusted_variable <- "L" adjusted_model <- "L" lag <- 2 boot_iter <- 2 id <- "id" # use a subset of subjects to keep the example fast ids <- unique(sim_data$id)[1:300] small_data <- sim_data[sim_data$id %in% ids, ] result <- CoxTermsearch_boot(small_data, time_start, time_end, status, exposure, knots = knots, latency, lag = lag, parallel = FALSE, boot_iter = boot_iter, id = id) # the bootstrap can also be run in parallel result <- CoxTermsearch_boot(small_data, time_start, time_end, status, exposure, knots = knots, latency, lag = lag, parallel = TRUE, boot_iter = boot_iter, id = id)
This is a function to extract log HR based on the resuls from CoxKnotsearch
extract_CoxKnotsearch(fit, lag, latency)extract_CoxKnotsearch(fit, lag, latency)
fit |
A model from CoxKnotsearch |
lag |
A lag time, or a vector of lag times |
latency |
prespecified latency |
A data frame with one row per lag, giving the estimated log HR at each lag time
time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) # knots can be set as as a vector of potential number of knots, here we use 3 to save time knots_number <- c(3) latency <- 20 fit <- CoxKnotsearch(sim_data, time_start, time_end, status, exposure, knots_number, latency) extract_CoxKnotsearch(fit, 10, latency = latency) extract_CoxKnotsearch(fit, c(0, 5, 10), latency = latency)time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) # knots can be set as as a vector of potential number of knots, here we use 3 to save time knots_number <- c(3) latency <- 20 fit <- CoxKnotsearch(sim_data, time_start, time_end, status, exposure, knots_number, latency) extract_CoxKnotsearch(fit, 10, latency = latency) extract_CoxKnotsearch(fit, c(0, 5, 10), latency = latency)
This is a function to extract log HR based on the resuls from CoxNCSpline
extract_CoxNCSpline(fit, lag, latency)extract_CoxNCSpline(fit, lag, latency)
fit |
A model from CoxNCSpline |
lag |
A lag time, or a vector of lag times |
latency |
prespecified latency |
A data frame with one row per lag, giving the estimated log HR and its variance at each lag time
time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) knots_number <- 3 latency <- 20 fit <- CoxNCSpline(sim_data, time_start, time_end, status, exposure, knots_number, latency) extract_CoxNCSpline(fit, 10, latency = latency) extract_CoxNCSpline(fit, c(0, 5, 10), latency = latency)time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) knots_number <- 3 latency <- 20 fit <- CoxNCSpline(sim_data, time_start, time_end, status, exposure, knots_number, latency) extract_CoxNCSpline(fit, 10, latency = latency) extract_CoxNCSpline(fit, c(0, 5, 10), latency = latency)
This is a function to extract log HR based on the resuls from CoxPoly
extract_CoxPoly(fit, lag)extract_CoxPoly(fit, lag)
fit |
A model from CoxPoly |
lag |
A lag time, or a vector of lag times |
A data frame with one row per lag, giving the estimated log HR and its variance at each lag time
time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) degree <- 3 latency <- 20 fit <- CoxPoly(sim_data, time_start, time_end, status, exposure, degree, latency) extract_CoxPoly(fit, 10) extract_CoxPoly(fit, c(0, 5, 10))time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) degree <- 3 latency <- 20 fit <- CoxPoly(sim_data, time_start, time_end, status, exposure, degree, latency) extract_CoxPoly(fit, 10) extract_CoxPoly(fit, c(0, 5, 10))
This is a function to extract log HR based on the resuls from CoxTermsearch
extract_CoxTermsearch(fit, lag, latency, knots)extract_CoxTermsearch(fit, lag, latency, knots)
fit |
A model from CoxKnotsearch |
lag |
A lag time, or a vector of lag times |
latency |
prespecified latency |
knots |
A vector of prespecified knots |
A data frame with one row per lag, giving the estimated log HR at each lag time
time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) knots <- seq(0, 15, by = 3) latency <- 20 fit <- CoxTermsearch(sim_data, time_start, time_end, status, exposure, knots = knots, latency) extract_CoxTermsearch(fit, 10, latency = latency, knot = knots) extract_CoxTermsearch(fit, c(0, 5, 10), latency = latency, knot = knots) #In this example, we will generate a random covariate L and adjust for it in our model sim_data$L <- rbinom(nrow(sim_data), 1, 0.5) adjusted_variable <- "L" adjusted_model <- "L+I(L^2)" fit <- CoxTermsearch(sim_data, time_start, time_end, status, exposure, knots = knots, latency, adjusted_variable = adjusted_variable, adjusted_model = adjusted_model) #L is selected into the final model but L^2 was not extract_CoxTermsearch(fit, 10, latency = latency, knot = knots)time_start <- "age_start" time_end <- "age_end" status <- "failure" exposure <- paste0("lag", 0:19) knots <- seq(0, 15, by = 3) latency <- 20 fit <- CoxTermsearch(sim_data, time_start, time_end, status, exposure, knots = knots, latency) extract_CoxTermsearch(fit, 10, latency = latency, knot = knots) extract_CoxTermsearch(fit, c(0, 5, 10), latency = latency, knot = knots) #In this example, we will generate a random covariate L and adjust for it in our model sim_data$L <- rbinom(nrow(sim_data), 1, 0.5) adjusted_variable <- "L" adjusted_model <- "L+I(L^2)" fit <- CoxTermsearch(sim_data, time_start, time_end, status, exposure, knots = knots, latency, adjusted_variable = adjusted_variable, adjusted_model = adjusted_model) #L is selected into the final model but L^2 was not extract_CoxTermsearch(fit, 10, latency = latency, knot = knots)
This is a function to help resemple clusters for bootstrap. It is adapted from the function "clusterboot" in the R package "fpc".
resample_clusters(data, id = "id")resample_clusters(data, id = "id")
data |
A data frame containing the data |
id |
A string of the column name that contains the subject ID |
A data frame with the same structure as the input data, but with resampled clusters
example A simulated data for the use of example
sim_datasim_data
An object of class data.frame with 9246 rows and 38 columns.