The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

ccwr

ccwr is an R package for building reproducible clone-censor-weight (CCW) workflows for target trial emulation.

This repository is meant to be easy to use from a fresh GitHub clone and easy to maintain as a shared collaboration project. The recommended setup uses:

Quick start

1. Clone the repository

git clone https://github.com/CausalInferenceLab/ccwr.git
cd ccwr

2. Use rig to install R 4.4.2

This project is pinned to R 4.4.2 for reproducibility.

rig add 4.4.2
rig default 4.4.2

If you already have R 4.4.2, you can skip rig add 4.4.2.

3. Restore the project package library with renv

Open R in the project directory and run:

install.packages("renv")
renv::restore()

renv::restore() installs the package versions recorded in renv.lock, so everyone works with the same dependency set.

Note: this repository includes a .Rprofile file that activates renv automatically when you open the project in R.

4. Install the package locally

From the project root:

R CMD INSTALL .

Then in R:

library(ccwr)

First example

library(ccwr)

data(lungcancer)

arms <- c("Control", "Surgery")
clones <- clone_arms(lungcancer, arms)

policies <- create_policy_A(
  arms,
  treatment = "surgery",
  time_to_treatment = "timetosurgery",
  grace_period = 182.62,
  outcome = "death",
  followup = "fup_obs",
  clone_outcome = "outcome",
  clone_followup = "fup"
)
clones_policy <- apply_logics(clones, policies)

censoring_logics <- create_censoring_logics_A(
  arms,
  treatment = "surgery",
  time_to_treatment = "timetosurgery",
  grace_period = 182.62,
  followup = "fup_obs",
  clone_censoring = "censoring",
  clone_uncensored_followup = "fup_uncensored"
)
clones_censored <- apply_logics(clones_policy, censoring_logics)

fup_uncensored is the strategy-specific follow-up time for the censoring rules. It remains the observed follow-up time when a clone adheres to its assigned strategy and is set to the artificial-censoring time only when that clone deviates from the strategy.

clones_final <- create_final_data(
  clones_censored,
  clone_followup = "fup",
  clone_outcome = "outcome",
  clone_censoring = "censoring",
  col_ids = "id"
)

clones_estimated <- estimate_censoring(
  clones_final,
  predictors = c("age", "sex"),
  method = "pooled_logit"
)
clones_weighted <- weight_cases(clones_estimated)

fit <- emul_estimate(
  clones_weighted,
  method = "Cox",
  weights = "weight_Cox",
  predictors = c("age", "sex")
)

exp(stats::coef(fit))

boot <- emul_estimate_bootstrap(
  lungcancer,
  arms = arms,
  id = "id",
  treatment = "surgery",
  time_to_treatment = "timetosurgery",
  grace_period = 182.62,
  outcome = "death",
  followup = "fup_obs",
  censoring_predictors = c("age", "sex"),
  predictors = c("age", "sex"),
  n_bootstrap = 200,
  seed = 1
)

The full process is:

  1. Clone each patient into the target trial arms with clone_arms().
  2. Define and apply treatment-policy logic with create_policy_A() and apply_logics().
  3. Define and apply artificial censoring logic with create_censoring_logics_A() and apply_logics().
  4. Expand cloned observations into long-form interval data with create_final_data().
  5. Estimate censoring probabilities with estimate_censoring().
  6. Add inverse probability of censoring weights with weight_cases().
  7. Estimate the emulated trial effect with emul_estimate().
  8. Use emul_estimate_bootstrap() to resample the original subjects and repeat the complete workflow when bootstrap confidence intervals are needed.

Pooled-logistic censoring models use a linear interval-start-time term by default. Set time_spline_df = 3 in estimate_censoring(), or censoring_time_spline_df = 3 in emul_estimate_bootstrap(), to use a natural cubic spline when the censoring data contain enough events to support the additional flexibility.

What the package currently provides

The package currently supports two-arm grace-period strategies for subject-level observational time-to-event data. It includes:

Working together on this repository

For collaborative work, the safest pattern is:

  1. Clone the repository.
  2. Switch to R 4.4.2 with rig.
  3. Run renv::restore().
  4. Make your changes in a branch.
  5. Run checks before opening a pull request.

Useful commands:

R CMD INSTALL .
R CMD check --no-manual .

In R:

testthat::test_local()

If you add, remove, or upgrade dependencies, update the lockfile from R:

renv::settings$snapshot.type("explicit")
renv::status(dev = TRUE)
renv::snapshot(dev = TRUE)

Please commit both code changes and the updated renv.lock when dependency changes are intentional.

Continuous integration

This repository includes two GitHub Actions workflows:

Together, these workflows help keep the project reproducible for collaborators and stable for future users.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.