---
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.