---
title: "A note about values"
author: "Håvard Rue (hrue@r-inla.org) & Sigrunn Holbek Sørbye (sigrunn.sorbye@uit.no)"
date: "Dec, 2025"
output: rmarkdown::pdf_document
vignette: >
  %\VignetteIndexEntry{A note about values}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include=FALSE, cache=FALSE}
library(knitr)
knitr::opts_chunk$set(echo = TRUE, warning = FALSE, error = FALSE, message = FALSE, cache =FALSE)
knitr::opts_chunk$set(fig.path="figures/a-note-on-values/")
library(INLA)
inla.setOption(num.threads="1:1")
inla.setOption(smtp="taucs")
if (file.exists("myinit.R")) source("myinit.R")
```

## Introduction

This a short note discussing the argument \texttt{values} in
\texttt{f()}, to avoid unfortunate confusion. This is
especially an issue for models like \texttt{ar1}, \texttt{ar} and 
\texttt{seasonal}, which are only defined for integer-valued arguments. 


Consider the AR1-model
$$
	x_t = \phi x_{t-1} + \epsilon_t
$$
for $t = 1, 2, \ldots, m$. 

In practice, we might use the AR1-model for various sequential indexes, like
years, weeks, etc. In these cases, it is naturally to write
```{r eval=FALSE}
y ~ ... + f(year, model = "ar1", ...) 
```
where for example \texttt{year} is given by 
```{r}
year <- 2000:2025
```
What happens internally, is that the \texttt{year}-variable specifies
the \texttt{values} (time points) at which the AR1-model is defined. So, the variable 
\texttt{year} would be mapped to the $t$-index, which runs from $1$ to $m$.

To be more specific, a mapping between \texttt{year} and the $t$-index is
defined as
```{r}
values <- sort(unique(year[!is.na(year)]))
values

map.year.to.t <- function(year, values) {
	a <- numeric(length(year))
	for(i in seq_along(year)) 
		a[i] = which(year[i] == values)
	return (a) 
}
yy <- c(2000, 2020, 2025)
print(cbind(year=yy, t=map.year.to.t(yy, values)))
```

An unfortunate consequence is that if some years
are missing, then "confusing" things happen. Suppose, we do not have
obsevations for some years,

```{r}
year <- c(2000:2020, 2023:2025)
```

Then the above mapping still applies but with

```{r} 
values <- sort(unique(year[!is.na(year)]))
values
```
in which the years 2021 and 2022 are missing. The internal mapping now gives

```{r}
yy <- c(2000, 2020, 2025)
print(cbind(year = yy, t = map.year.to.t(yy, values)))
```
Note that for \texttt{year} $=2025$ the index $t$ is now 24 and not 26 as earlier. This
implies that the correlation between year 2020 and 2023 is $\phi$ while it was
$\phi^3$ as before. Often, this is not what we expect to happen.

Another case is when the argument denote non-integers, like
```{r eval=FALSE}
time <- c(1.1, 2.2, 3.3, 4.4, 10.0)
```
A call using \texttt{f(time, model = "ar1")} would run, but \texttt{time} will be mapped to the discrete indexes $1, \ldots, 5$. This is because the models
\texttt{ar1/ar/seasonal} are defined on integers and cannot handle
irregular locations. 

We can ensure consistent behaviour by adding the argument
\texttt{values} to \texttt{f()}, specifying for which indexes the model
is defined, like
```{r eval=FALSE}
y ~ ... + f(year, model = "ar1", values = 2000:2025)
``` 
or, if we want predictions for additional years,
```{r eval=FALSE}
y ~ ... + f(year, model = "ar1", values = 1990:2035)
```
In this case, the \texttt{values} are defined by the corresponding
named argument and not by the variable \texttt{year} as before
```{r}
values <- sort(unique(values[!is.na(values)]))
```
The requirement for \texttt{year} is now that these are either \texttt{NA}-values or
a subset of the defined \texttt{values}. 

## An example

This is a simple simulated example demonstrating the issue about
\texttt{values}, having missing observations. 
```{r, plot=TRUE, out.width = "70%", fig.align = "center"}
year <- 2000:2025
n <- length(year)
phi <- 0.9
phi.intern <- inla.models()$latent$ar1$hyper$theta2$to.theta(phi)
x <- scale(arima.sim(n, model=list(ar=phi)))
s <- 0.3
y <- x + rnorm(n, sd=s)
plot(year, y, pch=19)
```

Let us fit an AR1 model
```{r, plot=TRUE, out.width = "70%", fig.align = "center"}
r <- inla(y ~ -1 + f(year, model="ar1",
	                 hyper = list(prec = list(initial=0, 
						                      fixed=TRUE),
								  rho = list(initial=phi.intern,
									         fixed=TRUE))),
	    family="gaussian",
		control.family = list(hyper = list(
                                  prec = list(initial=log(1/s^2),
								  fixed = TRUE))),
		data = data.frame(y, year))
plot(year, y, pch=19)
lines(year, r$summary.random$year$mean)
```		

Assume \texttt{y[10]} is missing, then we will get the wrong results
by removing \texttt{y[10]} from the data, because \texttt{values} are
not given (hence \texttt{year[10]} is removed as well).

```{r}
## this is correct
y[10] <- NA
r <- inla(y ~ -1 + f(year, model="ar1",
	                 hyper = list(prec = list(initial=0, 
						                      fixed=TRUE),
								  rho = list(initial=phi.intern,
									         fixed=TRUE))),
	    family="gaussian",
		control.family = list(hyper = list(
                                  prec = list(initial=log(1/s^2),
								  fixed = TRUE))),
		data = data.frame(y, year))  ## missing data included

## this is wrong
rr <- inla(y ~ -1 + f(year, model="ar1",
	                 hyper = list(prec = list(initial=0, 
						                      fixed=TRUE),
								  rho = list(initial=phi.intern,
									         fixed=TRUE))),
	    family="gaussian",
		control.family = list(hyper = list(
                                  prec = list(initial=log(1/s^2),
								  fixed = TRUE))),
		data = data.frame(y, year)[-10,]) ## missing data removed
## we compare the results
r$mlik - rr$mlik
```

If we add \texttt{values}, then we get the correct result when we remove
missing data.

```{r}
rrr <- inla(y ~ -1 + f(year, model="ar1", 
	                  values = 2000:2025,  ## values added
	                  hyper = list(prec = list(initial=0, 
						                      fixed=TRUE),
								  rho = list(initial=phi.intern,
									         fixed=TRUE))),
	    family="gaussian",
		control.family = list(hyper = list(
                                  prec = list(initial=log(1/s^2),
								  fixed = TRUE))),
		data = data.frame(y, year)[-10,]) ## missing data removed
## we compare the results
r$mlik - rrr$mlik
```

## Another example

We can extend the range using \texttt{values}, to get predictions.
```{r, plot=TRUE, out.width = "70%", fig.align = "center"}
values <- 1990:2035
r <- inla(y ~ -1 + f(year, model="ar1",
	                 values = values,  ## values added
	                 hyper = list(prec = list(initial=0, 
						                      fixed=TRUE),
								  rho = list(initial=phi.intern,
									         fixed=TRUE))),
	    family="gaussian",
		control.family = list(hyper = list(
                                  prec = list(initial=log(1/s^2),
								  fixed = TRUE))),
		data = list(y=y, year=year, values=values))
plot(year, y, pch=19, xlim=range(values))
lines(values, r$summary.random$year$mean)
```		
