我有一个类似的计划:
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
)
在编码的地方,德雷克在处理过程中出现错误,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)