Control parameters for gllvmTMB()
Usage
gllvmTMBcontrol(
d_B = NULL,
d_W = NULL,
spde_mode = c("per_trait", "shared"),
n_init = 1L,
optimizer = c("nlminb", "optim"),
optArgs = list(),
init_jitter = 0.3,
init_strategy = c("default", "single_trait_warmup"),
start_method = list(method = NULL, jitter.sd = 0),
start_from = NULL,
se = TRUE,
verbose = FALSE,
...
)Arguments
- d_B, d_W
Latent dimensions for the between-unit and within-unit reduced-rank components. Set to a positive integer to enable
latent()/indep()covariance structures at the corresponding tier.- spde_mode
"per_trait"(default) fits one independent SPDE field per trait when aspatial()term is present;"shared"fits one shared SPDE field with trait-specific scalar loadings.- n_init
Number of random-start replicates. Reduced-rank GLLVMs are often multimodal because the latent-factor likelihood has many equivalent local maxima; running several restarts with different starting values and keeping the fit with the lowest
-logLikreduces the risk of settling on a suboptimal solution. Default 1 (single fit). Increase to 5–10 for two-level rr models.- optimizer
One of
"nlminb"(default) or"optim". Use the latter together withoptArgsfor finicky two-level rr fits.- optArgs
A list of arguments passed to the optimiser. For
optimthe most useful islist(method = "BFGS").- init_jitter
Standard deviation of N(0, sigma) jitter applied to the starting parameter vector across the
n_initrestarts. Default 0.3.- init_strategy
One of
"default"(current behaviour) or"single_trait_warmup". The warmup option fits an intercept-only univariate GLM per trait — with that trait's family — and seeds the matchinglog_phi_*entries beforeMakeADFun(). Recommended for count families (especiallynbinom2) where the default initialisation can leave the optimiser walking the \((\psi_t, \phi_t)\) trade-off ridge. No effect for traits whose family doesn't carry aphiparameter (Gaussian, Poisson, binomial). Default"default".- start_method
Optional reduced-rank starting-value method, modelled after
glmmTMB::glmmTMBControl(start_method = ...)but extended for two-level gllvmTMB models. Uselist(method = "res", jitter.sd = 0.2)to seedlatent()loadings and latent scores from a reduced-rank decomposition of fixed-effect residuals. Uselist(method = "indep")to first fit the matching independent diagonal GLMM/GLLVM and copy its estimated fixed effects, per-trait variance starts, and random effects into the full latent covariance fit.jitter.sdadds Normal jitter to residual-start latent scores. Defaultlist(method = NULL, jitter.sd = 0)keeps the historical starts.- start_from
Optional fitted
gllvmTMBobject, usually a simpler model such as onelatent()tier or an independent diagonal model (indep()). Any estimated TMB parameters with shapes matching the current model are copied into the starting parameter list before optimisation. This implements the "fit simpler, then use it as starting values" workflow recommended for complex reduced-rank models.- se
Logical; if
TRUE, computeTMB::sdreport()after optimisation so Wald standard errors and Hessian diagnostics are available. IfFALSE, skip standard-error calculation and return the point-estimate fit withsd_report = NULLand a diagnostic note. This is useful for hard models where the point estimate is needed and uncertainty will be obtained by bootstrap or profile methods. DefaultTRUE.- verbose
If
TRUE, prints a one-line summary per restart so the user can see which seed led to the winning fit. DefaultFALSE.- ...
Reserved for future use. Currently ignored with a warning.
Details
Recommended workflow for two-level latent models. Reduced-rank
likelihoods are notoriously multimodal in two-level fits like
value ~ 0 + trait + latent(0+trait|ID, d_B) + latent(0+trait|obs_ID, d_W).
The recommended workflow is:
Run several restarts (
n_init = 5to10) and keep the one with the lowest-logLik.If that fails to converge cleanly, switch the optimiser to
optimwithBFGS:gllvmTMBcontrol(optimizer = "optim", optArgs = list(method = "BFGS")).For factor-analytic models, try
start_method = list(method = "res", jitter.sd = 0.2). This fits the fixed-effects part first, decomposes the residual matrix into starting values for \(\Lambda\) and the latent scores, and can be combined withn_init > 1to check whether the optimiser repeatedly reaches the same likelihood basin.For Gaussian two-level models, prefer
start_method = list(method = "indep")or manually fit a simpler model and pass it throughstart_from = simpler_fit. This is a GLMM warm start rather than a fixed-effect-only GLM residual start.
Examples
# gllvmTMBcontrol() is a pure-R constructor: it builds and validates a
# control list without fitting anything.
gllvmTMBcontrol() # historical defaults
#> $d_B
#> NULL
#>
#> $d_W
#> NULL
#>
#> $spde_mode
#> [1] "per_trait"
#>
#> $n_init
#> [1] 1
#>
#> $optimizer
#> [1] "nlminb"
#>
#> $optArgs
#> list()
#>
#> $init_jitter
#> [1] 0.3
#>
#> $init_strategy
#> [1] "default"
#>
#> $start_method
#> $start_method$method
#> NULL
#>
#> $start_method$jitter.sd
#> [1] 0
#>
#>
#> $start_from
#> NULL
#>
#> $se
#> [1] TRUE
#>
#> $verbose
#> [1] FALSE
#>
# Multi-start to guard against multimodal reduced-rank likelihoods, with
# jitter on the starting parameter vector across restarts.
gllvmTMBcontrol(n_init = 3, init_jitter = 0.2)
#> $d_B
#> NULL
#>
#> $d_W
#> NULL
#>
#> $spde_mode
#> [1] "per_trait"
#>
#> $n_init
#> [1] 3
#>
#> $optimizer
#> [1] "nlminb"
#>
#> $optArgs
#> list()
#>
#> $init_jitter
#> [1] 0.2
#>
#> $init_strategy
#> [1] "default"
#>
#> $start_method
#> $start_method$method
#> NULL
#>
#> $start_method$jitter.sd
#> [1] 0
#>
#>
#> $start_from
#> NULL
#>
#> $se
#> [1] TRUE
#>
#> $verbose
#> [1] FALSE
#>
# Switch the optimiser to optim + BFGS for finicky two-level rr fits.
gllvmTMBcontrol(optimizer = "optim", optArgs = list(method = "BFGS"))
#> $d_B
#> NULL
#>
#> $d_W
#> NULL
#>
#> $spde_mode
#> [1] "per_trait"
#>
#> $n_init
#> [1] 1
#>
#> $optimizer
#> [1] "optim"
#>
#> $optArgs
#> $optArgs$method
#> [1] "BFGS"
#>
#>
#> $init_jitter
#> [1] 0.3
#>
#> $init_strategy
#> [1] "default"
#>
#> $start_method
#> $start_method$method
#> NULL
#>
#> $start_method$jitter.sd
#> [1] 0
#>
#>
#> $start_from
#> NULL
#>
#> $se
#> [1] TRUE
#>
#> $verbose
#> [1] FALSE
#>
