[R] Communicating from one function to another

Greg Snow Greg.Snow at intermountainmail.org
Mon Nov 26 23:53:31 CET 2007


Global variables are strongly discouraged in R, but there are sometimes
when they may be needed and so are possible.

One example where they are used is in random number generation, every
time a random number function is called (rnorm for example) the "global"
variable .Random.seed is updated so that new random values will be
generated next time.

If you absolutely need a global variable, then use assign (or possibly
<<-) to do the assignment.  Also choose a name such that your global
variable is unlikely to overwright or be overwritten (if you use x, then
both are likely to happen, preferable to use a name starting with '.').

A better approach is to use variables in a local environment such that
the 2 functions can both see the variable, but nothing outside of that
environment can.  Here is a simple example:

> tmp <- local({
+ x23 <- numeric(1)
+ func1 <- function(){
+ x23 <<- 2.6
+ }
+ func2 <- function(){
+ print(x23)
+ }
+ list(func1=func1,func2=func2)
+ })
> 
> func1 <- tmp$func1
> func2 <- tmp$func2
> 
> func2()
[1] 0
> func1()
> func2()
[1] 2.6
> tmp$func2()
[1] 2.6
> 

The local function creates a new environment in which everything in the
{} is evaluated/created.  This new environment then gets a variable
(x23) which starts off to be 0.  The 2 functions defined in the same
environment can access x23.  The list statement just combines the 2
functions into a single object to be returned.  

So after running local, the variable tmp is a list with 2 elements each
being a function, we can run them as
tmp$func2() or copy them to easier to use functions.  We run func2 and
see that x23 is currently 0, then run func1 to change the value (don't
see anything yet) then run func2 again to see the new value of x23.

This is a cleaner solution in that if we already have a variable called
x23, it does not get overwritten by the "global" and it is very
difficult to accidentally overwrite the x23 shared by the 2 functions.

Hope this helps,

-- 
Gregory (Greg) L. Snow Ph.D.
Statistical Data Center
Intermountain Healthcare
greg.snow at intermountainmail.org
(801) 408-8111
 
 

> -----Original Message-----
> From: r-help-bounces at r-project.org 
> [mailto:r-help-bounces at r-project.org] On Behalf Of Thomas L Jones, PhD
> Sent: Monday, November 26, 2007 10:11 AM
> To: R-project help
> Subject: [R] Communicating from one function to another
> 
> My question is a seemingly simple one. I have a bunch of 
> user-defined functions which compute such-and-such objects. I 
> want to be able to define a variable in a particular 
> function, then make use of it later, perhaps in a different 
> function, without necessarily having to move it around in 
> argument lists. In the C community, it would be called a 
> "global" variable.
> 
> Question 1: Is this practical at all in the R language?
> 
> Suppose the variable is called x23. I want to assign a value 
> to it, then use it later. Seemingly, there are two cases:
> 
> Case I is if the variable is given its value at the top level.
> 
> Case II is if it is given its value inside a user-defined 
> function. That I do not know how to do.
> 
> Example:
> 
> func1 <- function (){
> 
> x23 <- 2.6
> 
> return ()
> 
> }
> 
> driver_func <- function (){
> 
> func1 ()
> 
> print (x23)
> 
> return ()
> 
> }
> 
> However, when I call driver_func, it won't work. Beginning 
> with the load operation, I get:
> 
> ----------------------------------------------------------------
> 
> Type 'demo()' for some demos, 'help()' for on-line help, or 
> 'help.start()' for an HTML browser interface to help.
> Type 'q()' to quit R.
> 
> > func1 <- function (){
> +
> + x23 <- 2.6
> +
> + return ()
> +
> + }
> >
> > driver_func <- function (){
> +
> + func1 ()
> +
> + print (x23)
> +
> + return ()
> +
> + }
> > driver_func ()
> Error in print(x23) : object "x23" not found
> >
> 
> --------------------------------------------------------------
> -------------
> >From Tom:
> 
> Clearly, the two functions cannot communicate. I am aware of 
> the existence of environments, but don't know much about 
> them. Also, the attach function and the get and set 
> functions. Also, .GlobalEnv It might or might not make sense 
> to create a list of "all" of the variables, with two 
> functions which get all of them and set all of them. The 
> function calls may be thought of as an upside down tree. I 
> want to be able to communicate from any node to any other node.
> 
> Your advice?
> 
> Tom
> Thomas L. Jones, PhD, Computer Science
> 
> ______________________________________________
> 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