On 11/17/2005 9:39 AM, Duncan Murdoch wrote: > 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
Whoops, as Martin Maechler pointed out to me, this line is unnecessary. The fact that test is an argument to wrapper means that a local copy would have been made already. (I am fairly sure this line wouldn't cost very much, since R would recognize that a third copy of test isn't needed, but I shouldn't have put it there.) Duncan Murdoch > 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 ______________________________________________ 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