Skip to content

How to share variables

7 messages · Sergio Martino, Gabor Grothendieck

#
Hi,

I would like to realize in R a structure like the fortran common ie a way to
declare some variable that can only be accessed by all the functions which
need to.

Browsing the archive it seems that the simplest way is to declare the
variables and the functions in a big function which wraps all. But this is
impratical when the functions are big.

The environments seems to do the trick but I am not enough familiar with
them to make my ways out.

Is there any example or pointers to easy but complete environment usage?

Thanks in Advance

Sergio Martino
#
On 8/2/06, Sergio Martino <s.martino at tno.it> wrote:
There is a demonstration of that found by issuing the command:

demo(scoping)
Yes place your data in an environment as shown and then for
each function that is to access the environment should have
its environment set accordingly:

e <- new.env()
e$dat <- 1:3
myfun <- function(x) sum(x + dat)
environment(myfun) <- e
myfun(10)  # fun can access dat

Realize that what you are trying to do is to create a sort of object
oriented structure with the data being the objects and the functions
being the methods.  The proto package provides some functionality
to implement that and also supports delegation (similar to
inheritance):

library(proto)
package?proto # all sources of info on proto

# example - create proto object p with some data dat and a method fun
p <- proto(dat = 1:3, fun = function(., x) sum(x + .$dat))

# invoke method
p$fun(10)  # runs fun.  fun has access to dat

# create a child q of p and run fun
# q overrides dat with its own dat while inheriting fun
q <- p$proto(dat = 4:6)
q$fun(10)

Another possibility would be to look at the R.oo package which is
another object oriented infrastructure based on environments.
18 days later
#
Thanks for your fast replay and sorry for my late one (I was on holidays)

The structure I would like to emulate (the fortran common statement) is a
different from what you are describing.

The examples "scoping" and the links to OO programming show the use of local
variable which are tied to the object itself.

My need is to have a group of (big) variable shared among some function in a
way that they can be accessed freely.

More useful is the environment example you reported. The only problem is
that it seems I need to replace the whole environment of the function. What
I need to investigate is where the variables created inside the inner
function (myfun) go. If they belong to the enviroment (e) I will get a
mix-up of variables with side effect (variables with the same name) and it
will be a pain.

If I can use inside myfun the variable as e$dat (without changing the
enviroment (no environment(myfun) <- e statement)) than it will be ok.

I need to experiment a little bit.

Sergio
way to
which
is
#
On 8/21/06, Sergio Martino <s.martino at tno.it> wrote:
Each time myfun is run a new environment is created to hold
its local variables.  The parent of that environment is e in
this example by construction.  So e and the environment that
is temporarily created to hold myfun's variables are distinct.

Adding a couple statements to display what is in each might
help clarify this:
+ cat("In current env:", ls(), "\n")
+ cat("In parent env:", ls(parent.env(environment())), "\n")
+ sum(x + dat)
+ }
In current env: x
In parent env: dat
[1] 36
Yes you can.  You can either make sure that e is visible to myfun
via normal scoping rules or pass it explicitly:

e <- new.env()
e$dat <- 1:3
myfun <- function(x) sum(x + e$dat)
myfun(10)

# or passing e explicitly

myfun2 <- function(x, e) sum(x + e$dat)
myfun2(10, e)

# or using the proto package:to define e
# and the same myfun and myfun2

library(proto)
e <- proto(dat = 1:3)
myfun(10)
myfun2(10, p)

In the above examples we used environments but these are simple
enough that we could have used lists:

e <- list(dat = 1:3)
myfun(10)  # relying on scope rules
myfun2(10, e)  # passing explicitly
#
On 8/21/06, Gabor Grothendieck <ggrothendieck at gmail.com> wrote:
Typo. That was supposed to be myfun2(10, e)
1 day later
#
Hi

Thanks again. I hope not to waste to much of your time.

I delete some lines of your answer
This means that the enviroment is duplicated, ie it is present twince in
memory?
I must keep some big variables and it will be a waste of memory; moreover if
I update a value it will be lost.
Hit!!!
It solves the problem.
A small drawback is that I need to modify the name of each occurrence of the
variable.
Any overhead in passing the environment? Is it a pointer?

Sergio
#
On 8/22/06, Sergio Martino <s.martino at tno.it> wrote:
Each time myfun starts up a new environment comes into being
that contains x and each time it completes that environment is
destroyed.
If you update a local variable then its lost upon exit (of course you
could return the variable or return the environment inside the
function) but if you update it in e then its not lost.
That's why in an earlier example we set the environment of myfun
to e.
?system.time

to experiment with timings.