5

在我的 .Rprofile 中,我定义了以下两行.First

makeActiveBinding(".refresh", function() { system("R"); q("no") }, .GlobalEnv)
makeActiveBinding('.rm', function() {rm(list=ls(envir = .GlobalEnv),envir=.GlobalEnv); gc()}, .GlobalEnv)

它们通常是无害的,除非我不小心输入它们!第一个.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)))))
4

1 回答 1

8

我认为您刚刚发现了以这种方式使用活动绑定的不利之处。你为什么不创建普通函数.rmand .refresh,你以通常的方式(即.rm()and .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()

编辑,解决方案:

进一步考虑,这似乎有效,只有在.rm直接“调用”时才执行核心位。它通过检查调用堆栈的长度来工作,并且仅在rm(...)其中只有一个调用时运行(表示当前.rm().更长,并且不会被执行。:.rmtables()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()
于 2012-06-27T17:06:24.943 回答