使用 .onLoad() 将 object 加载到 R 包中的全局环境中
Loading object into global environment in R Package using .onLoad()
我正在开发一个 R 包,我需要在其中随时间管理各种 object 的状态。从概念上讲,当包加载 (.onLoad) 时,它会检查缓存中的状态 object,如果不存在,则会创建一个新实例,保存到缓存中,并在全局环境中分配。使用 devtools :: build() 构建站点后,我无法使用 .onLoad() 在全局环境中看到 object。所以,我有三个问题:
- .onLoad() 函数是否适合此功能?如果是这样,当前使状态变量在全局环境中可见的最佳实践是什么?
- 是否开发了跨“R 会话”管理状态的解决方案(包)?
- 是否有比我采用的方法更好的概念方法来解决这个问题?
尝试过的解决方案...到目前为止
我搜索了 SE,阅读(和 re-read)Hadley 关于 R 包和高级 R 的书籍,仔细研究了 Winston Chang 在 R6 上的小插曲(post 底部的链接)和我将我的实验提炼为三种失败的方法。首先,这是一个简单的“GameClass”,它用三个变量实例化了一个游戏,玩家 1、玩家 2 和(游戏的)状态。
#' 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)
}
}
方法二:
创建一个新环境并return它
.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)
}
Session 信息
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
我是 OOP 的新手,R6 的新手,这是我的第一个 R 包,我已经使用 R 大约一年了。显然,我可以从这里的一些见解中受益。
提前致谢。
## 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]:
[5]:
[6]:
[7]:
应该有一个词是在显而易见的解决方案中寻找复杂的答案。它再明显不过了。
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()。哇!就这么简单。加载所有 运行 .onload() 函数并将对象渲染到全局环境中。谁知道?
我正在开发一个 R 包,我需要在其中随时间管理各种 object 的状态。从概念上讲,当包加载 (.onLoad) 时,它会检查缓存中的状态 object,如果不存在,则会创建一个新实例,保存到缓存中,并在全局环境中分配。使用 devtools :: build() 构建站点后,我无法使用 .onLoad() 在全局环境中看到 object。所以,我有三个问题:
- .onLoad() 函数是否适合此功能?如果是这样,当前使状态变量在全局环境中可见的最佳实践是什么?
- 是否开发了跨“R 会话”管理状态的解决方案(包)?
- 是否有比我采用的方法更好的概念方法来解决这个问题?
尝试过的解决方案...到目前为止
我搜索了 SE,阅读(和 re-read)Hadley 关于 R 包和高级 R 的书籍,仔细研究了 Winston Chang 在 R6 上的小插曲(post 底部的链接)和我将我的实验提炼为三种失败的方法。首先,这是一个简单的“GameClass”,它用三个变量实例化了一个游戏,玩家 1、玩家 2 和(游戏的)状态。
#' 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)
}
}
方法二:
创建一个新环境并return它
.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)
}
Session 信息
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
我是 OOP 的新手,R6 的新手,这是我的第一个 R 包,我已经使用 R 大约一年了。显然,我可以从这里的一些见解中受益。
提前致谢。
## 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]:
[5]:
[6]:
[7]:
应该有一个词是在显而易见的解决方案中寻找复杂的答案。它再明显不过了。
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()。哇!就这么简单。加载所有 运行 .onload() 函数并将对象渲染到全局环境中。谁知道?