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_datafiltered_data_ozonefiltered_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"