How to combine multiple drake targets into a single cross target without combining the datasets?

旧街凉风 提交于 2021-01-05 09:45:07

问题


Drake rocks! I have a complex multistage processing problem. The problem can be illustrated with this example. I have 2 processes at level l, and I want all the datasets generated by all the level 1 processes to be processed by a single target at level 2.

The code below does what I want, but I have to repeat the code at level 2, and in my complex situation, this seems wrong.



library(drake)
library(tidyverse)

f_process1a = function(x) {
  x
}


f_process1b = function(x) {
  x
}


f_process2 = function(data, x) {
  c(data, x )
}


drakeplan <- drake::drake_plan(
  process1a = target(
                    f_process1a (process1a_var),
                    transform = map( process1a_var = c(1,2) )
  )
  ,
  #
  process1b = target(
                    f_process1b ( process1b_var),
                    transform = map(process1b_var = c(2,3) )
  )
  ,
  process2a = target(
                    f_process2( process1a, process2_var ),
                    transform=cross( process1a,  process2_var = c(4,5))
  )
  ,
  process2b = target(
                    f_process2( process1b, process2_var ),
                    transform=cross( process1b,  process2_var = c(4,5))
  )
)


drake_plan_source(drakeplan )
#> drake_plan(
#>   process1a_1 = f_process1a(1),
#>   process1a_2 = f_process1a(2),
#>   process1b_2 = f_process1b(2),
#>   process1b_3 = f_process1b(3),
#>   process2a_4_process1a_1 = f_process2(process1a_1, 4),
#>   process2a_5_process1a_1 = f_process2(process1a_1, 5),
#>   process2a_4_process1a_2 = f_process2(process1a_2, 4),
#>   process2a_5_process1a_2 = f_process2(process1a_2, 5),
#>   process2b_4_process1b_2 = f_process2(process1b_2, 4),
#>   process2b_5_process1b_2 = f_process2(process1b_2, 5),
#>   process2b_4_process1b_3 = f_process2(process1b_3, 4),
#>   process2b_5_process1b_3 = f_process2(process1b_3, 5)
#> )


Created on 2019-09-05 by the reprex package (v0.3.0)

graph

I would like to combine the process2[ab] steps into a single target. Is this possible?

It seems like I should be able to have a single target such as:


  process2 = target(
                    f_process2( data, process2_var ),
                    transform=cross( data=c(process1a, process2a),
                                      process2_var = c(4,5))
  )

But that doesn't work.


回答1:


A compact solution is to supply a custom .data grid to map().

library(drake)
library(rlang)
library(tidyverse)

grid <- tibble(
  fun1 = syms(c("f1a", "f1a", "f1b", "f1b")),
  var1 = c(1, 2, 2, 3)
)

plan <- drake_plan(
  x = target(
    fun1(var1),
    transform = map(.data = !!grid)
  ),
  y = target(
    f2(x, var2),
    transform = cross(x, var2 = c(4, 5))
  )
)

config <- drake_config(plan)
vis_drake_graph(config)

Created on 2019-09-05 by the reprex package (v0.3.0)

But I might be overfitting your example here. Another approach is to use tags. Each transform understands arguments .tag_in and .tag_out. Here, .tag_out can define an overarching grouping variable to cover both the process1a_* and process1b_* targets. Then, you can pass that grouping variable to cross() when you are working on process2.

library(drake)

plan <- drake_plan(
  process1a = target(
    f_process1a(process1a_var),
    transform = map(process1a_var = c(1, 2), .tag_out = process1)
  ),
  process1b = target(
    f_process1b(process1b_var),
    transform = map(process1b_var = c(2, 3), .tag_out = process1)
  ),
  process2 = target(
    f_process2(process1, process2_var),
    transform = cross(process1, process2_var = c(4, 5))
  ),
  trace = TRUE
)

config <- drake_config(plan)
vis_drake_graph(config)

Created on 2019-09-05 by the reprex package (v0.3.0)



来源:https://stackoverflow.com/questions/57803846/how-to-combine-multiple-drake-targets-into-a-single-cross-target-without-combini

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!