Capture a linkage specification
Usage
linkage_spec(
formula,
param = NULL,
data = NULL,
by = ~species,
species = NULL,
sex = NULL,
fleet = NULL,
link = "log",
init = NULL,
bounds = NULL,
priors = NULL,
est_phase = 1L,
observe = NULL,
obs_sd = NULL,
obs_sd_est = FALSE,
integrate = TRUE
)Arguments
- formula
one-sided R formula whose RHS describes the linear predictor for
param(e.g.~ 1,~ temp,~ temp + (1 | Year)), where a(1 | g),rw(1 | g)orar1(1 | g)term adds a random effect with one deviation per level ofg.- param
target parameter name on the natural scale (e.g.
"alpha","M1","K"). May beNULLwhen the spec is built inside abuild_*()call that infers it from the enclosing list key; seebuild_growth().- data
Optional data frame for formula validation; validation happens at fit time inside
fit_mod().- by
one-sided formula naming stratifying factors that each get their own coefficients:
species,sex,age_bin, orfleet. Omitted, it defaults to the base stratum of the process the spec is attached to –~fleetfor catchability, selectivity and the fleet composition weights,~speciesfor recruitment, M, growth and the diet weight – so the base case needs noby. Pass~species + sexfor per-(species, sex) coefficients, orNULLto share one coefficient across every stratum; an explicitby,NULLincluded, is kept as given. In a selectivity or catchability linkage under~fleet, fleets sharing aSelectivity_indexorCatchability_indexstill take one coefficient between them, because they share one parameter block.- species
optional species this spec applies to, as 1-based ids (
c(1L, 2L)) or as names matchingdata_list$spnames(c("Pollock", "Cod")). Names are matched exactly after trimming whitespace, and an unrecognized one is an error listing the model's species. Give ids or names, not a mix, since R coercesc(1, "Cod")to character.NULL(default) means every species. Register several specs against one parameter to give species different formulas.- sex
optional sex ids, as integers (
1Lfemale,2Lmale) or strings ("Females"/"Males", case-insensitive;"f"/"m"accepted).NULL(default) means every sex.bymust includesexor it warns and has no effect.- fleet
optional fleets, as 1-based
Fleet_codes or as names matchingfleet_control$Fleet_name. Prefer names: aFleet_codethat is wrong but in range attaches the linkage to a different fleet and still fits, where a misspelled name cannot. Names are matched exactly after trimming; one that is unrecognized or not unique is an error listing the fleets. Give ids or names, not a mix.NULL(default) means every fleet, andbymust includefleetor it warns and has no effect.- link
how the linear predictor reaches the natural-scale parameter:
"log"(default), solog(param) = X * betaand slopes are multiplicative;"identity", soparam = X * betaand slopes are additive; or"exponential", where the predictor multiplies the log rather than shifting it,param^exp(X * beta). The exponential form reproduces Stock Synthesis's environmental link type 1 and is accepted on catchability only, for a lognormal index, with an estimated intercept.- init
optional named list of initial values keyed by design-matrix column (e.g.
list(`(Intercept)` = 4, temp = 0)), an intercept on the parameter's natural scale and a slope on the link scale; missing entries default to0. An intercept's value is logged onto the parameter's base (rec_pars,log_M1, ...), or onto the coefficient itself for recruitmentR_init, which has no base.- bounds
optional named list of
c(lower, upper), keyed and scaled asinit.- priors
optional named list of Rceattle_priors objects keyed by design-matrix column. Inside this argument
normal(),lognormal(),gamma()andbeta()may be written directly, sopriors = list(temp = normal(0, 1))is the same asprior_normal(0, 1).- est_phase
optional integer estimation phase, default
1L.0fixes the coefficient at itsinit, which then holds over anyinitsgiven tofit_mod()(an estimated intercept'sinitis only a starting value, andinitswin). It applies to the fixed-effect rows inbeta_linkageonly: a random-effect term's deviations live in a separate vector it cannot reach, soest_phase < 1on a formula containing one is an error rather than a silent no-op. Drop the term, or fix a small SD withinit = list(sigma = ), to remove the time variation. Values above1are inert for every linkage row.- observe
optional
env_datacolumn measuring the AR1 latent of anar1(1 | group)term, making it a state-space covariate (sensu Rogers et al. 2024): the latent reaches the linked parameter through an estimated effect size and is observed against this column.NULL(default) leaves the AR1 a plain random effect. The latent is zero-mean, so standardize the column to mean 0; a non-zero-mean column confounds its level with the intercept and warns.- obs_sd
optional positive measurement SD for the
observecovariate, one per observed group. Required withobserveand unused otherwise. Held fixed by default, or the starting value whenobs_sd_est = TRUE.- obs_sd_est
estimate the
observemeasurement SD instead of fixing it, as the state-space survey-catchability (GOA pollock) model does. DefaultFALSE. Caveat: the effect size andobs_sdare jointly identified only when the observed covariate is informative; on a smooth series the AR1 latent tracks it exactly and a freeobs_sdcollapses toward 0.- integrate
whether the random effect's deviations are integrated out by the Laplace approximation, default
TRUE.FALSEestimates them as a penalized fixed effect instead; see Details for when that is permitted.
Details
The reserved keys sigma and rho in init / priors route the
random-effect deviation SD and, for ar1, the correlation. sigma means
different things by structure – the innovation (per-step) SD for rw(),
the marginal (stationary) SD for ar1() – so the two are not comparable
across structures; see vignette("environmental-linkages-and-priors").
integrate = FALSE leaves the deviations in the objective as a plain
penalty and reports them with standard errors. That reproduces the
ADMB/AMAK convention behind the legacy Time_varying_sel /
Time_varying_q switches, which a Laplace-integrated rw() cannot match,
because the marginal likelihood carries a log-determinant term the
penalized form has no counterpart for. Permitted only with a fixed SD
(init = list(sigma = ), no sigma prior, plus a fixed rho for ar1),
since estimating deviations and their SD jointly as fixed effects is
degenerate, and never with observe, which must stay integrated.
Examples
# A covariate on a growth parameter, one coefficient per species. Attach to a
# parametric build_growth(); the default "empirical" form consumes no linkages.
linkage_spec(~ temp, param = "K")
#> <Rceattle linkage spec>
#> param: K
#> formula: ~temp
#> link: log
# A covariate on catchability for one fleet, named rather than numbered.
# `by` defaults to ~ fleet for catchability, so it need not be given.
linkage_spec(~ temp, fleet = "Pollock_survey_1_shelikof_acoustic")
#> <Rceattle linkage spec>
#> param: NA
#> formula: ~temp
#> fleet: Pollock_survey_1_shelikof_acoustic
#> link: log
# IID annual deviations; rw() for a random walk, ar1() for AR1.
linkage_spec(~ (1 | Year))
#> <Rceattle linkage spec>
#> param: NA
#> formula: ~(1 | Year)
#> link: log
# A random walk estimated as a penalized fixed effect, which requires a fixed
# SD: the ADMB/AMAK convention behind the legacy Time_varying_* switches.
linkage_spec(~ rw(1 | Year), init = list(sigma = 0.05), integrate = FALSE)
#> <Rceattle linkage spec>
#> param: NA
#> formula: ~rw(1 | Year)
#> link: log
#> estimate: penalized fixed effect (integrate = FALSE)
# Intercept-only: a prior on the base parameter itself.
linkage_spec(~ 1, priors = list(`(Intercept)` = normal(0, 1)))
#> <Rceattle linkage spec>
#> param: NA
#> formula: ~1
#> prior: (Intercept) ~ normal(0, 1)
#> link: log