---
title: "ROC Curves and Diagnostic Accuracy with ggrocplot()"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{ROC Curves and Diagnostic Accuracy with ggrocplot()}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 5.5,
  fig.height = 5,
  dpi = 96,
  message = FALSE,
  warning = FALSE
)
```

A **receiver operating characteristic (ROC) curve** shows how well a continuous
marker or score separates two groups, across every possible cut-point. The area
under the curve (**AUC**) summarizes it in one number: 0.5 is no better than
chance, 1.0 is perfect. `ggrocplot()` draws a publication-ready ROC with the AUC
and its confidence interval annotated, and can overlay several markers for
comparison -- all in base R, with no modeling dependency.

```{r libs}
library(ggpubr)

# A small biomarker study: disease status and two candidate markers
set.seed(2024)
n <- 120
dx <- data.frame(
  status = factor(
    rep(c("healthy", "diseased"), each = n / 2),
    levels = c("healthy", "diseased") # "diseased" = the positive class
  ),
  marker_A = c(rnorm(n / 2, 0), rnorm(n / 2, 1.4)),
  marker_B = c(rnorm(n / 2, 0), rnorm(n / 2, 0.6))
)
```

## A single ROC curve

Pass the outcome (`response`) and the marker (`predictor`). The AUC and its 95%
confidence interval -- computed in closed form (Hanley and McNeil, 1982) -- are
printed on the plot.

```{r single}
ggrocplot(dx, response = "status", predictor = "marker_A")
```

The curve bows toward the top-left corner; the further from the diagonal (the
grey chance line), the better the marker. Here the AUC is well above 0.5, so
higher `marker_A` values indicate disease.

### Which way round? The positive class and AUC below 0.5

`ggrocplot()` treats the **second factor level** of `response` as the positive
class and assumes **higher predictor values** indicate it -- it never silently
flips the curve. If a marker is *lower* in cases, its AUC comes out below 0.5 and
you get a message suggesting you reverse the predictor (or the factor levels):

```{r reversed, message = TRUE}
# A protective marker: LOWER values indicate disease
dx$marker_low <- c(rnorm(n / 2, 1), rnorm(n / 2, 0))

ggrocplot(dx, response = "status", predictor = "marker_low")
```

Negate the predictor to orient it (`transform()` a new column, or pass a
pre-negated one) and the AUC flips above 0.5:

```{r reversed-fixed}
dx$marker_low_rev <- -dx$marker_low
ggrocplot(dx, response = "status", predictor = "marker_low_rev")
```

## The optimal cut-point

For a diagnostic threshold, `youden = TRUE` marks the point that maximizes the
**Youden index** (sensitivity + specificity - 1) -- the cut-point furthest above
the chance line -- and labels its value:

```{r youden}
ggrocplot(dx, response = "status", predictor = "marker_A", youden = TRUE)
```

## Comparing several markers

Pass several predictors to overlay their curves on one plot; the legend shows
each marker's AUC and CI, so you can compare discriminative ability at a glance:

```{r compare, fig.width = 6}
ggrocplot(
  dx,
  response = "status",
  predictor = c("marker_A", "marker_B"),
  palette = "jco"
)
```

`marker_A` (the higher AUC) is the better discriminator. Customize with
`palette`, `linetype`, `size`, `legend`/`legend.title`, and toggle the diagonal
(`diag`), the AUC print-out (`print.auc`) or the CI (`ci`).

## Notes

- The empirical ROC, the AUC (equal to the Mann-Whitney statistic) and the
  large-sample CI are all computed in base R, so `ggrocplot()` has no modeling
  dependency and runs in lightweight environments.
- For DeLong or bootstrap confidence intervals, ROC smoothing, or formal tests
  between curves, use the `pROC` package.

See `?ggrocplot` for the full argument list.
