1

我有一个工作流,我针对基本相同数据集的变体运行(它是一个 emr 提取,有时我针对批量提取的迭代运行,有时针对测试提取的迭代)。

这些数据集(应该是)同质的,并且通常具有相同的处理要求。

也就是说,在我将项目迁移到 drake 之前,已经对其中一个测试数据集的一个子集执行了很多分析,有时是半交互式的,几乎不能保证可重复性。

尽管通常在我的数据集中我不希望根据分析师开始时使用的相同标准过滤数据集,但对于某些数据集,它有助于验证工作流实际上是否为与原始分析相同的输入产生相同的结果.

分析人员可能使用的起始过滤器示例:

filter_extract_window <- function(df) {
  start <- lubridate::dmy("01-04-2017")
  end   <- lubridate::dmy("30-06-2017")

  df %>%
    dplyr::filter(admit_dttm > start, admit_dttm < end) %>%
    return()
}

给定的数据集与项目代码完全分开存储在包含该数据集的 drake_cache 的目录树和原始数据的子目录中。

那么我的问题是 - 将这样的功能导入我的工作流程的好方法是什么,而不是静态声明的导入?

4

1 回答 1

1

考虑到一些想法,以及写出这个问题所花费的时间,我认为以下方法将适合这个工作流程。

定义filter_extract_window,或代码库/包中的任何等效函数,就像您通常那样,即:

{mypackage}

filter_extract_window <- function(df) {
  start <- lubridate::dmy("01-04-2017")
  end   <- lubridate::dmy("30-06-2017")

  df %>%
    dplyr::filter(admit_dttm > start, admit_dttm < end) %>%
    return()
}

将脚本“filter.R”放在保存数据的同一目录中,该脚本应定义如下:

# The following function is what I want to use to filter this dataset
mypackage::filter_extract_window

在你的代码库(例如,{mypackage})中,编写一个评估这个的函数:

eval_script <- function(path) {
  out <- identity
  if (! file.exists(path) ) return(out)

  out <- parse(file = path) %>% 
    eval(envir = new.env())

  out
}

现在,对于您的drake::drake_plan,我们可能会看到以下内容:

data_root <- "/path/to/your/data"

plan <- drake::drake_plan(
   filter_fn = drake::target(
      mypackage::eval_script(file.path(!!data_root, "filter.R")),
      trigger = drake::trigger(
        change = mypackage::eval_script(file.path(!!data_root, "filter.R"))
      )
   )
)

eval_script 的返回速度应该足够快,以至于在这种情况下使用它作为触发器应该没问题。

于 2020-02-11T05:38:27.317 回答