Skip to contents

Turn sdmTMB model output into a tidy data frame

Usage

# S3 method for class 'sdmTMB'
tidy(
  x,
  effects = c("fixed", "ran_pars", "ran_vals", "ran_vcov", "rsr", "dispersion"),
  model = 1,
  conf.int = TRUE,
  conf.level = 0.95,
  exponentiate = FALSE,
  silent = FALSE,
  ...
)

# S3 method for class 'sdmTMB_cv'
tidy(x, ...)

Arguments

x

Output from sdmTMB().

effects

A character value. One of "fixed" ('fixed' or main-effect parameters), "ran_pars" (standard deviations, spatial range, and other random effect and dispersion-related terms), "ran_vals" (individual random intercepts or slopes and time-varying coefficients, if included; behaves like ranef(); see Details), "ran_vcov" (list of variance covariance matrices for the random effects, by model and group), or "rsr" (Restricted Spatial Regression fixed-effect coefficients adjusted for spatial confounding with the random fields; Hanks et al. 2015; Diaz and Thorson 2025). To access RSR coefficients the model must be fitted with control = sdmTMBcontrol(get_rsr = TRUE). "dispersion" returns dispersion-model coefficients when dispformula is used.

model

Which model to tidy if a delta model (1 or 2). The model will be ignored when effects is "ran_vals" (all returned in a single data frame with a model column).

conf.int

Include a confidence interval?

conf.level

Confidence level for CI.

exponentiate

Whether to exponentiate the fixed-effect coefficient estimates and confidence intervals.

silent

Omit any messages?

...

Extra arguments (not used).

Value

A data frame

Details

Follows the conventions of the broom and broom.mixed packages.

Currently, effects = "ran_pars" also includes dispersion-related terms (e.g., phi) only when dispersion is scalar. With dispformula, use effects = "dispersion" to extract dispersion-model coefficients.

Time-varying coefficients (from the time_varying argument in sdmTMB()) are returned with effects = "ran_vals", one row per coefficient and time slice, with terms named "<coefficient>:<time>" (e.g., "(Intercept):2011"). These are on the link scale. Their standard deviation (sigma_V) and, for time_varying_type = "ar1", correlation (rho_time) are returned with effects = "ran_pars".

Standard errors for spatial variance terms fit in log space (e.g., variance terms, range, or parameters associated with the observation error) are omitted to avoid confusion. Confidence intervals are still available.

References

Restricted Spatial Regression (effects = "rsr"):

Diaz, R.R., and Thorson, J.T. 2025. When and How to Use Restricted Spatial Regression to Separate Environmental Effects from Spatial Confounding. EcoEvoRxiv. doi:10.32942/X28351 .

Hanks, E.M., Schliep, E.M., Hooten, M.B., and Hoeting, J.A. 2015. Restricted spatial regression in practice: geostatistical models, confounding, and robustness under model misspecification. Environmetrics 26(4): 243–254. doi:10.1002/env.2331 .

Examples

fit <- sdmTMB(density ~ poly(depth_scaled, 2, raw = TRUE),
  data = pcod_2011, mesh = pcod_mesh_2011,
  family = tweedie()
)
tidy(fit)
#> # A tibble: 3 × 5
#>   term                               estimate std.error conf.low conf.high
#>   <chr>                                 <dbl>     <dbl>    <dbl>     <dbl>
#> 1 (Intercept)                            3.65     0.281     3.10     4.20 
#> 2 poly(depth_scaled, 2, raw = TRUE)1    -1.54     0.186    -1.90    -1.17 
#> 3 poly(depth_scaled, 2, raw = TRUE)2    -1.11     0.101    -1.31    -0.913
tidy(fit, conf.int = TRUE)
#> # A tibble: 3 × 5
#>   term                               estimate std.error conf.low conf.high
#>   <chr>                                 <dbl>     <dbl>    <dbl>     <dbl>
#> 1 (Intercept)                            3.65     0.281     3.10     4.20 
#> 2 poly(depth_scaled, 2, raw = TRUE)1    -1.54     0.186    -1.90    -1.17 
#> 3 poly(depth_scaled, 2, raw = TRUE)2    -1.11     0.101    -1.31    -0.913
tidy(fit, "ran_pars", conf.int = TRUE)
#> # A tibble: 4 × 5
#>   term      estimate std.error conf.low conf.high
#>   <chr>        <dbl>     <dbl>    <dbl>     <dbl>
#> 1 range        19.1    14.0       4.58      80.0 
#> 2 phi          14.0     0.677    12.8       15.4 
#> 3 sigma_O       2.14    0.941     0.906      5.07
#> 4 tweedie_p     1.58    0.0153    1.55       1.61

pcod_2011$fyear <- as.factor(pcod_2011$year)
fit <- sdmTMB(density ~ poly(depth_scaled, 2, raw = TRUE) + (1 | fyear),
  data = pcod_2011, mesh = pcod_mesh_2011,
  family = tweedie()
)
tidy(fit, "ran_vals")
#> # A tibble: 4 × 7
#>   group_name term        level_ids estimate std.error conf.low conf.high
#>   <chr>      <chr>       <chr>        <dbl>     <dbl>    <dbl>     <dbl>
#> 1 fyear      (Intercept) 2011        0.0163     0.187   -0.351    0.384 
#> 2 fyear      (Intercept) 2013        0.177      0.188   -0.192    0.545 
#> 3 fyear      (Intercept) 2015        0.232      0.189   -0.139    0.603 
#> 4 fyear      (Intercept) 2017       -0.431      0.205   -0.833   -0.0287

# time-varying coefficients:
fit <- sdmTMB(density ~ 0, time_varying = ~ 1, time = "year",
  data = pcod_2011, mesh = pcod_mesh_2011, family = tweedie(),
  spatiotemporal = "off"
)
tidy(fit, "ran_vals", conf.int = TRUE)
#> # A tibble: 4 × 5
#>   term             estimate std.error conf.low conf.high
#>   <chr>               <dbl>     <dbl>    <dbl>     <dbl>
#> 1 (Intercept):2011     2.94     0.495     1.97      3.91
#> 2 (Intercept):2013     3.07     0.490     2.11      4.03
#> 3 (Intercept):2015     3.16     0.495     2.19      4.13
#> 4 (Intercept):2017     2.66     0.501     1.68      3.64
tidy(fit, "ran_pars")
#> # A tibble: 5 × 5
#>   term      estimate std.error conf.low conf.high
#>   <chr>        <dbl>     <dbl>    <dbl>     <dbl>
#> 1 range       38.2     17.0      16.0       91.3 
#> 2 phi         15.4      0.719    14.1       16.9 
#> 3 sigma_O      2.02     0.319     1.48       2.75
#> 4 sigma_V      0.348    0.193     0.117      1.03
#> 5 tweedie_p    1.59     0.0154    1.56       1.62