Вопрос или проблема
Документация гласит:
итерация.
Символ длиной 1, название режима итерации цели. Выборы:
- “vector”: ветвление происходит с помощью vctrs::vec_slice() и агрегация происходит с помощью vctrs::vec_c().
- “list”, ветвление происходит с помощью [[]] и агрегация происходит с помощью list().
Но ниже у меня есть цель df_list
, которая является списком из двух датафреймов. Затем я определяю целевую задачу tar_target(dfproc1, proc1(df_list), pattern = map(df_list), iteration = "list")
. Из вывода видно, что proc1
получил каждый df_list[i]
(а не каждый df_list[[i]]
). Я что-то делаю не так?
library(targets)
library(tarchetypes)
# функции
init <- function() {
data.frame(
g = rep(c(0,1), c(10,2)),
x = 1:12
)
}
filt <- function(df) {
df <- df[df$g==0, ]
df
}
proc1 <- function(df) {
# df <- df[[1]] с этим работает
df$y <- 10
df
}
# цели
list(
tar_target(df, init()),
tar_target(df0, filt(df)),
tar_target(df_list, list(df, df0)),
tar_target(
dfproc1,
proc1(df_list),
pattern = map(df_list),
iteration = "list"
)
)
targets::tar_read(dfproc1)
# $dfproc1_ae5e6cb0c537abdc
# $dfproc1_ae5e6cb0c537abdc[[1]]
# g x
# 1 0 1
# 2 0 2
# 3 0 3
# 4 0 4
# 5 0 5
# 6 0 6
# 7 0 7
# 8 0 8
# 9 0 9
# 10 0 10
# 11 1 11
# 12 1 12
# $dfproc1_ae5e6cb0c537abdc$y
# [1] 10
# $dfproc1_ac8961e3c84c4878
# $dfproc1_ac8961e3c84c4878[[1]]
# g x
# 1 0 1
# 2 0 2
# 3 0 3
# 4 0 4
# 5 0 5
# 6 0 6
# 7 0 7
# 8 0 8
# 9 0 9
# 10 0 10
# $dfproc1_ac8961e3c84c4878$y
# [1] 10
Ожидал список из двух датафреймов, каждый с колонкой y
.
Ответ или решение
Ваша проблема связана с тем, как работает механизм итерации в targets
, особенно когда используется итерация типа "list"
.
Согласно документации, когда вы указываете iteration = "list"
, то разделение (branching) происходит с использованием двойных квадратных скобок [[]]
и агрегация с помощью функции list()
. Однако, в вашем случае код вызывает функцию proc1(df_list)
, что приводит к обработке всего списка df_list
, а не отдельного элемента списка.
Когда вы вызываете proc1(df_list)
, функция получает весь список, и внутри нее не происходит распределения по элементам списка. Вместо этого вам нужно использовать map
для итерации по отдельным элементам списка.
Вам понадобится немного изменить код следующим образом:
library(targets)
library(tarchetypes)
# Функции
init <- function() {
data.frame(
g = rep(c(0, 1), c(10, 2)),
x = 1:12
)
}
filt <- function(df) {
df[df$g == 0, ]
}
proc1 <- function(df) {
df$y <- 10
df
}
# Цели
list(
tar_target(df, init()),
tar_target(df0, filt(df)),
tar_target(df_list, list(df, df0)),
tar_target(
dfproc1,
map(df_list, proc1), # Используйте map здесь
iteration = "list"
)
)
# Чтение результатов
targets::tar_read(dfproc1)
Попробуйте выполнить этот код. Используя map(df_list, proc1)
, вы преобразуете каждый элемент списка df_list
с помощью функции proc1
, тем самым создавая новый список, где каждая таблица будет содержать новый столбец y
.
Такой подход должен создать список из двух фреймов данных, каждый из которых будет содержать столбец y
. После выполнения этой версии кода результат должен быть таким, как вы ожидаете.