# circlecorR <img src="man/figures/logo.svg" align="right" height="139" alt="circlecorR logo" />

<!-- badges: start -->
<!-- badges: end -->

**Circular correlation "wheel" plots in native R.**

`circlecorR` draws **correlation wheel** plots with variables arranged around a
ring, grouped and colour-tiled by category, connected by curved links whose
colour maps to the correlation coefficient using
[`circlize`](https://github.com/jokergoo/circlize).

A traditional correlation matrix is mostly redundant. A diagonal of
self-correlations, two mirror-image triangles, and blocks of within-category
correlations bury the between-category relationships we care about. The
wheel, first seen in Gharibans et al. (2019), keeps only the relationships of 
interest. Hiding self- and within-category correlations also **removes them from the
multiple-comparison family**, which improves statistical power (see
`vignette("circlecorR")`).

![Example correlation wheel](man/figures/example_wheel.png)

## Installation

```r
# install.packages("remotes")
remotes::install_github("kriz98/circlecorR", build_vignettes = TRUE)
```

*(CRAN release pending.)*

Dependencies (`circlize` and `psych`) install automatically with the command
above.

## Quick start — straight from your data

`circlecorR` is designed to work straight from a data frame, **one row per
subject, one column per variable**, with no separate step to build
correlation matrices yourself. Hand that data frame to `corr_wheel()` and it
computes the correlations and p-values for you. The only other thing you
supply is `groups`, which both selects the variables and orders them around
the wheel (extra columns like IDs are ignored).

```r
library(circlecorR)

# `gastro_symptoms` is a synthetic example dataset bundled with the package --
# swap it for your own data frame (one row per subject) to use your own data.
groups <- list(
  Demographics = c("Age", "BMI"),
  Metrics      = c("Amplitude", "Fed-Fasted AR", "Frequency", "GA-RI"),
  Symptoms     = c("Nausea", "Early satiety", "Bloating",
                   "Upper GI pain", "Lower GI pain", "Heartburn"),
  Scores       = c("GCSI", "PAGI-SYM", "PAGI-QoL", "EQ-5D")
)

corr_wheel(
  gastro_symptoms,          # one row per subject -- use your own data here
  groups      = groups,
  method      = "pearson",
  adjust      = "hochberg",
  sig_level   = 0.05,
  r_threshold = 0.3,
  r_limits    = c(-0.6, 0.6)
)
```

### Save to file

```r
png("correlation_wheel.png", width = 2400, height = 2000, res = 300)
corr_wheel(gastro_symptoms, groups = groups, r_threshold = 0.3, r_limits = c(-0.6, 0.6))
dev.off()
```

See `vignette("circlecorR")` for the full tour.

## Flexibility

Everything the reference figure controls is a plain argument:

| What | Argument | Example |
|------|----------|---------|
| Category assignment & order | `groups` | named list *or* `variable = category` vector |
| Colour scheme (category colours + link palette, together) | `scheme` | `"colorblind"`, `"ocean"`, `"vivid"`, `"alimetry"`, or `list(colors=, palette=)` |
| Category colours | `colors` | `c(Symptoms = "#55A868", Scores = "#C44E52")` (overrides `scheme` per category) |
| Pretty variable labels | `labels` | `c("GA-RI" = "Rhythm index")` |
| Significance cutoff | `sig_level` | `0.05` |
| Multiple-comparison adjustment | `adjust` | `"holm"`, `"hochberg"`, `"BH"`, `"none"` |
| Minimum \|r\| shown | `r_threshold` | `0.3` |
| Hide within-category links | `hide_within_group` | `TRUE` / `FALSE` |
| Colour-scale range | `r_limits` | `c(-0.5, 0.5)` |
| Link colour ramp | `palette` | `c("#2166AC", "white", "#B2182B")` (overrides `scheme`'s) |
| Block size (thickness) | `tile_height` | `0.06` (thin) … `0.12` (thick) |
| Line size (width) | `link_lwd` | `1.6`, `3` |
| Rotation / spacing | `start_degree`, `group_gap`, `node_gap` | |
| Legend / colour bar | `legend`, `colorbar` | |

Built-in schemes are listed with `corr_wheel_schemes()` and inspected/tweaked
with `corr_wheel_scheme()`; see `vignette("circlecorR")` for examples.

`corr_wheel()` returns (invisibly) the ordered variables, resolved group and
colour maps, the colour function, and the masked matrix actually plotted — handy
for reproducibility or building a caption.

## Example data

`gastro_symptoms` is a bundled **synthetic** dataset — fully simulated, not
patient data — mimicking a gastric-symptom study, one row per subject. It's
loaded automatically with the package (`LazyData: true`), so it's available
directly as soon as you `library(circlecorR)` — no `data()` call needed. See
`?gastro_symptoms` for details, or use it as a template for your own data's
shape.

## How masking & statistics work

A link between variables *i* and *j* is drawn only if all hold:

1. they are in different categories (when `hide_within_group = TRUE`), and never
   the same variable (self-correlations are always excluded);
2. `p_adjusted <= sig_level`; and
3. `|r| >= r_threshold`.

The correlations left after step 1 form the **family** of comparisons. The
`adjust` correction is applied over **only that family** — so redundant self-
and within-category correlations don't inflate the count, and power improves.
`corr_wheel()` returns `n_tests` (the family size) and the family-adjusted
p-matrix for reporting.

## References

The correlation wheel was introduced in:

Gharibans AA, Coleman TP, Mousa H, Kunkel DC. Spatial patterns from
high-resolution electrogastrography correlate with severity of symptoms in
patients with functional dyspepsia and gastroparesis. *Clin Gastroenterol
Hepatol.* 2019 Dec;17(13):2668–77.

It has since been used in several other gastric physiology studies:

* Gharibans AA, Calder S, Varghese C, Waite S, Schamberg G, Daker C, et al.
  Gastric dysfunction in patients with chronic nausea and vomiting syndromes
  defined by a noninvasive gastric mapping device. *Sci Transl Med.* 2022 Sep
  21;14(663):eabq3544.
* Wang TH-H, Varghese C, Calder S, Gharibans A, Schamberg G, Bartlett A, et
  al. Long-term evaluation of gastric electrophysiology, symptoms and quality
  of life after pancreaticoduodenectomy. *HPB (Oxford).* 2025
  Dec;27(12):1535–42.
* Xu W, Wang T, Foong D, Schamberg G, Evennett N, Beban G, et al.
  Characterization of gastric dysfunction after fundoplication using body
  surface gastric mapping. *J Gastrointest Surg.* 2024 Mar;28(3):236–45.
* Xu W, Gharibans AA, Calder S, Schamberg G, Walters A, Jang J, et al.
  Defining and phenotyping gastric abnormalities in long-term type 1
  diabetes using a novel body surface gastric mapping device. *Gastro Hep
  Adv.* 2023 Aug 18;2(8):1120–32.
