[R] Appropriate method for sharing data across functions

William Dunlap
2012-04-06T01:17:33Z

> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at
r-project.org] On Behalf
> Of John C Nash
> Sent: Thursday, April 05, 2012 1:20 PM
> To: r-help at r-project.org
> Subject: [R] Appropriate method for sharing data across functions
>
> In trying to streamline various optimization functions, I would like to
have a scratch pad
> of working data that is shared across a number of functions. These can be
called from
> different levels within some wrapper functions for maximum likelihood and
other such
> computations. I'm sure there are other applications that could benefit
from this.
>
> Below are two approaches. One uses the <<- assignment to a structure
I call OPCON. The
> other attempts to create an environment with this name, but fails. Though I
have looked
> at
> a number of references, I have so far not found an adequate description of
how to
> specify
> where the OPCON environment is located. (Both the green and blue books do
not cover
> this
> topic, at least not under "environment" in the index.)
>
> Is there a recommended approach to this? I realize I could use argument
lists, but they
> get long and tedious with the number of items I may need to pass, though
passing the
> OPCON
> structure in and out might be the proper way.

Make OPCON an environment and pass it into the functions that may read it or
alter it.  There
is no real need to pass it out, since environments are changed in-place (unlike
lists).  E.g.,
  > x <- list2env(list(one=1, two="ii", three=3))
  > x
  <environment: 0x0000000003110890>
  > objects(x)
  [1] "one"   "three" "two"
  > x[["two"]]
  [1] "ii"
  > with(x, three+one)
  [1] 4
  > f <- function(z, env) { env[["newZ"]] <- z ; sqrt(z) }
  > f(10, x)
  [1] 3.162278
  > x[["newZ"]] # put there by f()
  [1] 10

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com

> An onAttach() approach was suggested by
> Paul
> Gilbert and tried, but it has so far not succeeded and, unfortunately, does
not seem to be
> usable from source() i.e., cannot be interpreted but must be built first.
>
> JN
>
> Example using <<-
>
> rm(list=ls())
> optstart<-function(npar){ # create structure for optimization
computations
>     # npar is number of parameters ?? test??
>     OPCON<<-list(MAXIMIZE=TRUE, PARSCALE=rep(1,npar), FNSCALE=1,
>         KFN=0, KGR=0, KHESS=0)
>     # may be other stuff
>     ls(OPCON)
> }
>
> add1<-function(){
>     OPCON$KFN<<-1+OPCON$KFN
>     test<-OPCON$KFN
> }
>
> OPCON<<-list(MAXIMIZE=TRUE, PARSCALE=rep(1,4), FNSCALE=1,
>         KFN=0, KGR=0, KHESS=0)
> ls(OPCON)
> print(add1())
> print(add1())
> print(ls.str())
>
> rm(OPCON) # Try to remove the scratchpad
> print(ls())
>
> tmp<-readline("Now try from within a function")
> setup<-optstart(4) # Need to sort out how to set this up appropriately
> cat("setup =")
> print(setup)
>
> print(add1())
> print(add1())
>
> rm(OPCON) # Try to remove the scratchpad
>
> =====================> Example (failing) using new.env:
>
> rm(list=ls())
> optstart<-function(npar){ # create structure for optimization
computations
>     # npar is number of parameters ?? test??
>     OPCON<-new.env(parent=globalenv())
>     OPCON<-list(MAXIMIZE=TRUE, PARSCALE=rep(1,npar), FNSCALE=1,
>         KFN=0, KGR=0, KHESS=0)
>     # may be other stuff
>     ls(OPCON)
> }
>
> add1<-function(){
>     OPCON$KFN<-1+OPCON$KFN
>     test<-OPCON$KFN
> }
>
> OPCON<-new.env(parent=globalenv())
> OPCON<-list(MAXIMIZE=TRUE, PARSCALE=rep(1,4), FNSCALE=1,
>         KFN=0, KGR=0, KHESS=0)