在我的.Rprofile中,我有以下两行定义 .First
makeActiveBinding(".refresh", function() { system("R"); q("no") }, .GlobalEnv)
makeActiveBinding('.rm', function() {rm(list=ls(envir = .GlobalEnv),envir=.GlobalEnv); gc()}, .GlobalEnv)
Run Code Online (Sandbox Code Playgroud)
它们通常是无害的,除非我偶然输入它们!第一个.refresh函数将退出并重新启动R会话.第二个清空全球环境.然而,在使用时,tables()从功能data.table这两个功能都运行哪些是不完全理想的.
目前,我已将它们从我身上移除,.First但我很好奇是否有办法避免这种情况.该tables()函数中的违规行是:
tt = objects(envir = env, all.names = TRUE)
ss = which(as.logical(sapply(tt, function(x) is.data.table(get(x,
envir = env)))))
Run Code Online (Sandbox Code Playgroud)
我想你刚刚发现了以这种方式使用主动绑定的缺点.为什么不改为创建普通函数.rm,而是.refresh以通常的方式调用(即.rm()和.refresh()),并且在简单检查时不会执行?
以下是您.First可能的部分内容:
.First <- function() {
assign(".rm",
function() {rm(list=ls(envir=.GlobalEnv), envir=.GlobalEnv)},
pos = .GlobalEnv)
}
## Try it out
j <- 1:10
ls()
.First()
.rm()
ls()
Run Code Online (Sandbox Code Playgroud)
使用解决方案编辑:
进一步考虑,这似乎有效,只在.rm直接"调用" 时执行核心位.它通过检查调用堆栈的长度来工作,并且仅rm(...)在其中只有一个调用时运行(表示当前调用.rm().如果.rm通过调用某些其他函数(例如tables())调用/触及,则调用堆栈将是更长,rm()不会被执行:
makeActiveBinding('.rm',
function() {
if(length(sys.calls())==1) {
rm(list=ls(envir = .GlobalEnv),envir=.GlobalEnv); gc()
}
},
.GlobalEnv)
## Try _it_ out
library(data.table)
j <- 100
.rm
ls()
j <- 100
tables()
ls()
Run Code Online (Sandbox Code Playgroud)