--- title: "Overview" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Overview} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup01, include=FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "fig/overview-", fig.ext = "png", fig.width = 6, fig.height = 4, dpi = 300, fig.retina = 2, fig.align = "center", out.width = "70%" ) if (requireNamespace("cifmodeling", quietly = TRUE)) { library(cifmodeling) } else { stop("Package 'cifmodeling' is not available during vignette build.") } library(nleqslv) library(boot) library(ggplot2) library(ggsurvfit) library(patchwork) data("diabetes.complications", package = "cifmodeling") set.seed(1) ``` ## Quick start Are you comfortable writing `Surv(time, status) ~ strata` but hesitant to dive into the Fine-Gray models or custom `ggplot2` code? **cifmodeling** helps clinicians, epidemiologists, and applied researchers move from basic Kaplan-Meier curves to clear, publication-ready survival and competing risk plots – with just a few lines of R. It provides a unified, high-level interface for survival and competing risks analysis, combining nonparametric estimation, regression modeling, and visualization. ```{r example01-1, fig.cap="Aalen-Johansen cumulative incidence curves from cifplot()", warning=FALSE, message=FALSE} library(cifmodeling) data(diabetes.complications) cifplot(Event(t,epsilon)~fruitq, data=diabetes.complications, outcome.type="competing-risk", panel.per.event=TRUE) ``` In competing risks data, censoring is often coded as 0, the event of interest as 1, and competing risks as 2. In the `diabetes.complications` data frame, `epsilon` follows this convention. With `panel.per.event = TRUE`, `cifplot()` visualizes both competing events, with the CIF of diabetic retinopathy (`epsilon = 1`) shown on the left and the CIF of macrovascular complications (`epsilon = 2`) on the right. ## Why cifmodeling? In clinical and epidemiologic research, analysts often need to handle censoring, competing risks, and intercurrent events (e.g. treatment switching), but existing R packages typically separate these tasks across different interfaces. **cifmodeling** provides a unified, publication-ready toolkit that integrates nonparametric estimation, regression modeling, and visualization for survival and competing risks data. The tools assist users in the following ways: - **Unified interface** for the Kaplan–Meier and Aalen–Johansen curves, with survival and competing risks handled by the same `Event()` + formula + data syntax. - **Effects on the CIF scale**: while the Fine-Gray models subdistribution hazards, `polyreg()` directly targets ratios of CIFs (risk ratios, odds ratios, subdistribution hazard ratios), so parameters align closely with differences seen in CIF curves. - **Coherent, joint modeling of all competing events**: `polyreg()` models all cause-specific CIFs together, parameterizing the nuisance structure with polytomous log odds products and enforcing that their CIFs sum to at most one. - **Tidy summaries and reporting**: support for `generics::tidy()`, `glance()`, and `augment()`, which integrate `polyreg()` smoothly with `modelsummary` and other broom-style tools. - **Publication-ready graphics** built on `ggsurvfit` and `ggplot2`, including number-at-risk/CIF+CI tables, censoring/competing-risk/intercurrent-event marks, and multi-panel layouts. ## Tools for survival and competing risks analysis The **cifmodeling** package is centered around three tightly connected functions: - `cifplot()` generates a survival or cumulative incidence function (CIF) curve. The visualization is built on top of `ggsurvfit` and `ggplot2`. - `cifpanel()` creates multi-panel displays for survival/CIF curves, arranged either **in a grid layout or as an inset overlay**. - `polyreg()` fits **coherent regression models** on all cause-specific CIFs simultaneously to estimate RR/OR/SHR, offering a practical complement to Fine-Gray. These functions adopt a formula + data syntax, return tidy, publication-ready outputs, and integrate seamlessly with `ggsurvfit` and `modelsummary` for visualization and reporting. > **Explore the main features visually:** > See the [Gallery](https://gestimation.github.io/cifmodeling/articles/gallery.html) for a curated set of examples using `cifplot()` and `cifpanel()`. > **Interested in the precise variance formulas and influence functions for the Aalen-Johansen estimator?** > Visit [Computational formulas in cifcurve()](https://gestimation.github.io/cifmodeling/articles/formulas.html). > **Learn the modeling framework with `polyreg()`:** > See the [Direct polytomous regression](https://gestimation.github.io/cifmodeling/articles/polyreg.html) for coherent, joint modeling of all cause-specific CIFs. > **Prefer to build intuition before diving into code?** > Visit the *Coffee and Research – Story and Quiz* series for narrative-style introductions to study design, survival and competing risks analysis, and frequentist and causality thinking: > ## Position in the survival ecosystem Several excellent R packages exist for survival and competing risks analysis. The **survival** package provides the canonical API for survival data. In combination with the **ggsurvfit** package, `survival::survfit()` can produce publication-ready survival plots. For CIF plots, however, integration in the general ecosystem is less streamlined. **cifmodeling** fills this gap by offering `cifplot()` for survival/CIF plots and multi-panel figures via a single, unified interface. Beyond providing a unified interface, `cifcurve()` also extends `survfit()` in a few targeted ways. For unweighted survival data, it reproduces the standard Kaplan-Meier estimator with **Greenwood and Tsiatis SEs** and a unified set of CI transformations. For competing risks data, it computes Aalen-Johansen CIFs with both **Aalen-type and delta-method SEs**. For weighted survival or competing risks data (e.g. inverse probability weighting), it implements **influence-function based SEs** (Deng and Wang 2025) as well as **modified Greenwood- and Tsiatis-type SEs** (Xie and Liu 2005), which are valid under general positive weights. If you need very fine-grained plot customization, you can compute the estimator and keep a survfit-compatible object with `cifcurve()` (or supply your own survfit object) and then style it using `ggsurvfit/ggplot2` layers. In other words: - use `cifcurve()` for estimation, - use `cifplot()` / `cifpanel()` for quick, high-quality figures, and - fall back to the `ggplot` ecosystem when you want full artistic control. The **causalRisk** package offers IPW-based estimation of counterfactual cumulative risks and hazards. It is most relevant when treatment, censoring, and missingness mechanisms must be modeled explicitly. In contrast, **cifmodeling** focuses on nonparametric estimation and direct CIF regression rather than structural causal models. The **mets** package is a more specialized toolkit that provides advanced methods for competing risks analysis. `cifmodeling::polyreg()` focuses on coherent modeling of all CIFs simultaneously to estimate the exposure effects in terms of RR/OR/SHR. This coherence can come with longer runtimes for large problems. If you prefer fitting separate regression models for each competing event or specifically need the Fine-Gray models (Fine and Gray 1999) and the direct binomial models (Scheike, Zhang and Gerds 2008), `mets::cifreg()` and `mets::binreg()` are excellent choices. In short, **cifmodeling** provides a unified high-level grammar for estimation, visualization, and direct CIF regression — something no existing package currently offers in one place. | Function | cifmodeling | survival | cmprsk | mets | ggsurvfit | |-------------------------------------|--------------------------|-----------------------------------|----------------|--------------------------|------------------| | AJ estimator | Yes | Yes (multistate `survfit`) | Yes (`cuminc`) | Yes | Depends on input | | Weighted AJ estimator and valid SE | Yes (IPW + IF-based SE) | Yes (case weights / robust SE) | No | Yes (IPW + IF-based SE) | Depends on input | | Gray test | No | No (only log-rank via `survdiff`) | Yes (`cuminc`) | No | `tidycmprsk::glance()` + `add_pvalue()`| | Fine–Gray model | No | `finegray`+`coxph` | `crr` | `cifregFG` | No | | Direct CIF regression | `polyreg` | No | No | `cifreg`, `binreg` | No | | Surv()/Event() interface | Yes (`Event`, `Surv`) | Yes (`Surv`) | No (`ftime`/`fstatus`) | Yes (`Event`, `Surv`) | Yes (`Surv`, `ggcuminc` + tidiers) | | Publication-ready survival/CIF plot | Yes (`cifplot`, `cifpanel`) | `plot` (base) | `plot.cuminc` (base) | `plot` (base) | Designed for publication | | Support for tidy/glance/augment | Yes (`polyreg` + methods) | Yes (via **broom**) | Yes (via **tidycmprsk**) | No | Yes (via **broom**) | ## Installation The package is implemented in R and relies on `Rcpp`, `nleqslv` and `boot` for its numerical back-end. The examples in this document also use `ggplot2`, `ggsurvfit`, `patchwork` and `modelsummary` for tabulation and plotting. Install the core package and these companion packages with: ``` r # Install cifmodeling with core dependencies install.packages(c("cifmodeling", "Rcpp", "nleqslv", "boot")) # Recommended packages for plotting and tabulation in this README install.packages(c("ggplot2", "ggsurvfit", "patchwork", "modelsummary")) ``` ## Quality control **cifmodeling** includes an extensive test suite built with **testthat**, which checks the numerical accuracy and graphical consistency of all core functions (`cifcurve()`, `cifplot()`, `cifpanel()`, and `polyreg()`). The estimators are routinely compared against related functions in **survival**, **cmprsk** and **mets** packages to ensure consistency. The package is continuously tested on GitHub Actions (Windows, macOS, Linux) to maintain reproducibility and CRAN-level compliance.