0

我有一个类似的计划:

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)

4

1 回答 1

1

drake不支持动态子目标中的动态分支,但您可以将静态分支与动态分支结合起来实现非常相似的效果。

library(drake)
input_values <- c(1, 99)
plan <- drake_plan(
  targ1 = target(
    f1(input),
    transform = map(input = !!input_values)
  ),
  targ2 = target(
    f2(targ1),
    transform = map(targ1),
    dynamic = map(targ1)
  )
)

drake_plan_source(plan)
#> drake_plan(
#>   targ1_1 = f1(1),
#>   targ1_99 = f1(99),
#>   targ2_targ1_1 = target(
#>     command = f2(targ1_1),
#>     dynamic = map(targ1_1)
#>   ),
#>   targ2_targ1_99 = target(
#>     command = f2(targ1_99),
#>     dynamic = map(targ1_99)
#>   )
#> )

reprex 包(v0.3.0)于 2020 年 5 月 28 日创建

于 2020-05-28T13:26:57.107 回答