reproducibility_tools | R Documentation |
Tools for reproducible computations
Description
Archiving of computations and control of the random-number generator.
Usage
bake(
file,
expr,
seed = NULL,
kind = NULL,
normal.kind = NULL,
dependson = NULL,
info = FALSE,
timing = TRUE,
dir = getOption("pomp_archive_dir", getwd())
)
stew(
file,
expr,
seed = NULL,
kind = NULL,
normal.kind = NULL,
dependson = NULL,
info = FALSE,
timing = TRUE,
dir = getOption("pomp_archive_dir", getwd())
)
freeze(
expr,
seed = NULL,
kind = NULL,
normal.kind = NULL,
envir = parent.frame(),
enclos = if (is.list(envir) || is.pairlist(envir)) parent.frame() else baseenv()
)
Arguments
file |
Name of the archive file in which the result will be stored or retrieved, as appropriate.
For |
expr |
Expression to be evaluated. |
seed , kind , normal.kind |
optional.
To set the state and of the RNG.
The default, |
dependson |
arbitrary R object (optional).
Variables on which the computation in |
info |
logical.
If |
timing |
logical.
If |
dir |
Directory holding archive files;
by default, this is the current working directory.
This can also be set using the global option |
envir |
the |
enclos |
relevant when |
Details
On cooking shows, recipes requiring lengthy baking or stewing are prepared beforehand.
The bake
and stew
functions perform analogously:
an computation is performed and archived in a named file.
If the function is called again and the file is present, the computation is not executed.
Instead, the results are loaded from the archive.
Moreover, via their optional seed
argument, bake
and stew
can control the pseudorandom-number generator (RNG) for greater reproducibility.
After the computation is finished, these functions restore the pre-existing RNG state to avoid side effects.
The freeze
function doesn't save results, but does set the RNG state to the specified value and restore it after the computation is complete.
Both bake
and stew
first test to see whether file
exists.
If it does, bake
reads it using readRDS
and returns the resulting object.
By contrast, stew
loads the file using load
and copies the objects it contains into the user's workspace (or the environment of the call to stew
).
If file
does not exist, then both bake
and stew
evaluate the expression expr
;
they differ in the results that they save.
bake
saves the value of the evaluated expression to file
as a single object.
The name of that object is not saved.
By contrast, stew
creates a local environment within which expr
is evaluated; all objects in that environment are saved (by name) in file
.
bake
and stew
also store information about the code executed, the dependencies, and the state of the random-number generator (if the latter is controlled) in the archive file.
Re-computation is triggered if any of these things change.
Value
bake
returns the value of the evaluated expression expr
.
Other objects created in the evaluation of expr
are discarded along with the temporary, local environment created for the evaluation.
The latter behavior differs from that of stew
, which returns the names of the objects created during the evaluation of expr
.
After stew
completes, these objects are copied into the environment in which stew
was called.
freeze
returns the value of evaluated expression expr
.
However, freeze
evaluates expr
within the parent environment, so other objects created in the evaluation of expr
will therefore exist after freeze
completes.
bake
and stew
store information about the code executed, the dependencies, and the state of the random-number generator in the archive file.
In the case of bake
, this is recorded in the “ingredients” attribute (attr(.,"ingredients")
);
in the stew
case, this is recorded in an object, “.ingredients”, in the archive.
This information is returned only if info=TRUE
.
The time required for execution is also recorded.
bake
stores this in the “system.time” attribute of the archived R object;
stew
does so in a hidden variable named .system.time
.
The timing is obtained using system.time
.
Avoid using ‘pomp’ objects as dependencies
Note that when a ‘pomp’ object is built with one or more C snippets, the resulting code is “salted” with a random element to prevent collisions in parallel computations.
As a result, two such ‘pomp’ objects will never match perfectly, even if the codes and data used to construct them are identical.
Therefore, avoid using ‘pomp’ objects as dependencies in bake
and stew
.
Compatibility with older versions
With pomp version 3.4.4.2, the behavior of bake
and stew
changed.
In particular, older versions did no dependency checking, and did not check to see whether expr
had changed.
Accordingly, the archive files written by older versions have a format that is not compatible with the newer ones.
When an archive file in the old format is encountered, it will be updated to the new format, with a warning message.
Note that this will overwrite existing archive files!
However, there will be no loss of information.
Author(s)
Aaron A. King
Examples
## Not run:
bake(file="example1.rds",{
x <- runif(1000)
mean(x)
})
bake(file="example1.rds",{
x <- runif(1000)
mean(x)
})
bake(file="example1.rds",{
a <- 3
x <- runif(1000)
mean(x)
})
a <- 5
b <- 2
stew(file="example2.rda",
dependson=list(a,b),{
x <- runif(10)
y <- rnorm(n=10,mean=a*x+b,sd=2)
})
plot(x,y)
set.seed(11)
runif(2)
freeze(runif(3),seed=5886730)
runif(2)
freeze(runif(3),seed=5886730)
runif(2)
set.seed(11)
runif(2)
runif(2)
runif(2)
## End(Not run)