I'm using the {targets}
package, trying to create new targets based on existing targets. Whereas it's simple to refer to an existing target by typing its name in NSE-style, I fail to do the same by using a character string as "alias".
Just to be clear about what I'm talking about. I'll show what I mean outside the {targets}
-land first.
If we create a data object such as:
my_vec <- 1:10
We can get it by either typing its name without quotes:
my_vec
#> [1] 1 2 3 4 5 6 7 8 9 10
or as a string using get()
:
get("my_vec")
#> [1] 1 2 3 4 5 6 7 8 9 10
And if, for whatever reason, we want to use an "alias" to my_vec
when we call it, one way (out of many) could be:
get_object_from_alias <- function(alias) {
switch(alias,
"the_1_to_10_vector" = get("my_vec"))
}
get_object_from_alias("the_1_to_10_vector")
#> [1] 1 2 3 4 5 6 7 8 9 10
So just to sum up this little intro: I can call the same object directly by its name:
my_vec
; orget("my_vec")
Or indirectly using its alias "the_1_to_10_vector"
via get_object_from_alias()
.
In {targets}
context
Here's a reproducible example. The bottom line that clearly conveys my question is at the end.
1. To keep things clean, let's create a new R project and load Rstudio.
library(usethis)
usethis::create_project(path = "my_reproducible_project", open = TRUE, rstudio = TRUE)
2. Now we should be inside a new RStudio window, part of my_reproducible_project
.Rproj.
# install.packages("targets")
library(targets)
3. Open a new R markdown file.
4. The following chunks set up the file and create the "targets".
---
title: "Target Markdown"
output: html_document
---
```{r setup, include = FALSE} knitr::opts_chunk$set(tar_interactive = FALSE, collapse = TRUE) ```
# Setup ```{r} library(targets) tar_unscript() ``` # Targets ```{targets raw-data} library(tibble) library(magrittr) tar_target(raw_data, airquality %>% tibble::rowid_to_column("id")) ``` ```{targets processed-data} library(dplyr) list( tar_target(filtered_data_ozone, raw_data %>% filter(!is.na(Ozone))), tar_target(filtered_data_solar_r , raw_data %>% filter(!is.na(Solar.R))) ) ``` # Pipeline ```{r} tar_make() ```
5. At this point, if we run the code above, it should create 3 targets:
raw_data
filtered_data_ozone
filtered_data_solar_r
They are not in the environment, but rather saved as .rds
files in the project's directory. We can bring them to the current environment using tar_read()
. Without assigning them to objects it will simply print them to the console:
# Read the `filtered_data_*` targets ```{r} tar_read(filtered_data_solar_r) tar_read(filtered_data_ozone) ```
So far so good! Here comes my problem
I now want to create a new target by referencing to filtered_data_*
targets indirectly (like I did using "the_1_to_10_vector" alias in the beginning of this post).
Whereas the direct method works no problem:
```{targets join-them-directly-by-target-name} library(dplyr) tar_target(joined_filtered, inner_join(filtered_data_solar_r, filtered_data_ozone)) ``` ```{r} tar_make() # will now create a new target called `joined_filtered` which we can bring using `tar_read()`. ```
But using "aliases" to filtered_data_solar_r
and filtered_data_ozone
won't work!
If we define a utility function for swapping aliases:
swap_alias_for_real_target_name <- function(alias) {
switch(alias,
#aliases # targets actual names
"ozone_without_na" = "filtered_data_ozone",
"solar_r_without_na" = "filtered_data_solar_r")
}
swap_alias_for_real_target_name("ozone_without_na")
#> [1] "filtered_data_ozone"
swap_alias_for_real_target_name("solar_r_without_na")
#> [1] "filtered_data_solar_r"
It won't work when we use it inside tar_target()
, even when converting the string to symbol.
```{targets join-them-by-utility-func-full-example} swap_alias_for_real_target_name = function(alias) { switch(alias, #aliases # targets actual names "ozone_without_na" = "filtered_data_ozone", "solar_r_without_na" = "filtered_data_solar_r") } tar_target(joined_filtered_full_example, inner_join(as.symbol(swap_alias_for_real_target_name("ozone_without_na")), as.symbol(swap_alias_for_real_target_name("solar_r_without_na")) ) ) ``` ```{r} tar_make(joined_filtered_full_example) ```
Error: callr subprocess failed: no applicable method for 'inner_join' applied to an object of class "name"