Skip to content

making changes to global variables in functions

5 messages · Yev, R. Michael Weylandt, Janko Thyson +2 more

#
No pointer functionality in R (that I know of), but if you want to
return two objects as one the standard way is to put them in a list
and to return that list.

Michael
On Tue, Dec 6, 2011 at 2:35 PM, Yev <kirpich at gmail.com> wrote:
#
None of this pass by reference complexity is necessary. Here's how to
do it without references or environments.

 A <- list(n=100,won=0)
 B <- list(n=100,won=0)

 f <- function(x,y)
 {
 	nmx <- deparse(substitute(x))
 	nmy <- deparse(substitute(y))
 	x$n <-50; y$n <- 50
 	assign(nmx,x, pos=parent.frame())
 	assign(nmy,y,pos=parent.frame())
 	invisible(NULL)
 }

## Does it work:
$n
[1] 100

$won
[1] 0
$n
[1] 100

$won
[1] 0
$n
[1] 50

$won
[1] 0
$n
[1] 50

$won
[1] 0

However, one may fairly ask whether doing things this way is wise --
and the answer is probably not: better to pass a list of lists, make
the changes in the passed copy, and then explicitly assign back the
results:

g <- function(l,...) {... your code ...}
z <- list(A,B)
z <- g(z)

Cheers,
Bert


On Wed, Dec 7, 2011 at 4:33 AM, Janko Thyson
<janko.thyson.rstuff at googlemail.com> wrote:

  
    
#
A third option is to put your state objects in a list
and write a replacement function to modify the state
of each.  E.g.,

  `n<-` <- function(state, value) {
      state[["n"]] <- value
      state
  }
  n <- function(state) state[["n"]]
  states <- list( list(n=100, won=0), list(n=101, won=1) )
  for(i in seq_along(states)) {
      n(states[[i]]) <- i*1000
  }
  invisible(lapply(states, dput))
  # that should show:
  #   structure(list(n = 1000, won = 0), .Names = c("n", "won"))
  #   structure(list(n = 2000, won = 1), .Names = c("n", "won"))

This can make it easier to understand the flow of data.

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com