我正在使用该{targets}
软件包,尝试根据现有目标创建新目标。虽然通过以 NSE 样式键入现有目标的名称来引用现有目标很简单,但我无法通过使用字符串作为“别名”来做到这一点。
只是为了清楚我在说什么。我将首先说明我在-land
之外的意思。如果我们创建一个数据对象,例如:{targets}
my_vec <- 1:10
我们可以通过输入不带引号的名称来获取它:
my_vec
#> [1] 1 2 3 4 5 6 7 8 9 10
或作为字符串使用get()
:
get("my_vec")
#> [1] 1 2 3 4 5 6 7 8 9 10
如果,无论出于何种原因,我们想my_vec
在调用它时使用“别名”,一种方式(在众多方式中)可能是:
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
所以总结一下这个小介绍:我可以直接用它的名字来调用同一个对象:
my_vec
; 或者get("my_vec")
或者间接使用它的别名"the_1_to_10_vector"
via get_object_from_alias()
。
在{targets}
上下文中
这是一个可重现的示例。清楚地表达我的问题的底线在最后。
1.为了保持干净,让我们创建一个新的 R 项目并加载 Rstudio。
library(usethis)
usethis::create_project(path = "my_reproducible_project", open = TRUE, rstudio = TRUE)
2.现在我们应该在一个新的 RStudio 窗口中,它是my_reproducible_project
.Rproj 的一部分。
# install.packages("targets")
library(targets)
3.打开一个新的 R markdown 文件。
4.以下块设置文件并创建“目标”。
---
title: "Target Markdown"
output: html_document
---
```{r 设置,包括 = FALSE} knitr::opts_chunk$set(tar_interactive = FALSE, collapse = TRUE) ```
# 设置 ```{r} 图书馆(目标) tar_unscript() ``` # 目标 ```{目标原始数据} 图书馆(小标题) 图书馆(magrittr) tar_target(raw_data, airquality %>% tibble::rowid_to_column("id")) ``` ```{目标处理数据} 图书馆(dplyr) 列表( tar_target(filtered_data_ozone, raw_data %>% filter(!is.na(Ozone))), tar_target(filtered_data_solar_r, raw_data %>% filter(!is.na(Solar.R))) ) ``` # 管道 ```{r} 焦油制作() ```
5.此时,如果我们运行上面的代码,它应该创建 3 个目标:
raw_data
filtered_data_ozone
filtered_data_solar_r
它们不在环境中,而是作为.rds
文件保存在项目目录中。我们可以使用tar_read()
. 如果不将它们分配给对象,它只会将它们打印到控制台:
# 读取 `filtered_data_*` 目标 ```{r} tar_read(filtered_data_solar_r) tar_read(filtered_data_ozone) ```
到目前为止,一切都很好!我的问题来了,我现在想通过
间接
引用filtered_data_*
目标来创建一个新目标(就像我在本文开头使用“the_1_to_10_vector”别名一样)。
而直接方法没有问题:
```{targets join-them-directly-by-target-name} 图书馆(dplyr) tar_target(joined_filtered,inner_join(filtered_data_solar_r,filtered_data_ozone)) ``` ```{r} 焦油制作() # 现在将创建一个名为 `joined_filtered` 的新目标,我们可以使用 `tar_read()` 带来它。 ```
但是使用“别名”是行不通的filtered_data_solar_r
!filtered_data_ozone
如果我们定义一个用于交换别名的实用函数:
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"
当我们在内部使用它时它不会起作用tar_target()
,即使在将字符串转换为符号时也是如此。
```{targets join-them-by-utility-func-full-example} swap_alias_for_real_target_name = 函数(别名){ 开关(别名, #aliases # 以实际名称为目标 "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) ```
错误:调用子进程失败:没有适用于“inner_join”的方法应用于“名称”类的对象