My function that produces a target depends not only on a data.frame
but also on additional parameters. Like:
# _targets.R
library(targets)
mydat <- function() data.frame(time=1901:2020, val=letters[1:10])
myfun <- function(dat, from, to) subset(dat, time>from & time<to)
list(
tar_target(dat, mydat()),
tar_target(dat_of_interest, myfun(dat, from=2019, to=2020)
)
Now I wonder how to define the target pipeline so it is aware of changes in the parameters? Is there a best practice?
targets
is smart enough to check dependencies on globals too, so you can simply write:
library(targets)
mydat <- function() data.frame(time = 1901:2020, val = letters[1:10])
myfun <- function(dat, from, to) subset(dat, time >= from & time <= to)
from <- 2018
to <- 2020
list(
tar_target(dat, mydat()),
tar_target(dat_of_interest, myfun(dat, from = from, to = to))
)
tar_make()
# ▶ start target dat
# ● built target dat [0.02 seconds]
# ▶ start target dat_of_interest
# ● built target dat_of_interest [0 seconds]
# ▶ end pipeline [4.39 seconds]
tar_make()
# ✔ skip target dat
# ✔ skip target dat_of_interest
# ✔ skip pipeline [2.62 seconds]
from <- 2017
tar_make()
# ✔ skip target dat
# ▶ start target dat_of_interest
# ● built target dat_of_interest [0 seconds]
# ▶ end pipeline [3.5 seconds]
However, you can also be more specific about it and make it an own target, either by hardcoding the constant in the target, or by creating a wrapper function:
tar_target(from, 2019)
## or
get_from <- function() {
2019
}
tar_target(from, get_from())
In the first case, to change from
change the value in tar_target
in the latter case change the return value of the function. I would either go for the global approach or the wrapper function.