Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

data.table's tables() function runs some of my .Rprofile functions

Tags:

r

data.table

In my .Rprofile I have the following two lines defined in my .First

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

They're usually harmless, unless I type them by accident! The first makes a .refresh function that will quit and restart the R session. The second empties the global environment. However, when using the tables() function from data.table these two functions are run which isn't exactly desirable.

For the moment, I've removed them from my .First but I'm curious if there is a way to avoid this. The offending lines in the tables() function are:

tt = objects(envir = env, all.names = TRUE)
ss = which(as.logical(sapply(tt, function(x) is.data.table(get(x, 
    envir = env)))))
like image 212
Justin Avatar asked Jun 27 '12 16:06

Justin


1 Answers

I think you just discovered a downside to using active bindings in that way. Why don't you instead create ordinary functions .rm and .refresh, that you call in the usual way (i.e. .rm() and .refresh()), and which won't be executed upon simple inspection?

Here's what part of your .First might then look like:

.First <- function() {
    assign(".rm", 
           function() {rm(list=ls(envir=.GlobalEnv), envir=.GlobalEnv)}, 
           pos = .GlobalEnv)
}

## Try it out
j <- 1:10
ls()
.First()
.rm()
ls()

Edit, with solution:

On further thought, this seems to work, only executing the core bits when .rm is 'called' directly. It works by inspecting the length of the call stack, and only running rm(...) if there is just one call in it (representing the current call to .rm(). If .rm is called/touched by a call to some other function (e.g. tables()), the call stack will be longer, and rm() won't be executed.:

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()
like image 169
Josh O'Brien Avatar answered Nov 01 '22 00:11

Josh O'Brien