---
title: "Introduction to Circular Regression"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Introduction to Circular Regression}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 6,
  fig.height = 4
)
```

CircularRegression models a circular response, such as an angle or movement
direction, using circular explanatory variables. Angles are assumed to be in
radians. The package follows the angular regression framework of Rivest,
Duchesne, Nicosia and Fortin (2016), where the conditional mean direction is
obtained from the argument of a resultant vector.

For a homogeneous angular model with reference direction \(x_1\), a simple
two-term mean direction can be written as

\[
\mu_i(\beta) =
\operatorname{atan2}\{
\sin(x_{1i}) + \beta z_i \sin(x_{2i}),
\cos(x_{1i}) + \beta z_i \cos(x_{2i})
\}.
\]

The formula syntax mirrors this construction. A plain term such as `x1`
represents an angular covariate. A term such as `x2:z2` represents an angular
covariate `x2` weighted by a finite non-negative modifier `z2`.

## Simulated example

```{r}
library(CircularRegression)

wrap_angle <- function(x) atan2(sin(x), cos(x))

set.seed(123)
n <- 150
x1 <- runif(n, -pi, pi)
x2 <- runif(n, -pi, pi)
z2 <- runif(n, 0.2, 1.8)
beta <- 0.35

mu <- atan2(
  sin(x1) + beta * z2 * sin(x2),
  cos(x1) + beta * z2 * cos(x2)
)
y <- wrap_angle(mu + rnorm(n, sd = 0.12))

dat <- data.frame(y = y, x1 = x1, x2 = x2, z2 = z2)
```

The recommended high-level interface is `circular_regression()`. Its default
method is `"two_step"`: it first fits the consensus model, then fits the
homogeneous angular model using the selected reference direction.

```{r}
fit <- circular_regression(y ~ x1 + x2:z2, data = dat)
fit
```

The usual S3 generics are available.

```{r}
coef(fit)
head(fitted(fit))
head(residuals(fit))
head(predict(fit))
```

Predictions for new angular covariates are returned as angles in radians.

```{r}
new_dat <- dat[1:5, c("x1", "x2", "z2")]
predict(fit, newdata = new_dat)
```

## Model-specific functions

The original model-specific interfaces remain available. Use `angular()` when
you want direct control of the homogeneous model and the reference direction.

```{r}
fit_hom <- angular(
  y ~ x1 + x2:z2,
  data = dat,
  reference = c("name", "x1")
)

summary(fit_hom)
```

Use `consensus()` to fit the consensus formulation directly.

```{r}
fit_cons <- consensus(y ~ x1 + x2:z2, data = dat)
summary(fit_cons)
```

## Practical notes

All angles should be supplied in radians. Missing values are handled through
the `na.action` argument passed to `model.frame()`. Modifiers in `x:z` terms
must be finite and non-negative, because they act as vector weights in the
mean-direction construction.

Reference:

Rivest, L.-P., Duchesne, T., Nicosia, A. and Fortin, D. (2016). A general
angular regression model for the analysis of data on animal movement in
ecology. Journal of the Royal Statistical Society: Series C (Applied
Statistics), 65(3), 445-463.
