Changelog
Source:NEWS.md
sdmTMBexperiments 0.1.0
First release. Experimental helper functions for fitted sdmTMB models, ported and generalised from project-local helpers.
Functions
- Model comparison:
compare_models()(+plot()method). - Mesh-resolution sensitivity:
compare_meshes()(+plot()method). - Retrospective analysis:
sdmTMB_retro()(+plot()method). - Survey-specific index comparison:
compare_surveys()(+plot()method: index, scatter, spatial). - Spatial mesh cross-validation:
sdmTMB_mesh_cv()(+plot()method). - Prediction grids:
make_survey_prediction_region(),make_prediction_grid(). -
mohns_rho()— Mohn’s rho for any set of index series. - Plotting helpers:
plot_mesh(),plot_prediction_map(),plot_random_field(),plot_index(),plot_fixed_effects(),plot_variance_partitioning(),plot_prediction_histogram(),plot_residual_qq(), andbubble_map(). - Bundled public example data:
sebastes.
Fixes applied during extraction
- Assign
future.globals.maxSizein the low-memory branch (previously computed but never applied). - Correct the per-cell
mean_pr_diffpercent-difference formula incompare_models()andcompare_surveys(). - Unify the parallel seed argument to
future_seedeverywhere. - Validate
X/Ycolumns incompare_meshes(). - Palette-safe colours in
plot.sdmTMB_mesh_comparison()for any number of cutoffs. -
sdmTMB_retro()rebuilds the mesh’s data mapping for each peel whenrefit_meshes = FALSE(previously reusing the fittedsdmTMBmeshunchanged meant every peel but the terminal one failed to converge and silently returnedNAindex rows), and clampsnyearsto the available years. - Use portable
future::multisessionparallelism (works on Windows). -
compare_surveys()no longer silently inherits anNACRS fromcompiled_modelwhenobject_crsis leftNULL(a normally builtsdmTMB::make_mesh()mesh hascrs = NA, notNULL); it now errors with a clear message asking forobject_crsinstead of failing deep insideplot(..., type = "spatial"). -
plot_prediction_map()no longer hardcodes alimits = c(0, NA)fill scale, which silently rendered any out-of-range cell (e.g. negative link-scale predictions) as blank/grey with no indication why. The scale range is now taken from the data by default; a newfill_limitsargument (defaultNULL) lets you opt into an explicit floor/ceiling, and a warning fires only if that explicit choice actually clips data. -
sdmTMB_mesh_cv()’sdeltaNLL/deltaNLL_prhad the wrong sign: they were computed straight fromsum_loglik(a log-likelihood, where higher is better) without negating it, so despite the name they were a delta-log-likelihood (<= 0, max = best) rather than a proper delta-NLL. Now>= 0with0(min) indicating the best-fitting mesh cutoff, consistent withdeltaAIC. - The vignette’s
compare_surveys()example fitdensityas the response while also passing aswept_arealog-offset; sincedensityis alreadybiomass / swept_area, this double-corrected for effort and, combined with anareaargument left in km² instead ofswept_area’s square nautical miles, inflated the resulting index by roughly 1000x. Fixed by fittingbiomassas the response and convertingareato square nautical miles. -
.spatial_diff_map()’s (the shared spatial-difference map used by all three comparisonplot()methods) fill-scale breaks could be crowded/ illegible for skewed or extreme ranges, and didn’t guarantee the scale’s actual limits or0were shown. Breaks are now guaranteed to include the limits and0(when spanned), de-crowded so adjacent breaks are never too close together, and labelled with abbreviated numbers (e.g."-9.2K") viascales::label_number(scale_cut = scales::cut_short_scale()). -
compare_models()/compare_surveys()’s spatialplot()methods unconditionally labelled the fill legend “Percent anomaly” even whenspatial_response = "mean"(an absolute density difference, not a percent);compare_meshes()didn’t have this bug. Fixed by only applying the percent label whenspatial_responseis actually one of the percent-based options. - The rightmost year’s x-axis label was cropped in every index plot (
plot_index(), and thetype = "index"plot()methods of the three comparison functions andsdmTMB_retro()):coord_cartesian(expand = FALSE)puts the last data point exactly on the panel edge, and the default plot margin didn’t leave room for its tick label. Fixed with a shared, wider plot margin. - Those same index plots’ x-axis could show decimal year breaks (
2020.0,2020.5, …) for short year ranges, sincescales::pretty_breaks()picks sub-1 steps when that gives a better fit to the target break count. Whole year ranges now always get whole-year breaks (falling back to the regular algorithm only if the range itself isn’t whole numbers).
Other changes
-
plot.sdmTMB_model_comparison(type = "index")gains amohnargument (defaultFALSE) controlling whether the Mohn’s rho annotation is added; previously it was always shown. -
plot.sdmTMB_model_comparison(type = "spatial")gains afill_prefixargument for the fill legend title (e.g."Biomass density","CPUE"). Previously the legend was hardcoded to “Biomass densityanomaly”, which doesn’t hold for models with other response variables. DefaultNULLnow gives a generic “Percent anomaly” title. -
plot_prediction_map()’stransargument is renamedtransform(default"identity", was"sqrt"), matching ggplot2’scontinuous_scale()API (transis deprecated there in favour oftransform). -
plot.sdmTMB_mesh_comparison(type = "index")gains the samemohnargument (defaultFALSE) asplot.sdmTMB_model_comparison(), and acutoff_labelargument (default"Cutoff") for the colour/fill legend title, e.g.cutoff_label = "Cutoff (km)". -
compare_meshes()now also computesmean_pr_diff, sospatial_response = "mean_pr_diff"is available forplot.sdmTMB_mesh_comparison(type = "spatial")— previously onlycompare_models()/compare_surveys()computed it, so mesh comparisons silently had one fewer (and arguably the most useful) spatial-plot option. - Documented what the
spatial_responseoptions ("mean","pr_mean","mean_pr_diff") actually compute and when to prefer each, in theplot()methods of all three comparison functions (?plot.sdmTMB_model_comparisonetc.) and in the vignette. -
make_prediction_grid()output now carries classsdmTMB_prediction_gridandcrs/coord_multiplier/resolutionattributes, and gains aplot.sdmTMB_prediction_grid()method: draws the grid points as squares on a [ggOceanMaps::basemap()], optionally coloured by a column (depthby default, when present). -
make_prediction_grid()now extracts depth automatically whenmax_depthis set and nodepth_funis supplied, viaggOceanMaps::get_depth(bathy.style = bathy_style)(newbathy_styleargument, default"raster_continuous", ggOceanMaps’ bundled ETOPO grid — no extra download path needed). A customdepth_funstill overrides this for other bathymetry sources. -
compare_models(),compare_meshes()andcompare_surveys()no longer leaksdmTMB’s informational “assuming the offset vector is 0” message (frompredict.sdmTMB()) when comparing models fit with an offset. This is expected/correct — prediction grids aren’t real hauls, so the offset is deliberately zero and area-weighting is done via theareaargument instead — but it was showing on every spatial-difference calculation (.pred_diff_base(), shared by all three comparison functions) with no way to turn it off;.safe_index()’sget_index_split()call already suppressed it. - Default
spatial_responsefor all three comparisonplot()methods changes from"pr_mean"to"mean_pr_diff"— the more robust of the two percent summaries (see thespatial_responsedocs/vignette for why). - Default
metricforplot.sdmTMB_mesh_cv()changes from"sum_loglik"to"deltaNLL"(now that its sign is fixed — see above), which is easier to read at a glance than the raw summed log-likelihood. -
plot.sdmTMB_survey_comparison(type = "spatial")gains the samefill_prefixargument asplot.sdmTMB_model_comparison(). -
plot.sdmTMB_survey_comparison(type = "scatter")gains anannotate_fitargument (defaultTRUE): annotates each survey’s regression line with its fitted equation and R², coloured to match that survey. -
compare_models()andcompare_meshes()had the same silent-NA-CRS bug as thecompare_surveys()fix above; fixed the same way. Found by actually running every function’s roxygen example end-to-end (see below) — prior examples happened to always passobject_crsexplicitly, so this had never surfaced. -
bubble_map()’s legend was rendering as two separate, mismatched legends (one binned colour swatch legend, one continuous size legend), and printed an “Ignoring unknown labels: colour” warning. Fixed: thefill/colourandsizescales now use matchingguide = "bins"so ggplot2 merges them into one combined size+colour legend, and a redundantshapeaesthetic mapping (constant within each already-split zero/non-zero data subset, but was breaking the guide merge even withguide = "none") is now a fixed value per layer instead of a mapped-but-hidden aesthetic. - Every exported function now has a working
@examplesblock. SincesdmTMBis an Imports (not Depends) dependency, unqualified calls likepcodormake_mesh()fail outside a session withlibrary(sdmTMB)attached — one existing example (plot_residual_qq()) had this bug. Slow (model-fitting) examples are wrapped in\dontrun{}, which — unlike\donttest{}— is never run by this package’sR CMD check(even under--as-cran) but does run on the pkgdown site (run_dont_run = TRUEis now passed in.github/workflows/pkgdown.yaml). Seememory/examples-policy.md. -
sdmTMB_mesh_cv()(spatial block cross-validation across mesh cutoffs, viablockCV::cv_spatial()+sdmTMB::sdmTMB_cv()) is confirmed working end-to-end and now has a real, runnable example (was previously untested, with a placeholder example referencing an undefinedfit).