2012-06-27 4 views
5

Nel mio .Rprofile Ho le seguenti due linee definite nel mio .Firsttavoli di data.table() la funzione viene eseguito alcune delle mie funzioni .Rprofile

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

Sono di solito innocui, a meno che non li si digita per sbaglio ! Il primo esegue una funzione .refresh che chiude e riavvia la sessione R. Il secondo svuota l'ambiente globale. Tuttavia, quando si utilizza la funzione tables() da data.table, vengono eseguite queste due funzioni che non sono esattamente desiderabili.

Per il momento, li ho rimossi dal mio .First ma sono curioso di sapere se c'è un modo per evitarlo. Le linee offensive nella funzione tables() sono:

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

risposta

8

Penso che hai appena scoperto un aspetto negativo di utilizzare attacchi attivi in ​​quel modo. Perché non crei invece le normali funzioni .rm e .refresh, che chiami nel solito modo (ad esempio .rm() e .refresh()) e che non verrà eseguito con una semplice ispezione?

Ecco quale parte del vostro .First potrebbe quindi apparire come:

.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, con la soluzione:

Su ulteriore riflessione, questo sembra funzionare, solo eseguendo le corone quando .rm viene 'chiamato' direttamente. Funziona controllando la lunghezza dello stack di chiamate e funziona solo con rm(...) se è presente una sola chiamata (che rappresenta la chiamata corrente a .rm()) Se .rm viene chiamato/toccato da una chiamata a qualche altra funzione (ad esempio tables()) , lo stack di chiamate sarà più lungo, e non verrà eseguita 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() 
+0

Ecco come li ho scritto all'inizio, ma le mie dita ottenuto così stanco di digitare '()' che ho deciso di giocare con il fuoco ... – Justin

+0

Abbastanza giusto Se si tenta di mantenere il fuoco acceso, però, nel tempo finirà per costare più di alcune sequenze di tasti;) –

+0

Non c'è un modo per controllare l'ambiente attuale t, o un parametro che dice "questo è un ambiente interattivo ...", e fai in modo che le tue funzioni utilizzino tali informazioni per decidere se eseguire o meno? –

Problemi correlati