6

I would like to have a set of colors become defined when a package loads and cleared when package detaches.

What I've come up with that seems to work is shown in the following toy example which relies on deep assignment (which I know to be evil)

.onLoad <- function(libname, pkgname) {

}

.registerColors <- function(){
  C.1 <<- c("#FF0000FF", "#80FF00FF", "#00FFFFFF", "#8000FFFF")
  C.2 <<- c("#00AAFFFF", "#0000FFFF", "#AA00FFFF", "#FF00AAFF")
}

.onUnload <- function(libpath){
}
.onAttach <- function(libname, pkgname) {
  .registerColors()
  packageStartupMessage("Welcome to XYZ")
}

.onDetach <- function(libname, pkgname) {
  rm(C.1, C.2, pos = 1)
  packageStartupMessage("Buh-bye")
}

In this case, plot(seq(1:4, col = C.1) works. Is there a better or more elegant or less potentially destructive way to implement this?

Avraham
  • 1,655
  • 19
  • 32

2 Answers2

5

You don't really need to go to all that trouble. Just define a function that checks if the package is loaded, and returns the appropriate colours.

chooseCols <- function()
{
    if("this_package" %in% search())
        C.1
    else # use default colours
}

plot(1:4, col=chooseCols())
Hong Ooi
  • 56,353
  • 13
  • 134
  • 187
  • I actually have a list of 12 color palettes, each of length 4, which we want to use. So we'd like the users to assign the name of the palette in calls like `scale_fill_manual(value = C.3` or `plot(x, y, col = C.7[2])`. The user's choice will need to be either the name of the palette or the name & location of a specific color. – Avraham May 18 '17 at 20:10
  • You can easily extend this approach to any complexity desired. – Hong Ooi May 18 '17 at 20:35
0

What seems to work the way I want it to is:

.registerColors <- function(){
  assign(x = 'C.1', value = c("#FF0000FF", "#80FF00FF", "#00FFFFFF", "#8000FFFF"), pos = 2)
  assign(x = 'C.2', value = c("#00AAFFFF", "#0000FFFF", "#AA00FFFF", "#FF00AAFF"), pos = 2)
}

.onAttach <- function(libname, pkgname) {
  .registerColors()
}

Now the colors are accessible by name, they do not appear in the global environment search list (saving us from evil), and thus they don't need to be cleared manually on detach, as the package environment in which they live is automatically cleared on detach.

The benefit of this is that the users can now just access the palettes directly as variables without the need for a function call.

Avraham
  • 1,655
  • 19
  • 32