У меня есть план вроде:
plan = drake::drake_plan(
targ1 = target(
f1(input)
, dynamic = map(input)
)
, targ2 = target(
f2(targ1)
, dynamic = map(targ1)
)
)
Где функция f1
на самом деле выдает несколько фрагментов вывода (скажем, в списке), и я бы хотел, чтобы эти несколько фрагментов обрабатывались отдельно когда вычисляется targ2
. Возможно ли это?
Вот минимальный пример:
f1 = function(x){
return(list(x,x+1))
}
f2 = function(x){
return(x*2)
}
input = c(1,99)
plan = drake::drake_plan(
targ1 = target(
f1(input)
, dynamic = map(input)
)
, targ2 = target(
f2(targ1)
, dynamic = map(targ1)
)
)
drake::make(
plan
)
Где, как указано в коде, drake получает ошибку при обработке targ2
, потому что список в каждой подцели из targ1
не имеет еще не развалился. Очевидно, я мог бы переписать f2
, чтобы перебирать список, но это было сделано для демонстрационных целей, и в моем фактическом варианте использования есть веские причины для того, чтобы просто разделить результаты из targ1
.
Я подумал Я решил это с помощью:
f1 = function(x){
return(list(x,x+1))
}
f2 = function(x){
return(x*2)
}
input = c(1,99)
plan = drake::drake_plan(
targ1 = target(
f1(input)
, dynamic = map(input)
)
, targ2 = target(
unlist(targ1)
)
, targ3 = target(
f2(targ2)
, dynamic = map(targ2)
)
)
Но в моем реальном случае использования каждая подцель занимает много памяти, и вычисление targ2
, похоже, требует переноса их всех в память, вызывая блокировку поскольку на моей машине заканчивается память.
Я разработал хак, в котором я сохраняю отдельные элементы списка из каждой подцели в targ1 в файл, а затем выполняю list_files()
поиск всех таких файлов в качестве ввода для более позднего мишени, а может есть попроще?
Вот хак, который "работает", но явно не идеален:
library(drake)
f1 = function(x){
out = list(x,x+1)
for(i in 1:length(out)){
a = out[[i]]
save(a,file=paste0(digest::digest(a),'.rda'))
}
return(digest::digest(out))
}
f2 = function(x){
list.files(pattern='.rda')
}
f3 = function(this_rda){
load(this_rda)
return(a)
}
f4 = function(x){
return(x*2)
}
input = c(1,99)
plan = drake::drake_plan(
targ1 = target(
f1(input)
, dynamic = map(input)
)
, targ2 = target(
f2(targ1)
)
, targ3 = target(
f3(targ2)
, dynamic = map(targ2)
)
, targ4 = target(
f4(targ3)
, dynamic = map(targ3)
)
)
drake::make(plan)
readd(targ4)