I’m working on an R Package in which I need to manage the state of various objects over time. Conceptually, when the package loads (.onLoad), it checks for the state object in cache and if it doesn’t exist, a new instance is created, saved to cache, and assigned in the global environment. I’ve not been able to see the object in the global environment using .onLoad() after building the site using devtools :: build(). So, I have three questions:
I’ve scoured SE, read (and re-read) Hadley’s books on R Packages, and Advanced R, brooded over Winston Chang’s vignettes on R6 (links at bottom of post) and I’ve distilled my experiments down to three failed approaches. First, here’s a simple “GameClass” that instantiates a game with three variables, player 1, player 2, and state (of the game).
#' GameClass
#' \code{GameClass} Class that...#'
#' @export
GameClass <- R6::R6Class(
"GameClass",
public = list(
player1 = character(0),
player2 = character(0),
state = character(0),
initialize = function(player1, player2) {
self$player1 <- player1
self$player2 <- player2
self$state <- "1st Match"
}
)
)
Assign the variable to the global environment using the <<- operator
.onLoad <- function(libname, pkgname) {
gameFile <- "./gameFile.Rdata"
if (file.exists(gameFile)) {
game <<- load(gameFile)
} else {
game <<- GameClass$new("Eric", "Cassie")
save(game, file = gameFile)
}
}
Create a new environment and return it
.onLoad <- function(libname, pkgname) {
gameFile <- "./gameFile.Rdata"
e <- new.env()
if (file.exists(gameFile)) {
e$game <- load(gameFile)
} else {
e$game <- GameClass$new("Eric", "Cassie")
save(e$game, file = gameFile)
}
e
}
.onLoad <- function(libname, pkgname) {
gameFile <- "./gameFile.Rdata"
if (file.exists(gameFile)) {
game <- load(gameFile)
} else {
game <- GameClass$new("Eric", "Cassie")
save(game, file = gameFile)
}
assign("game", game, envir = .GlobalEnv)
}
R version 3.4.1 (2017-06-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United
States.1252 LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C LC_TIME=English_United
States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] R6Lab_0.1.0
loaded via a namespace (and not attached):
[1] compiler_3.4.1 R6_2.2.2 tools_3.4.1 yaml_2.1.14
I"m new to OOP, new to R6, this is my first R package and I've been playing around with R for about a year. Clearly, I could benefit from some insight here.
Thanks in advance.
## References ##
[Hadley's Advanced R][1]
[Hadley's R Packages][2]
[Introduction to R6 Classes][3]
[How to define hidden global variables inside R Packages][4]
[Global variables in packages in r][5]
[Global variables in r][6]
[Global variable in a package which approach is more recommended][7]
[1]: http://adv-r.had.co.nz/
[2]: http://r-pkgs.had.co.nz/
[3]: https://cran.r-project.org/web/packages/R6/vignettes/Introduction.html
[4]: https://stackoverflow.com/questions/34254716/how-to-define-hidden-global-variables-inside-r-packages
[5]: https://stackoverflow.com/questions/12598242/global-variables-in-packages-in-r
[6]: https://stackoverflow.com/questions/1236620/global-variables-in-r
[7]: https://stackoverflow.com/questions/28246952/global-variable-in-a-package-which-approach-is-more-recommended
There should be a word for looking for complex answers amidst obvious solutions. It could NOT have been more obvious.
R code workflow
The first practical advantage to using a package is that it’s easy to re-load your code. You can either run devtools::load_all(), or in RStudio press Ctrl/Cmd + Shift + L, which also saves all open files, saving you a keystroke. This keyboard shortcut leads to a fluid development workflow:
- Edit an R file.
- Press Ctrl/Cmd + Shift + L.
- Explore the code in the console.
- Rinse and repeat.
Congratulations! You’ve learned your first package development workflow. Even if you learn nothing else from this book, you’ll have gained a useful workflow for editing and reloading R code
Load_all(). Wow! Just that simple. Load all ran the .onload() function and rendered the objects into global environment. Who knew?
Reference: R Code Workflow, R Packages, Hadley