0

I created a package to organise my files for an analysis workflow using {drake}. One function creates the Drake plan. This function is called in _drake.R to run the analysis with r_make(). So far so good everything works, I can change some paths and arguments in the function arguments and it creates a new plan to run.

Here is an example code

library(drake)
library(readr)
test_fn_plan <- function(paths, countries) {
    drake_plan(
        data = target(
            read_tsv(file_in(path)),
            transform = map(path = !!paths, country = !!countries, .id = country)
        )
    )
}

test_fn_plan(
    c("path/to/data_IE.tsv", "path/to/data_UK.tsv"),
    c("Ireland", "United Kingdom")
)
#> # A tibble: 2 x 2
#>   target              command                                 
#>   <chr>               <expr>                                  
#> 1 data_Ireland        read_tsv(file_in("path/to/data_IE.tsv"))
#> 2 data_United.Kingdom read_tsv(file_in("path/to/data_UK.tsv"))

Created on 2019-10-29 by the reprex package (v0.3.0)

The problem comes from devtools::check(). The plan steps are considered as global variables, undefined global variables, and I don't know how to handle them.

I get the following warnings (dozens on my actual code)

  test_fn_plan: no visible binding for global variable ‘path’
  test_fn_plan: no visible binding for global variable ‘country’

I already fixed all the other undefined global variables with rlang's .data$ pronoun. I am left with these warnings and I don't know what to do (except living with it).

Jean
  • 15
  • 7

1 Answers1

0

From this post, it looks like you can call globalVariables() somewhere in your package and be fine. Maybe something like this in the package source?

test_fn_plan <- function(paths, countries) {
  drake_plan(
    data = target(
      read_tsv(file_in(path)),
      transform = map(path = !!paths, country = !!countries, .id = country)
    )
  )
}

plan <- test_fn_plan()
utils::globalVariables(plan$target)
landau
  • 5,636
  • 1
  • 22
  • 50
  • Yes, I ended up using `globalVariables` but not `plan$target` because I have some custom grids in different map transformations. So I manually added some names to consider as global variables. This is although not optimal as this could interfere with the global variable check of normal functions (not not `drake_plan` function) I am sure there are ways to refactor my plan to make it simpler, I also think things might look less hacky once dynamic branching with Drake will be released. – Jean Oct 30 '19 at 15:14
  • Glad you are following dynamic branching! I'm actually working on the implementation now! – landau Oct 30 '19 at 15:25
  • Also, utils::globalVariables(codetools::findGlobals(test_fn_plan)) is probably an easier solution to your original question. – landau Oct 30 '19 at 15:26
  • Yes! To be placed in `zzz.R` to load at the end. It did the trick but it might be a bit too much, I will tinker with it because it adds functions defined in the package and a lot of other functions or variables such as `c`, `{`, `::`, or `sprintf` or objects from other packages already re-exported like `.data`, `syms` etc. I am afraid it will cause problems in the future – Jean Oct 30 '19 at 15:43
  • `codetools::findGlobals(test_fn_plan, merge = FALSE)$variables` is better, it only returns the variables, not the functions – Jean Oct 30 '19 at 15:45
  • except for `combine` which is the only transformation verb that doesn't have an equivalent in purrr (when loaded) or base R, unlilke `map` and `cross` – Jean Oct 30 '19 at 15:49