Saya punya rencana seperti:

plan = drake::drake_plan(

    targ1 = target(
        f1(input)
        , dynamic = map(input)
    )

    , targ2 = target(
        f2(targ1)
        , dynamic = map(targ1)
    )
)

Di mana fungsi f1 benar-benar menghasilkan beberapa potongan output (katakanlah, dalam daftar), dan saya ingin beberapa potongan ini diproses secara terpisah ketika targ2 dihitung. Apakah ini mungkin?

Berikut adalah contoh minimal:

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
)

Sedangkan pada kode, drake mendapatkan error dalam memproses targ2 karena daftar di setiap subtarget dari targ1 belum terpecahkan. Jelas saya bisa menulis ulang f2 untuk mengulangi daftar, tetapi ini untuk tujuan demonstrasi dan dalam kasus penggunaan saya yang sebenarnya ada alasan bagus untuk hanya membagi hasil dari targ1.

Saya pikir saya telah menyelesaikannya dengan:

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)
    )
)

Tetapi dalam kasus penggunaan saya yang sebenarnya, setiap subtarget menghabiskan banyak memori, dan perhitungan targ2 tampaknya mengharuskan memasukkan semuanya ke dalam memori, menyebabkan penguncian saat mesin saya kehabisan memori.

Saya telah melakukan peretasan di mana saya menyimpan elemen daftar individual dari setiap subtarget di targ1 ke file kemudian melakukan pencarian list_files() untuk semua file seperti itu sebagai input ke target selanjutnya, tetapi mungkin ada yang lebih sederhana?

Inilah peretasan yang "berfungsi" tetapi tentu saja kurang ideal:

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)

0
Mike Lawrence 28 Mei 2020, 04:58

1 menjawab

Jawaban Terbaik

drake tidak mendukung percabangan dinamis dalam sub-target dinamis, tetapi Anda dapat menggabungkan percabangan statis dengan percabangan dinamis untuk mencapai sesuatu yang sangat mirip.

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)
#>   )
#> )

Dibuat pada 28-05-2020 oleh paket reprex (v0.3.0)

1
landau 28 Mei 2020, 13:26