Skip to contents

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.

What is recorded

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.

What happens on load

loadFit()

When you load a fit and the installed nlmixr2est or rxode2 differs from the version that produced it, loadFit() warns:

fit2 <- loadFit("fit")
#> Warning: this fit was run with nlmixr2est 6.2.0 (installed 6.3.0)

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.

The := caching operator

The := 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 packages

    Choosing 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 fit

If 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).

Turning the check on or off

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)

Always load, never rerun

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:

fit2 <- loadFit("fit", checkVersion = FALSE) # load this one quietly

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:

options(nlmixr2save.checkVersion = FALSE)

Loading without checking the model/data hash

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.

Backward compatibility

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.