2012-06-27 5 views
5

En mi .Rprofile tengo las dos líneas siguientes se definen en mi .Firsttablas de data.table() se ejecuta algunos de mis funciones .Rprofile

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

Por lo general son inofensivas, a menos que los escribe por accidente ! El primero hace una función .refresh que saldrá y reiniciará la sesión R. El segundo vacía el ambiente global. Sin embargo, al usar la función tables() desde data.table, se ejecutan estas dos funciones, lo que no es exactamente deseable.

Por el momento, los he quitado de mi .First pero tengo curiosidad si hay una manera de evitar esto. Las líneas ofensivas en la función tables() son:

tt = objects(envir = env, all.names = TRUE) 
ss = which(as.logical(sapply(tt, function(x) is.data.table(get(x, 
    envir = env))))) 

Respuesta

8

Creo que acaba de descubrir una desventaja de usar los enlaces de activos de esa manera. ¿Por qué no crea en su lugar las funciones ordinarias .rm y .refresh, que llama de la forma habitual (es decir, .rm() y .refresh()) y que no se ejecutarán tras una simple inspección?

Esto es lo que parte de su .First entonces podría ser:

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

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

Editar, la solución:

En pensarlo más, esto parece funcionar, solamente la ejecución de las brocas cuando .rm es 'llamado' directamente. Funciona inspeccionando la longitud de la pila de llamadas y solo ejecuta rm(...) si solo hay una llamada (que representa la llamada actual al .rm(). Si .rm es llamado/tocado por una llamada a otra función (por ej. tables()) , la pila de llamadas será más largo, y rm() no se ejecutará .:

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() 
+0

así es como yo las escribí al principio, pero mis dedos conseguido tan cansados ​​de escribir '()' que decidí jugar con fuego ... – Justin

+0

Aunque si intentas mantener ese fuego en marcha, con el tiempo acabará costándote más que unas pocas teclas;) –

+0

¿No hay alguna forma de verificar el entorno actual? t, o un parámetro que dice "este es un entorno interactivo ...", y haga que sus funciones utilicen esa información para decidir si se ejecutan o no. –

Cuestiones relacionadas