[R] changing the value of a variable from inside a function
Duncan Murdoch
murdoch at stats.uwo.ca
Thu Nov 17 15:39:05 CET 2005
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 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
More information about the R-help
mailing list