The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

First-week intervals: fit, profile, and boundary

This page is for an applied ecology or evolution user in the first week with drmTMB. It walks one short path: fit → inventory targets → profile a random-effect SD → read profile.boundary → decide when not to trust the interval. It restates the default uncertainty story in ?confint.drmTMB; it does not claim nominal coverage on every route.

For the longer post-fit toolbox (check_drm(), Wald shortcuts, bootstrap, newdata profiles), read Checking and using fitted models. For which cells have coverage evidence, read Can I fit and report this model?.

Default recipe (read once)

  1. Fixed effects and other routine Wald-ready targets: start with confint(fit).
  2. Random-effect SDs and other direct variance components: prefer confint(..., method = "profile") after profile_targets() shows the row is profile-ready.
  3. Always read conf.status and profile.boundary on the returned table.
  4. A computable interval is not coverage certification.

Fit a small random-intercept model

The example is intentionally tiny and non-phylogenetic so it stays CRAN-safe and fast:

library(drmTMB)

set.seed(13)
n_site <- 18
n_per_site <- 6
site <- factor(rep(seq_len(n_site), each = n_per_site))
site_effect <- rnorm(n_site, sd = 0.45)

fish_site <- data.frame(
  site = site,
  temperature = runif(n_site * n_per_site, -1.5, 1.5),
  habitat = factor(
    sample(c("reef", "kelp"), n_site * n_per_site, replace = TRUE)
  )
)

site_mu <- site_effect[as.integer(fish_site$site)]
fish_site$growth <- rnorm(
  nrow(fish_site),
  mean = 1 + 0.7 * fish_site$temperature +
    0.35 * (fish_site$habitat == "kelp") + site_mu,
  sd = 0.35
)

fit_site <- drmTMB(
  bf(growth ~ temperature + habitat + (1 | site), sigma ~ 1),
  family = gaussian(),
  data = fish_site
)

Run check_drm(fit_site) before interpreting estimates. A clean diagnostic table catches optimizer and Hessian problems; it does not certify coverage.

Inventory targets, then profile the RE-SD

profile_targets(fit_site)
#>                          parm         target_class  dpar        term
#> 1        fixef:mu:(Intercept)         fixed-effect    mu (Intercept)
#> 2        fixef:mu:temperature         fixed-effect    mu temperature
#> 3        fixef:mu:habitatreef         fixed-effect    mu habitatreef
#> 4     fixef:sigma:(Intercept)         fixed-effect sigma (Intercept)
#> 5                       sigma distributional-scale sigma  (constant)
#> 6            sd:mu:(1 | site)     random-effect-sd    mu  (1 | site)
#> 7 derived:repeatability(site)      derived-summary    mu  (1 | site)
#>   tmb_parameter index   estimate link_estimate    scale   transformation
#> 1       beta_mu     1  1.3588788     1.3588788     link linear_predictor
#> 2       beta_mu     2  0.6814229     0.6814229     link linear_predictor
#> 3       beta_mu     3 -0.2416812    -0.2416812     link linear_predictor
#> 4    beta_sigma     1 -0.9603029    -0.9603029     link linear_predictor
#> 5    beta_sigma     1  0.3827769    -0.9603029 response              exp
#> 6     log_sd_mu     1  0.3721619    -0.9884264 response              exp
#> 7          <NA>    NA  0.4859419            NA response   variance_ratio
#>   target_type profile_ready   profile_note
#> 1      direct          TRUE          ready
#> 2      direct          TRUE          ready
#> 3      direct          TRUE          ready
#> 4      direct          TRUE          ready
#> 5      direct          TRUE          ready
#> 6      direct          TRUE          ready
#> 7     derived         FALSE derived_target

Wald is the fast first pass for fixed effects and other Wald-ready rows:

confint(fit_site, parm = "fixed_effects")
#>                      parm level      lower       upper scale   transformation
#> 1    fixef:mu:(Intercept)  0.95  1.1553271  1.56243054  link linear_predictor
#> 2    fixef:mu:temperature  0.95  0.5880442  0.77480166  link linear_predictor
#> 3    fixef:mu:habitatreef  0.95 -0.3939464 -0.08941602  link linear_predictor
#> 4 fixef:sigma:(Intercept)  0.95 -1.1064326 -0.81417319  link linear_predictor
#>   tmb_parameter index method profile.engine conf.status profile.boundary
#> 1       beta_mu     1   wald           <NA>        wald               NA
#> 2       beta_mu     2   wald           <NA>        wald               NA
#> 3       beta_mu     3   wald           <NA>        wald               NA
#> 4    beta_sigma     1   wald           <NA>        wald               NA
#>   profile.message
#> 1            <NA>
#> 2            <NA>
#> 3            <NA>
#> 4            <NA>

For the site random-intercept SD, prefer the profile route and copy the exact target name from profile_targets():

ci_site <- confint(
  fit_site,
  parm = "sd:mu:(1 | site)",
  method = "profile"
)
ci_site
#>               parm level     lower    upper    scale transformation
#> 1 sd:mu:(1 | site)  0.95 0.2554993 0.561249 response            exp
#>   tmb_parameter index  method profile.engine conf.status profile.boundary
#> 1     log_sd_mu     1 profile       endpoint     profile            FALSE
#>   profile.message
#> 1              ok

Read profile.boundary before you trust the interval

Successful profile rows use conf.status = "profile". When the profile lands near a variance-component boundary, profile.boundary is TRUE and confint(method = "profile") warns with class drmTMB_profile_boundary_warning.

ci_site[, c("parm", "lower", "upper", "conf.status", "profile.boundary")]
#>               parm     lower    upper conf.status profile.boundary
#> 1 sd:mu:(1 | site) 0.2554993 0.561249     profile            FALSE

When not to trust a returned interval

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.