ixpl
ixpl

Reputation: 279

Make list content available in a function environment

In order to avoid creating R functions with many arguments defining settings for a single object, I'm gathering them in a list,

list_my_obj <- list("var1" = ..., "var2" = ..., ..., "varN" = ...)
class(list_my_obj) <- "my_obj"

I then define functions that accept such a list as argument and inject the elements of the list in the function scope:

my_fun <- function(list_my_obj) {

  stopifnot(class(list_my_obj) == "my_obj")

  list2env(list_my_obj, envir=environment())
  rm(list_my_obj)

  var_sum <- var1 + var2
  (...)

}

Injecting the elements of the list in the function scope allows me to avoid calling them with list_my_obj$var1, list_my_obj$var2, etc, later in the function, which would reduce the readability of the code.

This solution works perfectly fine, however it produces a note when running R CMD check, saying "no visible binding for global variable" for var1, var2, ... varN.

To avoid such notes, one could just create new variables at the beginning of the function body "by hand" for each element of the list:

var1 <- list_my_obj$var1
(...)
varN <- list_my_obj$varN

but I would like to avoid this because N can be large.

Any better solution or idea on how to suppress the R CMD check notes in this case?

Thank you!

Upvotes: 11

Views: 1595

Answers (2)

rsoren
rsoren

Reputation: 4216

The function list2env is made for this, for example:

list2env(list_my_obj, env = environment())

Upvotes: 10

G. Grothendieck
G. Grothendieck

Reputation: 270195

Try with (or within):

f <- function(x) {
   stopifnot(inherits(x, "my_obj"))
   with(x, {
      # ...
      var_sum <- var1 + var2
      # ...
      var_sum
   })
}

my_obj <- structure(list(var1 = 1, var2 = 2), class = "my_obj")
f(my_obj)

Upvotes: 4

Related Questions