changing the value of a variable from inside a function
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 at 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 at 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