---
title: "Ising networks for binary data"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Ising networks for binary data}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 6, fig.height = 5)
has_cograph <- requireNamespace("cograph", quietly = TRUE)
```

```{r}
library(psychnets)
```

The **Ising model** is the binary analogue of the Gaussian graphical model: a
network for **0/1 data**, where each edge is a conditional association between two
binary variables. `psychnets` fits it by nodewise L1-penalised logistic regression
with EBIC selection (`method = "ising"`, equivalent to `IsingFit::IsingFit()`),
or unregularised with Wald-based pruning (`method = "ising_sampler"`). Both
self-certify via the nodewise GLM stationarity residual.

## Dichotomising

The construct scores are continuous, so we first binarise them with
`dichotomize()` -- here into "high" vs "low" on each construct. A median split on
coarse data is often badly unbalanced; `method = "rank"` gives a balanced ~50/50
split robust to ties.

```{r}
bin <- dichotomize(SRL_GPT, method = "rank")
colMeans(bin)             # endorsement ("high") rate per construct (~0.5)
```

## Fitting the Ising network

```{r}
fit <- psychnet(bin, method = "ising", rule = "AND")
fit
certificate(fit)
```

The edges are the symmetrised conditional associations between constructs:

```{r}
as.data.frame(fit)
```

Predictability for binary nodes is classification accuracy above the marginal
baseline (`nCC`); it needs the data the model was fit on:

```{r}
net_predict(fit, data = bin)
```

## Regularised vs unregularised

`method = "ising_sampler"` is the unregularised counterpart; with `alpha` it
prunes edges by a Wald p-value instead of shrinking them.

```{r}
samp <- psychnet(bin, method = "ising_sampler", alpha = 0.05)
as.data.frame(samp)
```

## Plotting

Pass the network object to `cograph::splot()` with `psych_styling = TRUE`
(spring layout, green = positive, red = negative); ask for the predictability
ring with `predictability = TRUE`.

```{r ising-plot, eval = has_cograph}
cograph::splot(fit, psych_styling = TRUE, predictability = TRUE)
```
