The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
Parameters of a pipeline are usually plain values such as numbers or strings. Some packages, however, store annotated values as parameters: numbers with a unit, values with a label and a description, or parameter objects that carry metadata for a user interface. The step functions usually need the plain value, though.
Without further help, every step function of such a pipeline would
have to unwrap its arguments itself, or be wrapped in a function that
does so. The generic pip_param_value() is a single hook for
this. You write one method for your class, and the pipeline applies it
whenever a step is run.
Let’s use a simple class that holds a number together with its unit.
library(pipeflow)
quantity <- function(value, unit) {
structure(list(value = value, unit = unit), class = "quantity")
}
print.quantity <- function(x, ...) {
cat("<quantity>", x$value, x$unit, "\n")
invisible(x)
}
quantity(120, "km")
# <quantity> 120 kmWe use it as the parameters of a step that computes a speed.
p <- pip_new("speed") |>
pip_add("speed", \(distance = 1, time = 1) distance / time)
pip_set_params(
p,
list(distance = quantity(120, "km"), time = quantity(2, "h"))
)Running the pipeline fails, because the step function receives the
quantity objects, not the numbers:
pip_param_value() is an S3 generic, which has a default
method that returns the value unchanged. For our class we add a method
that returns the plain value.
Inside a script, register the method with
registerS3method():
In a package, register it in the NAMESPACE file instead,
either directly with
S3method(pipeflow::pip_param_value, quantity) or, if you
use roxygen, by tagging the method with
@exportS3Method pipeflow::pip_param_value. Methods are
meant for your own classes, not for base classes such as
numeric or character.
Now the pipeline runs:
The step function received the plain numbers, while the stored parameters still hold the annotated values.
The generic is applied once to each unbound argument of a
step right before the step function is called. This includes extra
parameters passed on via ...:
p2 <- pip_new("defaults") |>
pip_add(
"describe",
\(x = quantity(3, "m"), ...) {
c(x = class(x), dots = sapply(list(...), class))
},
params = list(extra = quantity(1, "s"))
)
pip_run(p2, lgr = NULL)
p2[["describe", "out"]]
# x dots.extra
# "numeric" "numeric"The generic is not applied to
~step,pip_run(on_error = "continue")).Step outputs, for example, are passed on as they are:
p3 <- pip_new("outputs") |>
pip_add("make", \(v = 3) quantity(v, "m")) |>
pip_add("inspect", \(q = ~make) class(q))
pip_run(p3, lgr = NULL)
p3[["inspect", "out"]]
# [1] "quantity"The quantity that make returns reaches
inspect untouched.
A method runs as part of the step call. An error in a method is therefore an error of the step, handled like any other step error as described in the vignette on handling failures. Let’s add a class that checks its unit.
checked <- function(value, unit) {
structure(list(value = value, unit = unit), class = "checked")
}
pip_param_value.checked <- function(x, ...) {
if (!x$unit %in% c("m", "km")) {
stop("unknown unit '", x$unit, "'")
}
x$value
}
registerS3method("pip_param_value", "checked", pip_param_value.checked)
p4 <- pip_new("errors") |>
pip_add("double", \(x = 1) x * 2) |>
pip_add("increment", \(y = ~double) y + 1)
pip_set_params(p4, list(x = checked(1, "ft")))By default, the run stops and the message tells which step failed:
tryCatch(
pip_run(p4, lgr = NULL),
error = \(e) conditionMessage(e)
)
# [1] "step 'double': unknown unit 'ft'"With on_error = "continue", the step is marked as failed
and the run goes on with the steps that don’t depend on it. The run also
signals a pipeflow_run_failed warning, which we suppress
here.
suppressWarnings(
pip_run(p4, lgr = NULL, on_error = "continue")
)
pip_data(p4)[, c("step", "state")]
# step state
# <char> <char>
# 1: double failed
# 2: increment newAs usual, the condition of the failed step is stored as its output.
pip_param_value(x) unwraps a stored parameter value
right before the step function is called, and it does not change the
stored parameters.params, defaults,
and ...), not to step outputs, partitions or failure
objects.on_error
applies.These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.