#' @title One optimization run per model with multiple outputs
#' @export
#' @description `tar_stan_mle()` creates targets to optimize a Stan model once
#' per model and separately save draws-like output and summary-like output.
#' @details Most of the arguments are passed to the `$compile()`,
#' `$optimize()`, and `$summary()` methods of the `CmdStanModel` class.
#' If you previously compiled the model in an upstream [tar_stan_compile()]
#' target, then the model should not recompile.
#' @family optimization
#' @return `tar_stan_mle()` returns a
#' list of target objects. See the "Target objects" section for
#' background.
#' The target names use the `name` argument as a prefix, and the individual
#' elements of `stan_files` appear in the suffixes where applicable.
#' As an example, the specific target objects returned by
#' `tar_stan_mle(name = x, stan_files = "y.stan", ...)`
#' are as follows.
#' * `x_file_y`: reproducibly track the Stan model file. Returns
#' a character vector with paths to
#' the model file and compiled executable.
#' * `x_lines_y`: read the Stan model file for safe transport to
#' parallel workers. Omitted if `compile = "original"`.
#' Returns a character vector of lines in the model file.
#' * `x_data`: run the R expression in the `data` argument to produce
#' a Stan dataset for the model. Returns a Stan data list.
#' * `x_mle_y`: run generated quantities on the model and the dataset.
#' Returns a `cmdstanr` `CmdStanGQ` object with all the results.
#' * `x_draws_y`: extract maximum likelihood estimates from `x_mle_y`
#' in draws format.
#' Omitted if `draws = FALSE`.
#' Returns a wide data frame of MLEs.
#' * `x_summary_y`: extract MLEs from from `x_mle_y` in summary format.
#' Returns a long data frame of MLEs.
#' Omitted if `summary = FALSE`.
#' @inheritSection tar_stan_compile Target objects
#' @inheritParams cmdstanr::cmdstan_model
#' @inheritParams tar_stan_compile_run
#' @inheritParams tar_stan_mle_run
#' @inheritParams tar_stan_summary
#' @inheritParams tar_stan_mcmc
#' @inheritParams targets::tar_target
#' @examples
#' if (Sys.getenv("TAR_LONG_EXAMPLES") == "true") {
#' targets::tar_dir({ # tar_dir() runs code from a temporary directory.
#' targets::tar_script({
#' library(stantargets)
#' # Do not use temporary storage for stan files in real projects
#' # or else your targets will always rerun.
#' path <- tempfile(pattern = "", fileext = ".stan")
#' tar_stan_example_file(path = path)
#' list(
#' tar_stan_mle(
#' your_model,
#' stan_files = path,
#' data = tar_stan_example_data(),
#' stdout = R.utils::nullfile(),
#' stderr = R.utils::nullfile()
#' )
#' )
#' }, ask = FALSE)
#' targets::tar_make()
#' })
#' }
tar_stan_mle <- function(
name,
stan_files,
data = list(),
compile = c("original", "copy"),
quiet = TRUE,
stdout = NULL,
stderr = NULL,
dir = NULL,
pedantic = FALSE,
include_paths = NULL,
cpp_options = list(),
stanc_options = list(),
force_recompile = FALSE,
seed = NULL,
refresh = NULL,
init = NULL,
save_latent_dynamics = FALSE,
output_dir = NULL,
algorithm = NULL,
init_alpha = NULL,
iter = NULL,
tol_obj = NULL,
tol_rel_obj = NULL,
tol_grad = NULL,
tol_rel_grad = NULL,
tol_param = NULL,
history_size = NULL,
sig_figs = NULL,
variables = NULL,
variables_fit = NULL,
summaries = list(),
summary_args = list(),
return_draws = TRUE,
return_summary = TRUE,
draws = NULL,
summary = NULL,
tidy_eval = targets::tar_option_get("tidy_eval"),
packages = targets::tar_option_get("packages"),
library = targets::tar_option_get("library"),
format = "qs",
format_df = "fst_tbl",
repository = targets::tar_option_get("repository"),
error = targets::tar_option_get("error"),
memory = targets::tar_option_get("memory"),
garbage_collection = targets::tar_option_get("garbage_collection"),
deployment = targets::tar_option_get("deployment"),
priority = targets::tar_option_get("priority"),
resources = targets::tar_option_get("resources"),
storage = targets::tar_option_get("storage"),
retrieval = targets::tar_option_get("retrieval"),
cue = targets::tar_option_get("cue"),
description = targets::tar_option_get("description")
) {
assert_variables_fit(variables, variables_fit)
tar_stan_deprecate(draws, "return_draws")
tar_stan_deprecate(summary, "return_summary")
return_draws <- draws %|||% return_draws
return_summary <- summary %|||% return_summary
envir <- tar_option_get("envir")
compile <- match.arg(compile)
targets::tar_assert_chr(stan_files)
targets::tar_assert_unique(stan_files)
lapply(stan_files, assert_stan_file)
name <- targets::tar_deparse_language(substitute(name))
name_stan <- produce_stan_names(stan_files)
name_file <- paste0(name, "_file")
name_lines <- paste0(name, "_lines")
name_data <- paste0(name, "_data")
name_mle <- paste0(name, "_mle")
name_draws <- paste0(name, "_draws")
name_summary <- paste0(name, "_summary")
sym_stan <- as_symbols(name_stan)
sym_file <- as.symbol(name_file)
sym_lines <- as.symbol(name_lines)
sym_data <- as.symbol(name_data)
sym_mle <- as.symbol(name_mle)
command_data <- targets::tar_tidy_eval(
substitute(data),
envir = envir,
tidy_eval = tidy_eval
)
command_draws <- substitute(
tibble::as_tibble(posterior::as_draws_df(
fit$draws(variables = variables)
)),
env = list(fit = sym_mle, variables = variables)
)
command_summary <- tar_stan_summary_call(
sym_fit = sym_mle,
sym_data = sym_data,
summaries = substitute(summaries),
summary_args = substitute(summary_args),
variables = variables
)
args_mle <- list(
call_ns("stantargets", "tar_stan_mle_run"),
stan_file = if_any(identical(compile, "original"), sym_file, sym_lines),
data = sym_data,
compile = compile,
quiet = quiet,
stdout = stdout,
stderr = stderr,
dir = dir,
pedantic = pedantic,
include_paths = include_paths,
cpp_options = cpp_options,
stanc_options = stanc_options,
force_recompile = force_recompile,
seed = seed,
refresh = refresh,
init = init,
save_latent_dynamics = save_latent_dynamics,
output_dir = output_dir,
algorithm = algorithm,
init_alpha = init_alpha,
iter = iter,
sig_figs = sig_figs,
tol_obj = tol_obj,
tol_rel_obj = tol_rel_obj,
tol_grad = tol_grad,
tol_rel_grad = tol_rel_grad,
tol_param = tol_param,
history_size = history_size,
variables = variables_fit
)
command_mle <- as.expression(as.call(args_mle))
target_file <- targets::tar_target_raw(
name = name_file,
command = quote(._stantargets_file_50e43091),
packages = character(0),
format = "file",
repository = "local",
error = error,
memory = memory,
garbage_collection = garbage_collection,
deployment = "main",
priority = priority,
cue = cue,
description = description
)
target_lines <- targets::tar_target_raw(
name = name_lines,
command = command_lines(sym_file),
packages = character(0),
error = error,
memory = memory,
garbage_collection = garbage_collection,
deployment = "main",
priority = priority,
cue = cue,
description = description
)
target_data <- targets::tar_target_raw(
name = name_data,
command = command_data,
packages = packages,
library = library,
format = format,
repository = repository,
error = error,
memory = memory,
garbage_collection = garbage_collection,
deployment = deployment,
priority = priority,
cue = cue,
description = description
)
target_output <- targets::tar_target_raw(
name = name_mle,
command = command_mle,
format = format,
repository = repository,
packages = character(0),
error = error,
memory = memory,
garbage_collection = garbage_collection,
deployment = deployment,
priority = priority,
resources = resources,
storage = storage,
retrieval = retrieval,
cue = cue,
description = description
)
target_draws <- targets::tar_target_raw(
name = name_draws,
command = command_draws,
packages = character(0),
format = format_df,
repository = repository,
error = error,
memory = memory,
garbage_collection = garbage_collection,
deployment = deployment,
priority = priority,
cue = cue,
description = description
)
target_summary <- targets::tar_target_raw(
name = name_summary,
command = command_summary,
packages = packages,
format = format_df,
repository = repository,
error = error,
memory = memory,
garbage_collection = garbage_collection,
deployment = deployment,
priority = priority,
cue = cue,
description = description
)
tar_stan_target_list(
name_data = name_data,
stan_files = stan_files,
sym_stan = sym_stan,
compile = compile,
return_draws = return_draws,
return_summary = return_summary,
return_diagnostics = FALSE,
target_file = target_file,
target_lines = target_lines,
target_data = target_data,
target_output = target_output,
target_draws = target_draws,
target_summary = target_summary,
target_diagnostics = NULL
)
}
#' @title Compile and run a Stan model and return a `CmdStanMLE` object.
#' @export
#' @keywords internal
#' @description Not a user-side function. Do not invoke directly.
#' @return A `CmdStanFit` object.
#' @inheritParams tar_stan_mcmc_run
#' @inheritParams cmdstanr::`model-method-optimize`
tar_stan_mle_run <- function(
stan_file,
data,
compile,
quiet,
stdout,
stderr,
dir,
pedantic,
include_paths,
cpp_options,
stanc_options,
force_recompile,
seed,
refresh,
init,
save_latent_dynamics,
output_dir,
algorithm,
init_alpha,
iter,
sig_figs,
tol_obj,
tol_rel_obj,
tol_grad,
tol_rel_grad,
tol_param,
history_size,
variables
) {
if (!is.null(stdout)) {
withr::local_output_sink(new = stdout, append = TRUE)
}
if (!is.null(stderr)) {
withr::local_message_sink(new = stderr, append = TRUE)
}
file <- stan_file
if (identical(compile, "copy")) {
tmp <- tempfile(pattern = "", fileext = ".stan")
writeLines(stan_file, tmp)
file <- tmp
}
model <- cmdstanr::cmdstan_model(
stan_file = file,
compile = TRUE,
quiet = quiet,
dir = dir,
pedantic = pedantic,
include_paths = include_paths,
cpp_options = cpp_options,
stanc_options = stanc_options,
force_recompile = force_recompile
)
if (is.null(seed)) {
seed <- abs(targets::tar_seed_get()) + 1L
}
stan_data <- data
stan_data$.join_data <- NULL
fit <- model$optimize(
data = stan_data,
seed = seed,
refresh = refresh,
init = init,
save_latent_dynamics = save_latent_dynamics,
output_dir = output_dir,
algorithm = algorithm,
init_alpha = init_alpha,
iter = iter,
sig_figs = sig_figs,
tol_obj = tol_obj,
tol_rel_obj = tol_rel_obj,
tol_grad = tol_grad,
tol_rel_grad = tol_rel_grad,
tol_param = tol_param,
history_size = history_size
)
# Load all the data and return the whole unserialized fit object:
# https://github.com/stan-dev/cmdstanr/blob/d27994f804c493ff3047a2a98d693fa90b83af98/R/fit.R#L16-L18 # nolint
fit$draws(variables = variables)
try(fit$init(), silent = TRUE)
try(fit$profiles(), silent = TRUE)
remove_temp_files(fit)
fit
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.