A saved nlmixr2 fit is the result of two packages
working together: nlmixr2est estimates the model, and
rxode2 compiles and solves it. A change in either package
can, in principle, change the fit. Because a saved fit is meant to be
reloaded later – possibly months later, on a different machine, with
newer packages installed – nlmixr2save records which
versions produced it and tells you when they no longer match.
This behavior is easy to miss, because when the versions do match (the common case) nothing is printed at all.
When you saveFit() a fit (or cache one with
:=), nlmixr2save stores a small piece of
metadata alongside it: the nlmixr2est and
rxode2 versions, and, when either package
was installed from a remote such as GitHub (via remotes or
pak), its commit sha. The metadata is
embedded in the saved fit’s loader script, so it travels inside the
portable .zip and survives a load -> save round-trip (it
always records the version that ran the fit, not the version
that happened to re-save it).
This version metadata is only the package versions – it does
not itself contain your model or data. The saved fit as a whole is a
different matter: it does store the model and the data it was fit to
(for example in $origData, which is written into the
.zip); see vignette("uses") for what a saved
fit includes.
loadFit()When you load a fit and the installed nlmixr2est or
rxode2 differs from the version that produced it,
loadFit() warns:
The fit still loads normally – the warning is only there to explain
why a reloaded fit might not be bit-for-bit identical to one you would
get by re-running today. loadFit() cannot re-run the fit
itself, because a saved fit does not carry the original
nlmixr2() call.
:= caching operatorThe := operator does have the original call, so
it can offer to re-run. When a cached fit was produced by a different
package version:
In an interactive session, you are asked what to do:
fit := nlmixr2(one.cmt, theo_sd, est = "focei")
#> The cached fit was run with nlmixr2est 6.2.0 (installed 6.3.0).
#>
#> 1: Reload the cached fit as-is
#> 2: Rerun the fit with the installed packagesChoosing 2 re-runs the fit with the currently installed packages and refreshes the cache; choosing 1 keeps the cached fit.
In a non-interactive session (scripts,
R CMD build, CI, rendering a document), there is no one to
ask, so := loads the cached fit and warns:
#> Warning: the cached fit was run with nlmixr2est 6.2.0 (installed 6.3.0);
#> loading the cached fitIf both packages changed, the message names both, e.g.
nlmixr2est 6.2.0 (installed 6.3.0); rxode2 5.1.3 (installed 6.0.0).
The version check is controlled by a single option,
nlmixr2save.checkVersion, which defaults to
TRUE:
# Silence version-mismatch warnings and skip the interactive rerun prompt
options(nlmixr2save.checkVersion = FALSE)
# Turn the check back on (the default)
options(nlmixr2save.checkVersion = TRUE)If you would rather always load the cached fit – never be
interactively asked to rerun, and never warned – set the option to
FALSE. With nlmixr2save.checkVersion = FALSE,
an interactive := behaves exactly like a non-interactive
one used to, except quietly: it loads the cached fit and moves on, no
matter which nlmixr2est or rxode2 version is
installed.
options(nlmixr2save.checkVersion = FALSE)
# loads the cached fit.zip as-is, with no prompt and no warning
fit := nlmixr2(one.cmt, theo_sd, est = "focei")This is the setting to reach for when you have deliberately committed a cache and want it to load unconditionally – for example in a rendered report or in CI, or simply because you prefer to decide when to rerun yourself.
loadFit() also takes a per-call
checkVersion argument, which defaults to the option, so you
can override it for a single load without changing the global
setting:
A common place to set the option is at the top of a script or vignette that deliberately ships a committed cache and does not want version warnings:
By default, := verifies a cached fit against an
md5/hash of the current model, data, and arguments, and
refits when they differ. That check is separate from the version check
described above, and it has its own option,
nlmixr2save.check:
# Load the cache file if it exists, WITHOUT checking the model/data/argument
# md5 -- the cache is trusted and only regenerated when it is missing
options(nlmixr2save.check = FALSE)
fit := nlmixr2(one.cmt, theo_sd, est = "focei")With nlmixr2save.check = FALSE (trusted-cache mode,
described in vignette("uses")), := simply
loads a committed cache whenever the file exists, ignoring any
md5 differences in the model, data, or arguments – and,
because it does no comparison at all, it also never prompts or warns
about package versions. In other words it subsumes
nlmixr2save.checkVersion = FALSE on the :=
path. To force a rerun in this mode, delete the cache with
nlmixr2saveInvalidate() (or remove the file).
Use the two options together to pick exactly what is (and is not) checked:
nlmixr2save.check |
nlmixr2save.checkVersion |
behavior of := on a cache hit |
|---|---|---|
TRUE (default) |
TRUE (default) |
refit if the model/data/args md5 changed;
otherwise warn/prompt if the package version changed |
TRUE |
FALSE |
refit if the md5 changed; ignore package
versions |
FALSE |
(ignored) | always load the cache file if it exists; check nothing |
The nlmixr2save.checkVersion option is the one to reach
for when you are using ordinary (checked) caching or
loadFit() and only want to control the version comparison;
nlmixr2save.check is the one that also turns off the
model/data md5 check.
Fits saved by versions of nlmixr2save that predate this
feature carry no version metadata. Loading them is completely silent:
with nothing to compare against, nlmixr2save never warns
and never prompts.