[R] Suggestion on how to make permanent changes to a single object in a list?

Gabor Grothendieck ggrothendieck at gmail.com
Fri Jan 4 01:02:31 CET 2008


There is an online appendix to John Fox's book here:
http://cran.r-project.org/doc/contrib/Fox-Companion/appendix-scope.pdf

and there is a background paper in the additional information section
of the proto home page.

Here is a stack implementation using proto.   We define
a proto object, stack, with pop and push methods and the stack
data itself.

library(proto)
stack <- proto(
  pop = function(.) {
    len <- length(.$stack)
    if (len) {
       top <- .$stack[[len]]
       .$stack <- .$stack[-len]
       top
    }
  },
  push = function(., x) {
   .$stack <- append(.$stack, x)
   invisible(x)
  },
  stack = list()
)

stack$push(3)
stack$push(sin)
stack$stack # displays stack
stack$pop() # sin
stack$pop() # 3
stack$pop() # NULL

Here is an example that just uses function closures:

stack <- function() {
  stack <- list()
  list(pop = function() {
    len <- length(stack)
    if (len) {
       top <- stack[[len]]
       stack <<- stack[-len]
       top
    }
  },
  push = function(x) {
   stack <<- append(stack, x)
   invisible(x)
  })
}

mystack <- stack()
mystack$push(3)
mystack$push(sin)
mystack$pop() # sin
mystack$pop() # 3

The R.oo is another oo layer on top of environments you could look at too.


On Jan 3, 2008 5:58 PM, Peter Waltman <waltman at cs.nyu.edu> wrote:
> Hi Gabor -
>
> Thanks for the 2 suggestions (and to Charilaos Skiadas as well, who also
> suggested looking at proto).
>
> I think I'm leaning towards using the new environment idea you
> suggested, however, I don't quite get what a promise is (beyond what the
> help page says and I didn't really follow it).
>
> Is there a single document describing the relationship between
> environments, assignments, bindings, etc?  Unfortunately, I haven't been
> able to find anything which gives a good overview of what these are and
> how they interact.
>
> Clearly, it's beyond the introduction to R document that you can find on
> the website, and any books I've looked at focus on how to use R to
> generate statistical results, rather than on the actual language
> aspects.  Finally, while the help pages may explain the individual
> functions, I find these difficult to use without understanding the
> general framework in which they work.
>
> Thanks,
>
> Peter
>
>
> Gabor Grothendieck wrote:
> > You can do it with environments.  The first line sets up fooStack with
> > a list of environments instead of a list of lists and the remaining lines
> > are the same as in your post squished to one line each to make it
> > easier to see the entire code at once:
> >
> > fooStack <- lapply(1:5, new.env)
> > fooModifier <- function( foo ) foo$bar <- "bar"
> > fooModifier( fooStack[[ 1 ]] )
> > fooStack[[1]]$bar # "bar"
> >
> > You may need to be a bit careful if you pursue this line of reasoning as there
> > is a long standing bug in R relating to lists of promises so take care that you
> > don't get promises in the list.  See point #2 in:
> > https://stat.ethz.ch/pipermail/r-devel/2008-January/047914.html
> >
> > Also you might want to look at the proto package which reframes the
> > use of environments in terms of object oriented programming.
> > http://r-proto.googlecode.com
> >
> >
> > On Jan 3, 2008 4:35 PM, Peter Waltman <waltman at cs.nyu.edu> wrote:
> >
> >>   specifically, imagine we have:
> >>
> >>     fooStack <- list()
> >>     for ( i in 1:5 )
> >>         fooStack[[i]] <- list()
> >>
> >>   and we have a function:
> >>
> >>     fooModifier <- function( foo ) {
> >>
> >>     foo$bar <- "bar"
> >>
> >>     }
> >>
> >>   then, if we invoke fooModifier, i.e.:
> >>
> >>     fooModifier( fooStack[[ 1 ]] )
> >>
> >>   the $bar elt is only set in the scope of the function, and if we use the
> >>   "<<-" modifier in fooModifier, R will throw an error b/c it can't find the
> >>   "foo" object.  I have to say that for someone coming from languages that
> >>   have pointers and/or references, it's really frustrating that R fails to
> >>   allow one to have direct access to the objects' memory space.
> >>   Onyway, one workaround would be to pass in the whole fooStack object and the
> >>   index of the elt that you want to modify to the fooModifier fn, but I'd
> >>   rather not have to pass the whole thing in.
> >>   Any suggestions?
> >>   Thanks!
> >>   Peter Waltman
> >> ______________________________________________
> >> R-help at r-project.org mailing list
> >> https://stat.ethz.ch/mailman/listinfo/r-help
> >> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> >> and provide commented, minimal, self-contained, reproducible code.
> >>
> >>
>




More information about the R-help mailing list