By default nlmixr2save writes fits into the working
directory: fit := nlmixr2(...) caches to
./fit.zip, and saveFit(fit) writes
./fit.zip. In a project with more than a couple of models,
that quickly mixes fits in with scripts, reports and data. This article
shows how to keep them all in one place – a models/
directory – by default.
Caching := fits in a directory
The := operator reads three options:
| Option | Default | Effect |
|---|---|---|
nlmixr2save.dir |
"." |
Directory the cache files live in (created when needed) |
nlmixr2save.prefix |
"" |
String prepended to the variable name to name the cache file |
nlmixr2save.check |
TRUE |
Whether a cached fit is checked against the current model, data and arguments |
To send every cache to models/, set the directory
once:
library(nlmixr2)
library(nlmixr2save)
options(nlmixr2save.dir = "models")
fit := nlmixr2(one.cmt, theo_sd, est = "focei") # fits, writes models/fit.zip
fit := nlmixr2(one.cmt, theo_sd, est = "focei") # loads models/fit.zipThe directory is created the first time something is cached there.
Other values assigned with := (simulations, or functions
registered with saveFitRandom()) are cached there too, as
models/<name>.rds.
Naming the files with a prefix
A prefix keeps caches from different analyses apart in the same directory:
options(nlmixr2save.dir = "models", nlmixr2save.prefix = "pk-")
fit := nlmixr2(one.cmt, theo_sd, est = "focei") # models/pk-fit.zipThe prefix applies only to the file name on disk. The variable is
still fit, and inside the archive the fit is stored under
its bare name, so models/pk-fit.zip is an ordinary fit
archive that loadFit() reads like any other.
Setting the directory for a whole project
Options last for the R session, so set them where every script and report picks them up.
A project .Rprofile. R runs the
.Rprofile in the directory it starts in, so the setting
applies to every session in the project:
# .Rprofile
options(nlmixr2save.dir = "models")The setup chunk of a report. When a report should be self-contained, set the option at the top instead:
Only for part of a script.
withr::local_options() or
withr::with_options() restore the previous value
afterwards:
withr::with_options(list(nlmixr2save.dir = "models/sensitivity"), {
fitLow := nlmixr2(one.cmt, theo_sd, est = "focei")
fitHigh := nlmixr2(one.cmt, theo_sd, est = "saem")
})Relative paths and rendered reports
A relative nlmixr2save.dir is resolved against the
working directory at the time of the :=. An R
Markdown or Quarto document is rendered from its own folder, so
"models" means reports/models/ for a report in
reports/, but models/ at the project root for
a script run from there. To point everything at one directory, give an
absolute path, for example with the here package:
Saving and loading by path
saveFit() and loadFit() do not read
nlmixr2save.dir; give them the path directly. The directory
is created if needed:
saveFit(fit, "models/run001") # writes models/run001.zip
fit2 <- loadFit("models/run001.zip") # or loadFit("models/run001")The archive holds the fit under its bare name (run001),
not the path it was saved to, so models/run001.zip can be
moved, renamed or sent to a colleague and still loads from wherever it
ends up. loadFit() extracts it to a temporary directory, so
loading never writes into your working directory.
Sharing and clearing the directory
nlmixr2saveShare() and
nlmixr2saveInvalidate() resolve names through the same
options as :=:
options(nlmixr2save.dir = "models", nlmixr2save.prefix = "pk-")
nlmixr2saveShare("fit") # models/pk-fit.zip -> models/pk-fit-noData.zip
nlmixr2saveInvalidate() # removes models/pk-* so := refits next timenlmixr2saveInvalidate() removes every file in
nlmixr2save.dir whose name starts with
nlmixr2save.prefix. With no prefix set, that is
every file in the directory, including fits saved there by hand
with saveFit(). If you keep both kinds of fit in
models/, give the := caches a prefix, or cache
them in a subdirectory such as models/cache.
Keeping the directory under version control
By default := refits when the cached fit no longer
matches the model, the data or the arguments, and when the fit was made
with a different nlmixr2est or rxode2 version
it asks what to do (or, when rendering, warns). For a
models/ directory committed to version control, where the
cache is the result, turn the check off so a cached fit is
loaded whenever it exists:
options(nlmixr2save.dir = "models", nlmixr2save.check = FALSE):= then fits only when the file is missing, and compares
nothing – not the model, not the data, and not the package versions.
Delete the file, or call nlmixr2saveInvalidate(), to refit.
See vignette("version-tracking") for how the two checks
combine.
