# concordance_index_incidence()


IPCW concordance index for cause-specific cumulative incidence.


Usage

``` python
concordance_index_incidence(
    surv,
    incidence_prob,
    *,
    data=None,
    cause,
    tau=None,
)
```


Measures how well predicted cumulative incidence probabilities for a specific cause discriminate between subjects who experience that cause and those who do not. This extends the IPCW concordance to competing risks by considering two types of comparable pairs: standard pairs (event-of-interest vs. still-at-risk) and competing-event pairs (event-of-interest vs. competing event).

**Interpretation**:

- 0.5: Random discrimination (predicted CIF carries no information about cause ordering).

- > 0.5: Better-than-random. Subjects who experience the cause tend to have higher predicted CIF.

- 1.0: Perfect discrimination.


## Parameters


`surv: Surv | Outcome | str`  
A multi-state [Surv](Surv.md#greenwood.Surv) response (from `gw.Surv()` with a categorical event). An [Outcome](Outcome.md#greenwood.Outcome) or a formula response such as `'Surv(time, status == 2)'` is also accepted, with its columns read from `data`.

`incidence_prob: Any`  
Predicted cumulative incidence probability for the cause of interest at the evaluation time `tau`, one value per subject. Higher values should indicate a higher predicted probability of experiencing the cause. Accepts a 1-D array, Pandas/Polars Series, or Python sequence.

`cause: int`  
The cause of interest, as an integer event code from the [Surv](Surv.md#greenwood.Surv) response.

`tau: float | None = None`  
Truncation time. Only subjects with events before `tau` contribute as cases. Defaults to the largest observed time for the cause of interest.

`data: Any = None`  
A data frame (pandas, Polars, PyArrow, DuckDB, a lazy frame, …) holding the columns named by the response and `incidence_prob`. When `surv` is an [Outcome](Outcome.md#greenwood.Outcome) or a formula, rows with a missing value in any column used are dropped first, along with the matching rows of any arrays passed alongside.


## Returns


`float`  
Concordance index between 0 and 1.


## Details

Two types of comparable pairs contribute to the concordance:

- **Type A** (standard survival pairs): Subject i experienced cause k at T_i, and subject j is still at risk at T_i (T_j \> T_i). Weighted by 1 / \hat{G}(T_i)^2.
- **Type B** (competing-event pairs): Subject i experienced cause k at T_i, and subject j experienced a competing event at T_j \le T_i. Weighted by 1 / (\hat{G}(T_i) \cdot \hat{G}(T_j)).

A pair is concordant if the subject with the cause of interest has a higher predicted CIF than the comparator. IPCW weights correct for censoring bias by reweighting pairs according to the inverse censoring probability.


## Examples

Name the competing endpoints in the `mgus2` dataset and evaluate the concordance of a marginal Aalen-Johansen CIF as a naive baseline:


``` python
import greenwood as gw
import numpy as np

# The first of progression (PCM) or death, each with its own time and status columns
mgus2 = gw.load_dataset("mgus2", backend="polars")
first = gw.Outcome.first_event(
    endpoints={"pcm": ("ptime", "pstat"), "death": ("futime", "death")}
)

# Fit Aalen-Johansen for the marginal CIF
aj = gw.AalenJohansen().fit(first, data=mgus2)
cif_df = aj.to_frame(format="polars")
pcm_cif = cif_df.filter(cif_df["cause"] == "pcm")

# Marginal CIF at tau=240 months as a naive predictor (same value for everyone)
tau = 240.0
marginal_at_tau = float(
    np.interp(tau, pcm_cif["time"].to_numpy(), pcm_cif["estimate"].to_numpy())
)
pred = np.full(mgus2.height, marginal_at_tau)

c = gw.concordance_index_incidence(
    first, incidence_prob=pred, cause=1, tau=tau, data=mgus2
)
c
```


    np.float64(0.49999999999999994)
