【问题标题】:How to combine multiple drake targets into a single cross target without combining the datasets?如何在不组合数据集的情况下将多个德雷克目标组合成一个交叉目标?
【发布时间】:2019-09-05 10:50:59
【问题描述】:

德雷克岩石!我有一个复杂的多级处理问题。这个问题可以用这个例子来说明。我在级别 l 有 2 个进程,我希望 all 级别 1 进程生成的所有数据集都由级别 2 的单个目标处理。

下面的代码做了我想要的,但我必须在第 2 级重复代码,在我的复杂情况下,这似乎是错误的。



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


由reprex package (v0.3.0) 于 2019-09-05 创建

我想将 process2[ab] 步骤合并到一个目标中。这可能吗?

似乎我应该能够有一个单一的目标,例如:


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

但这不起作用。

【问题讨论】:

    标签: r drake-r-package


    【解决方案1】:

    一个紧凑的解决方案是为map() 提供一个自定义的.data 网格。

    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)
    

    由reprex package (v0.3.0) 于 2019-09-05 创建

    但我可能会过度拟合您的示例。另一种方法是使用标签。每个转换都理解arguments .tag_in and .tag_out。在这里,.tag_out 可以定义一个总体分组变量来覆盖process1a_* 和process1b_* 目标。然后,您可以在处理 process2 时将该分组变量传递给 cross()。

    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)
    

    由reprex package (v0.3.0) 于 2019 年 9 月 5 日创建

    【讨论】:

    • “过度拟合你的例子”这句话是一个真正的数据科学家的签名,我个人非常高兴。是的,tag_out 正是我所寻求的。鉴于包装的绝对美感和远见,似乎必须存在这样的东西,以填补生态位。顺便说一句,本周早些时候,几个简单的 Drake 目标替换了我脆弱的缓存代码的大约 500 行,真是一种解脱!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 2015-09-25
    相关资源
    最近更新 更多