On 11/15/2005 12:22 PM, Michael Wolosin wrote: > All - > > I am trying to write R code to implement a recursive algorithm. I've > solved the problem in a klunky way that works, but uses more memory and > computing time than it should. > > A more elegant solution than my current one would require updating the > values of a variable that is located in what I will call the "root" > environment - that environment from which the original call to the > recursive function was issued.
That's tricky and ugly, but possible in various ways. However, the clean easy way to do this is to wrap your recursive function in a non-recursive one, and refer to variables in the non-recursive one using lexical scoping. For example, wrapper <- function(test) { test <- test # make a copy in the wrapper environment blah <- function() { # references here to test will see the one in wrapper # blah can call itself; each invocation will see the same test test[i,] <<- expr # use "super-assignment" to modify it } return(test) } This makes one copy of the matrix and works on that. If you want to make zero copies, you need to get tricky. Duncan Murdoch Certainly, I could pass the variable into > the function, update it inside, and return it. However, the variable I am > updating is a large matrix, and the recursion could end up several hundred > levels deep. Passing the matrix around would create a copy in the > environment for each call, wasting memory, time, and space. > > I've read the help on the "sys.{}" family of functions, and "eval", and > although I can't claim to have absorbed it all, it seems like it is much > easier to access the value of a variable in a parent frame than it is to > update that value with assignment. > If you make an assignment inside a function, even if it is to a section of > a variable that exists in a parent frame, the variable is only created or > updated in the current environment - never in the parent frame. > > For example: > > test <- matrix(NA,nrow=4,ncol=3) > test[1,] <- c(1,2,3) > blah <- function(i){ > test[i,] <- c(0,1,2) + i > return(test) > } > test > blah(2) > test > > So the real question is, how do I write the function like "blah" above that > updates "test" in the parent or root frame? > > blah <- function(i){ > test[i,] <- c(1,2,3) + i #modify this line somehow > return(NULL) > } > If done "correctly", we will get: > > blah(2) > > test > [,1] [,2] [,3] > [1,] 1 2 3 > [2,] 2 3 4 > [3,] NA NA NA > [4,] NA NA NA > > And given an example that works from within a single function call, does it > have to be modified to work recursively? > > blah <- function(i){ > if (i<4) {blah(i + 1)} > test[i,] <- c(0,1,2) + i #modify this line somehow > return(NULL) > } > If written "correctly", the following would be the output: > > blah(2) > > test > [,1] [,2] [,3] > [1,] 1 2 3 > [2,] 2 3 4 > [3,] 3 4 5 > [4,] 4 5 6 > > One idea would be to write out to a file. The filename could reside in the > root environment, and that is all that is needed. But this also seems > inelegant (and slow). If I can read and write to a file, I should be able > to read and write to a memory location. > > I suspect that the solution lies somewhere in the "sys" functions, but I > was having trouble seeing it. Any help would be appreciated. > > Thank you in advance, > > Mike > > ______________________________________________ > R-help@stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html ______________________________________________ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html