data.table的tables()函数运行我的一些.Rprofile函数

Jus*_*tin 5 r data.table

在我的.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)

Jos*_*ien 8

我想你刚刚发现了以这种方式使用主动绑定的缺点.为什么不改为创建普通函数.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)