Skip to content

Commit

Permalink
Fix #191
Browse files Browse the repository at this point in the history
  • Loading branch information
wlandau committed Sep 24, 2024
1 parent 92cdae0 commit 1c6f39d
Show file tree
Hide file tree
Showing 67 changed files with 1,119 additions and 4,455 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Description: Function-oriented Make-like declarative pipelines for
reproducible pipelines concisely and compactly.
The methods in this package were influenced by the 'drake' R package
by Will Landau (2018) <doi:10.21105/joss.00550>.
Version: 0.9.1.9000
Version: 0.9.1.9001
License: MIT + file LICENSE
URL: https://docs.ropensci.org/tarchetypes/, https://github.com/ropensci/tarchetypes
BugReports: https://github.com/ropensci/tarchetypes/issues
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export(tar_map2)
export(tar_map2_count)
export(tar_map2_count_raw)
export(tar_map2_group)
export(tar_map2_raw)
export(tar_map2_run)
export(tar_map2_run_rep)
export(tar_map2_size)
Expand Down
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# tarchetypes 0.9.1.9000 (development)
# tarchetypes 0.9.1.9001 (development)

* Add a `delimiter` argument to `tar_map()` etc. for customizing separators in target names (#177, @psychelzh).
* Add "raw" hook functions (#185, @multimeric).
* Add `tar_assign()` (#186, https://github.com/ropensci/targets/issues/1309, @hadley).
* Merge help files of "_raw" functions (#191, @hadley).

# tarchetypes 0.9.0

Expand Down
22 changes: 20 additions & 2 deletions R/tar_cue_age.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,32 @@
#' The age of the target is determined by `targets::tar_timestamp()`,
#' and the way the time stamp is calculated is explained
#' in the Details section of the help file of that function.
#'
#' `tar_cue_age()` expects an unevaluated symbol for the `name`
#' argument, whereas `tar_cue_age_raw()` expects a character string
#' for `name`.
#' @details `tar_cue_age()` uses the time stamps from `tar_meta()$time`.
#' If no time stamp is recorded, the cue defaults to the ordinary
#' invalidation rules (i.e. `mode = "thorough"` in `targets::tar_cue()`).
#' @inheritSection tar_age Dynamic branches at regular time intervals
#' @return A cue object. See the "Cue objects" section for background.
#' @inheritSection tar_cue_force Cue objects
#' @inheritParams tar_cue_age_raw
#' @param name Symbol, name of the target.
#' @inheritSection tar_cue_force Cue objects
#' @inheritParams targets::tar_cue
#' @param name Name of the target.
#' `tar_cue_age()` expects an unevaluated symbol for the `name`
#' argument, whereas `tar_cue_age_raw()` expects a character string
#' for `name`.
#' @param age A `difftime` object of length 1, such as
#' `as.difftime(3, units = "days")`. If the target's output data
#' files are older than `age` (according to the most recent
#' time stamp over all the target's output files)
#' then the target will rerun.
#' On the other hand, if at least one data file is
#' younger than `Sys.time() - age`, then the ordinary
#' invalidation rules apply, and the target may or not rerun.
#' If you want to force the target to run every 3 days,
#' for example, set `age = as.difftime(3, units = "days")`.
#' @examples
#' if (identical(Sys.getenv("TAR_LONG_EXAMPLES"), "true")) {
#' targets::tar_dir({ # tar_dir() runs code from a temporary directory.
Expand Down
50 changes: 1 addition & 49 deletions R/tar_cue_age_raw.R
Original file line number Diff line number Diff line change
@@ -1,53 +1,5 @@
#' @title Cue to run a target when the last run reaches a certain age
#' (raw version)
#' @rdname tar_cue_age
#' @export
#' @family cues
#' @description `tar_cue_age_raw()` acts like `tar_cue_age()`
#' except the `name` argument is a character string,
#' not a symbol. `tar_cue_age_raw()` creates a cue object to
#' rerun a target if the most recent output data becomes old enough.
#' The age of the target is determined by `targets::tar_timestamp()`,
#' and the way the time stamp is calculated is explained
#' in the Details section of the help file of that function.
#' @details `tar_cue_age_raw()` uses the time stamps from `tar_meta()$time`.
#' If no time stamp is recorded, the cue defaults to the ordinary
#' invalidation rules (i.e. `mode = "thorough"` in `targets::tar_cue()`).
#' @inheritSection tar_age Dynamic branches at regular time intervals
#' @return A cue object. See the "Cue objects" section for background.
#' @inheritSection tar_cue_force Cue objects
#' @inheritParams targets::tar_cue
#' @param name Character of length 1, name of the target.
#' @param age A `difftime` object of length 1, such as
#' `as.difftime(3, units = "days")`. If the target's output data
#' files are older than `age` (according to the most recent
#' time stamp over all the target's output files)
#' then the target will rerun.
#' On the other hand, if at least one data file is
#' younger than `Sys.time() - age`, then the ordinary
#' invalidation rules apply, and the target may or not rerun.
#' If you want to force the target to run every 3 days,
#' for example, set `age = as.difftime(3, units = "days")`.
#' @examples
#' if (identical(Sys.getenv("TAR_LONG_EXAMPLES"), "true")) {
#' targets::tar_dir({ # tar_dir() runs code from a temporary directory.
#' targets::tar_script({
#' library(tarchetypes)
#' list(
#' targets::tar_target(
#' data,
#' data.frame(x = seq_len(26)),
#' cue = tarchetypes::tar_cue_age_raw(
#' name = "data",
#' age = as.difftime(0.5, units = "secs")
#' )
#' )
#' )
#' })
#' targets::tar_make()
#' Sys.sleep(0.6)
#' targets::tar_make()
#' })
#' }
tar_cue_age_raw <- function(
name,
age,
Expand Down
12 changes: 11 additions & 1 deletion R/tar_eval.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,24 @@
#' @description Loop over a grid of values, create an expression object
#' from each one, and then evaluate that expression.
#' Helps with general metaprogramming.
#'
#' [tar_eval()] expects an unevaluated expression for
#' the `expr` object, whereas [tar_eval_raw()] expects an
#' evaluated expression object.
#' @return A list of return values from the generated expression objects.
#' Often, these values are target objects.
#' See the "Target objects" section for background
#' on target objects specifically.
#' @inheritSection tar_map Target objects
#' @inheritParams tar_eval_raw
#' @inheritParams tar_sub
#' @param expr Starting expression. Values are iteratively substituted
#' in place of symbols in `expr` to create each new expression,
#' and then each new expression is evaluated.
#'
#' [tar_eval()] expects an unevaluated expression for
#' the `expr` object, whereas [tar_eval_raw()] expects an
#' evaluated expression object.
#' @param envir Environment in which to evaluate the new expressions.
#' @examples
#' # tar_map() is incompatible with tar_render() because the latter
#' # operates on preexisting tar_target() objects. By contrast,
Expand All @@ -27,6 +36,7 @@
#' path <- tempfile()
#' file.create(path)
#' str(tar_eval(tar_render(name, path), values = values))
#' str(tar_eval_raw(quote(tar_render(name, path)), values = values))
#' # So in your _targets.R file, you can define a pipeline like as below.
#' # Just make sure to set a unique name for each target
#' # (which tar_map() does automatically).
Expand Down
43 changes: 1 addition & 42 deletions R/tar_eval_raw.R
Original file line number Diff line number Diff line change
@@ -1,46 +1,5 @@
#' @title Evaluate multiple expressions created with symbol substitution
#' (raw version).
#' @rdname tar_eval
#' @export
#' @family Metaprogramming utilities
#' @description Loop over a grid of values, create an expression object
#' from each one, and then evaluate that expression.
#' Helps with general metaprogramming. Unlike [tar_sub()],
#' which quotes the `expr` argument, `tar_sub_raw()` assumes `expr`
#' is an expression object.
#' @return A list of return values from evaluating the expression objects.
#' Often, these values are target objects.
#' See the "Target objects" section for background
#' on target objects specifically.
#' @inheritSection tar_map Target objects
#' @inheritParams tar_sub_raw
#' @param expr Expression object with the starting expression.
#' Values are iteratively substituted
#' in place of symbols in `expr` to create each new expression,
#' and then each expression is evaluated.
#' @param envir Environment in which to evaluate the new expressions.
#' @examples
#' # tar_map() is incompatible with tar_render() because the latter
#' # operates on preexisting tar_target() objects. By contrast,
#' # tar_eval_raw() and tar_sub_raw() iterate over code farther upstream.
#' values <- list(
#' name = lapply(c("name1", "name2"), as.symbol),
#' file = c("file1.Rmd", "file2.Rmd")
#' )
#' tar_sub_raw(quote(list(name, file)), values = values)
#' tar_sub_raw(quote(tar_render(name, file)), values = values)
#' path <- tempfile()
#' file.create(path)
#' str(tar_eval_raw(quote(tar_render(name, path)), values = values))
#' # So in your _targets.R file, you can define a pipeline like as below.
#' # Just make sure to set a unique name for each target
#' # (which tar_map() does automatically).
#' values <- list(
#' name = lapply(c("name1", "name2"), as.symbol),
#' file = c(path, path)
#' )
#' list(
#' tar_eval_raw(quote(tar_render(name, file)), values = values)
#' )
tar_eval_raw <- function(expr, values, envir = parent.frame()) {
targets::tar_assert_lang(expr)
assert_values_list(values)
Expand Down
47 changes: 43 additions & 4 deletions R/tar_hook_before.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,43 @@
#' @export
#' @family hooks
#' @description Prepend R code to the commands of multiple targets.
#' `tar_hook_before()` expects unevaluated expressions for the `hook` and
#' `names` arguments, whereas `tar_hook_before_raw()` expects
#' evaluated expression objects.
#' @return A flattened list of target objects with the hooks applied.
#' Even if the input target list had a nested structure,
#' the return value is a simple list where each element is a target object.
#' All hook functions remove the nested structure of the input target list.
#' @inheritSection tar_map Target objects
#' @inheritParams tar_hook_before_raw
#' @param hook R code to insert. When you supply code to this argument,
#' the code is quoted (not evaluated) so there is no need
#' to wrap it in `quote()`, `expression()`, or similar.
#' @param hook R code to insert.
#' `tar_hook_before()` expects unevaluated expressions for the `hook` and
#' `names` arguments, whereas `tar_hook_before_raw()` expects
#' evaluated expression objects.
#' @param names Name of targets in the target list
#' to apply the hook. Supplied with `tidyselect` helpers like
#' to apply the hook. Supplied using `tidyselect` helpers like
#' [starts_with()], as in `names = starts_with("your_prefix_")`.
#' Set to `NULL` to include all targets supplied to the `targets` argument.
#' Targets not included in `names` still remain in the target list,
#' but they are not modified because the hook does not apply to them.
#'
#' The regular hook functions expects unevaluated expressions for the `hook`
#' and `names` arguments, whereas the `"_raw"` versions expect
#' evaluated expression objects.
#' @param set_deps Logical of length 1, whether to refresh the dependencies
#' of each modified target by scanning the newly generated
#' target commands for dependencies. If `FALSE`, then the target will
#' keep the original set of dependencies it had before the hook.
#' Set to `NULL` to include all targets supplied to the `targets` argument.
#' `TRUE` is recommended for nearly all situations. Only use `FALSE`
#' if you have a specialized use case and you know what you are doing.
#' @param envir Optional environment to construct the quosure for the `names`
#' argument to select names.
#' @param targets A list of target objects. The input target list
#' can be arbitrarily nested, but it must consist entirely of target
#' objects. In addition, the return value is a simple list
#' where each element is a target object.
#' All hook functions remove the nested structure of the input target list.
#' @examples
#' if (identical(Sys.getenv("TAR_LONG_EXAMPLES"), "true")) {
#' targets::tar_dir({ # tar_dir() runs code from a temporary directory.
Expand All @@ -38,6 +60,23 @@
#' })
#' targets::tar_manifest(fields = command)
#' })
#' # With tar_hook_before_raw():
#' targets::tar_script({
#' targets <- list(
#' # Nested target lists work with hooks.
#' list(
#' targets::tar_target(x1, task1()),
#' targets::tar_target(x2, task2(x1))
#' ),
#' targets::tar_target(x3, task3(x2)),
#' targets::tar_target(y1, task4(x3))
#' )
#' tarchetypes::tar_hook_before_raw(
#' targets = targets,
#' hook = quote(print("Running hook.")),
#' names = quote(starts_with("x"))
#' )
#' })
#' }
tar_hook_before <- function(
targets,
Expand Down
53 changes: 1 addition & 52 deletions R/tar_hook_before_raw.R
Original file line number Diff line number Diff line change
@@ -1,56 +1,5 @@
#' @title Hook to prepend code (raw version)
#' @rdname tar_hook_before
#' @export
#' @family hooks
#' @description Prepend R code to the commands of multiple targets.
#' Like [tar_hook_before()] except that the `hook` and `names`
#' arguments are already pre-quoted language objects.
#' @return A flattened list of target objects with the hooks applied.
#' Even if the input target list had a nested structure,
#' the return value is a simple list where each element is a target object.
#' All hook functions remove the nested structure of the input target list.
#' @inheritSection tar_map Target objects
#' @param targets A list of target objects. The input target list
#' can be arbitrarily nested, but it must consist entirely of target
#' objects. In addition, the return value is a simple list
#' where each element is a target object.
#' All hook functions remove the nested structure of the input target list.
#' @param hook A pre-quoted language object with R code to insert.
#' @param names Name of targets in the target list
#' to apply the hook. Supplied as a language object with a
#' `tidyselect` expression: for example, `names = quote(starts_with("x_"))`.
#' Targets not included in `names` still remain in the target list,
#' but they are not modified because the hook does not apply to them.
#' @param set_deps Logical of length 1, whether to refresh the dependencies
#' of each modified target by scanning the newly generated
#' target commands for dependencies. If `FALSE`, then the target will
#' keep the original set of dependencies it had before the hook.
#' Set to `NULL` to include all targets supplied to the `targets` argument.
#' `TRUE` is recommended for nearly all situations. Only use `FALSE`
#' if you have a specialized use case and you know what you are doing.
#' @param envir Optional environment to construct the quosure for the `names`
#' argument to select names.
#' @examples
#' if (identical(Sys.getenv("TAR_LONG_EXAMPLES"), "true")) {
#' targets::tar_dir({ # tar_dir() runs code from a temporary directory.
#' targets::tar_script({
#' targets <- list(
#' # Nested target lists work with hooks.
#' list(
#' targets::tar_target(x1, task1()),
#' targets::tar_target(x2, task2(x1))
#' ),
#' targets::tar_target(x3, task3(x2)),
#' targets::tar_target(y1, task4(x3))
#' )
#' tarchetypes::tar_hook_before_raw(
#' targets = targets,
#' hook = quote(print("Running hook.")),
#' names = quote(starts_with("x"))
#' )
#' })
#' targets::tar_manifest(fields = command)
#' })
#' }
tar_hook_before_raw <- function(
targets,
hook,
Expand Down
27 changes: 25 additions & 2 deletions R/tar_hook_inner.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
#' @family hooks
#' @description In the command of each target, wrap each mention of
#' each dependency target in an arbitrary R expression.
#'
#' `tar_hook_inner()` expects unevaluated expressions for the `hook` and
#' `names` arguments, whereas `tar_hook_inner_raw()` expects
#' evaluated expression objects.
#' @details The expression you supply to `hook`
#' must contain the special placeholder symbol `.x`
#' so `tar_hook_inner()` knows where to insert the original command
Expand All @@ -17,8 +21,10 @@
#' The hook must contain the special placeholder symbol `.x`
#' so `tar_hook_inner()` knows where to insert the code to wrap
#' mentions of dependencies.
#' The hook code is quoted (not evaluated) so there is no need
#' to wrap it in `quote()`, `expression()`, or similar.
#'
#' `tar_hook_inner()` expects unevaluated expressions for the `hook` and
#' `names` arguments, whereas `tar_hook_inner_raw()` expects
#' evaluated expression objects.
#' @param names_wrap Names of targets to wrap with the hook
#' where they appear as dependencies in the commands of other targets.
#' Use `tidyselect` helpers like [starts_with()], as in
Expand All @@ -43,6 +49,23 @@
#' )
#' })
#' targets::tar_manifest(fields = command)
#' # With tar_hook_inner_raw():
#' targets::tar_script({
#' targets <- list(
#' # Nested target lists work with hooks.
#' list(
#' targets::tar_target(x1, task1()),
#' targets::tar_target(x2, task2(x1))
#' ),
#' targets::tar_target(x3, task3(x2, x1)),
#' targets::tar_target(y1, task4(x3))
#' )
#' tarchetypes::tar_hook_inner_raw(
#' targets = targets,
#' hook = quote(fun(.x)),
#' names = quote(starts_with("x"))
#' )
#' })
#' })
#' }
tar_hook_inner <- function(
Expand Down
Loading

0 comments on commit 1c6f39d

Please sign in to comment.