1

In an R package, let's say we have two functions. One is setting some parameters; the other one is using those parameters. How can I build such a pattern in R. It is similar to event-driven applications. But I am not sure if it is possible in R or not.

For example: If we run set_param( a=10), whenever we run print_a.R, it prints 10, and incase of running set_param(a=20), it prints 20. I need a solution without assigning value to the global environment because CRAN checks raise notes.

Naeem Khoshnevis
  • 2,001
  • 4
  • 18
  • 30
  • 3
    You could set options and read those options I guess – Dason Jul 16 '21 at 20:10
  • 1
    If you are making a package, you can store values in the package environment, you don't have to use the global environment. Things like [last_plot() in ggplot2](https://github.com/tidyverse/ggplot2/blob/master/R/plot-last.r) do this. It would really be helpful to have some sort of [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) that we can use for testing possible solutions. – MrFlick Jul 16 '21 at 20:12
  • Thanks Dason, and MrFlick. – Naeem Khoshnevis Jul 16 '21 at 20:40

1 Answers1

2

I suggest adding a variable to your package, as @MrFlick suggested.

For instance, in ./R/myoptions.R:

.myoptions <- new.env(parent = emptyenv())

getter <- function(k) {
  .myoptions[[k]]
}

setter <- function(k, v) {
  .myoptions[[k]] <- v
}

lister <- function() {
  names(.myoptions)
}

Then other package functions can use this as a key/value store:

getter("optA")
# NULL
setter("optA", 99)
getter("optA")
# [1] 99
lister()
# [1] "optA"

and all the while, nothing is in the .GlobalEnv:

ls(all.names = TRUE)
# character(0)

Values can be as complex as you want.

Note that these are not exported, so if you want/need the user to have direct access to this, then you'll need to update NAMESPACE or, if using roxygen2, add #' @export before each function definition.


NB: I should add that a more canonical approach might be to use options(.) for these, so that users can preemptively control and have access to them., programmatically.

r2evans
  • 141,215
  • 6
  • 77
  • 149