# Defining model components

#### Generated on 2022-12-02

(Note: vignette under construction!)

## Basic component features

Model components are defined using a formula syntax that is similar to R-INLA but has some differences. The basic syntax is

~ my_component_name(
main = ...,
model = ...
)

my_component_name is a user-chosen label for the model component. This label is used in model summaries, to label relevant parts of a fitted model object, and to access model components when sampling from a model using generate() and predict().

The main argument defines the input data for the component. For example, an intercept-like component has a vector of ones as an input. The linear effect of a covariate has the vector of covariate values as an input. A 2-dimensional SPDE effect takes a 2-column matrix of coordinate locations as an input. This argument can be a general R expression, more details on this are below. The main argument doesn’t not need to be named. Other arguments should normally be named, to avoid confusion.

## Shortcuts

There are a few shortcuts to defining model components. They are for

1. Parameters that are the same for all predictor evaluations (intercept-like parameters).
2. Using a covariate stored in an sp Spatial* or terra SpatRaster object.
3. Defining linear effects using an lm-style syntax.
4. Behaviour for if main, group or replicate is a function given with no arguments.

#### Intercept-like components

The syntax

~ my_intercept(1)

can be used as a shortcut for

~ my_intercept(
main = rep(1, n),
model = "linear"
)

where n is the length of the predictor vector. Note that this shortcut makes an assumption about the approriate length of the predictor. For many models this can be easily deduced by inspecting input data, but this is not always the case, for example if the response and covariate data are of different dimensions or for joint likelihood models with shared components.

#### sp covariates

If main, group, or replicate, is the name of an Spatial* or SpatRaster object stored in the global R environment, then inlabru attempts to do something intelligent by extracting the covariate information at the locations of the data passed to bru() or like(). This requires that this data is a SpatialPoints* or sf object. For Spatial* inputs, inlabru does this by applying sp::coordinates() to the data and then extracting the covariate information using sp::over().

The shorcut

~ my_sp_effect(
main = a_spatial_object,
model = "linear"
)

internally calls eval_spatial() which is almost equivalent to

get_sp_covariate <- function(df) {
locs <- coordinates(df)
over(locs, an_sp_object)[, 1]
}

~ my_sp_effect(
main = get_sp_covariate(.data.),
model = "linear"
)

Note that this requires a_spatial_object to be stored in the global R environment (or in the environment associated with the model definition code) so it is findable when the expression is internally evaluated by inlabru. Also note that the get_sp_covariate function above extracts the first column of the sp object evaluation. For more general situations, one can either specify the optional main_layer argument to extract another named or indexed column, or directly use main = eval_spatial(a_spatial_object, .data., layer = some_layer).

Note that this assumes that coordinates() applied to the input data is a sensible thing to do, this might not be the case for all models! For example, if the input data is a SpatialPolygonsDataFrame then coordinates() returns the centroid of each polygon. As more specific input type support is developed, and support for sp is gradually deprecated in favour of sf and terra, these special cases may be given more precise meaning.

#### lm-style syntax

Since inlabru version 2.5.0, a feature has been added to allow users to specify linear fixed effects using a formula as input. This uses the model = 'fixed' component type. The syntax is

~ my_fixed_effects(
main = ~ x1:x2 + x3 * x4,
model = "fixed"
)

where the data has columns named x1, x2, x3, and x4. In this case, inlabru creates the design matrix for this component by running

MatrixModels::model.Matrix(~ x1:x2 + x3 * x4, .data.)

This allows users to define interactions in a concise way, by utilising the functionality already supported by the MatrixModels package. The formula is interpreted in the conventional way, x1:x2 is the interaction of covariates x1 and x2, not including their individual fixed effects, and x3:x4 is the interaction of x3 and x4 inclusive of the individual fixed effects x3 and x4. Note that for implementation technical reasons, the estimated parameters appear in 'summary.random' instead of the normal 'summary.fixed' part of the inla/bru output object.

The alternative to using this shortcut would be for the user to define and name individual components for each term in the formula.

#### A function given with no arguments

If main, group, or replicate are given as a function with no covariates, then this function is applied to the data. For example,

~ a_component(
main = a_function,
model = ...
)

is equivalent to

~ a_component(
main = a_function(.data.),
model = ...
)

#### Non-linear predictors

inlabru supports non-linear predictors, where $$\tilde{\eta}(u,v)$$ is a non-linear function of $$\eta_u$$ and $$\eta_v$$. It is important to note that the mapping each component effect vector $$\eta_u=A^{(u)} u$$ happens before the non-linear function is applied. So, for example, if $$\tilde{\eta}(u,v) = \exp(\eta_u + \eta_v)$$ then this is evaluated as $$\exp(A^{(u)} u + A^{(v)} v)$$.