How to find where the object is created?

I am currently working on improving code that has different calls for other scripts, and I would like to know where the object is being created. For some of them, only the text editor search function works. Just see if obj <- or obj = . But this does not apply to those created using the assign function. And those that are created in loaded scripts, too.

The debug() function, when an error occurs, indicates where it happened, even if it is in another script. But is there any function that tells a line of code that it created an object? Is there any other tool?

Perhaps this can be done with grepl , but I don’t know enough to create such a function ...

+4
r
Nov 06 '13 at 15:24
source share
1 answer

It looks like basically you want the function to identify when new objects are created using the debugger. The simplest thing you can do is simply type ls(envir=.GlobalEnv) in your browser to find out what objects you have. Alternatively, you can write a function that will show you new objects since the last search (for example, what new objects were created (for example, in the global environment). Here is a function that does this:

 comparels <- function(){ oldls <- try(get('oldls', envir=.GlobalEnv)) if(inherits(oldls, 'try-error')) oldls <- list() newls <- ls(.GlobalEnv) assign('oldls',newls, envir=.GlobalEnv) gone <- oldls[!oldls %in% newls] added <- newls[!newls %in% oldls] list(gone=gone, added=added) } 

Here is an example of what it shows you:

 > comparels() $gone list() $added [1] "comparels" > a <- 1 > b <- 2 > c <- 3 > comparels() $gone character(0) $added [1] "a" "b" "c" "oldls" 

Then, if you run this in the debugger for your function (here is a simple example below), you can call comparels() and see what new objects were created at any given point in the function:

 funtodebug <- function(){ for(i in 1:100){ assign(paste('obj',i,sep='_'), i, .GlobalEnv) } } debug(funtodebug) > funtodebug() debugging in: funtodebug() debug at #1: { for (i in 1:100) { assign(paste("obj", i, sep = "_"), i, .GlobalEnv) } } Browse[2]> debug at #2: for (i in 1:100) { assign(paste("obj", i, sep = "_"), i, .GlobalEnv) } Browse[2]> debug at #2: i Browse[2]> debug at #3: assign(paste("obj", i, sep = "_"), i, .GlobalEnv) Browse[2]> debug at #2: i Browse[2]> debug at #3: assign(paste("obj", i, sep = "_"), i, .GlobalEnv) Browse[2]> comparels() $gone character(0) $added [1] "funtodebug" "obj_1" 

EDIT: An alternative approach would be to use task callbacks to call the comparels function every time something happens at the top level, so printing is created at any time by new objects. Here's a trivial example:

 addTaskCallback(function(expr,value,ok,visible) { print(comparels()) TRUE}, name='ls') a <- 1 b <- 2 a b 3+3 # remove the callback removeTaskCallback('ls') 

This saves you from having to debug your entire program. You can simply call the callback before you run your code, and then see what happens and delete the callback.

+5
Nov 22 '13 at 9:18
source share



All Articles