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