[R] Return variable assignments from a function

Greg Snow Greg.Snow at imail.org
Thu Jun 4 18:45:25 CEST 2009


I still think that fortune(181) applies here.  Someday you (or another user that you give your function to) will run this, then realize that you/they had an A, B, or c variable that has just been overwritten that you/they wanted to keep.  (also 'c' is one of the variable names recommended against, there is a very often used function 'c').

You are also still breaking the association between A, B, and c.  Keeping things grouped into a single object is one of the powerful concepts in R/S.

If you know that one function (funcA) is only going to be called by another function (funcB) and you want funcB to have access to things computed in funcA, then the easiest/most straight forward is to return the values from funcA to funcB and use the ret$A type syntax.  Using '<<-' to have funcA assign values in funcB is safer (and often simpler) than using 'assign', but you still need to be careful.

If you want to use the return values at the command line and just want to avoid all the typing of object$... then use the 'with' and 'within' functions (or other functions that take a list of objects as the data to operate on).

If you tell us more about what you are trying to accomplish, maybe we can show you a way to use the power of the R way of thinking to make your task easier rather than trying to work around it.

-- 
Gregory (Greg) L. Snow Ph.D.
Statistical Data Center
Intermountain Healthcare
greg.snow at imail.org
801.408.8111


> -----Original Message-----
> From: hydebyuh at gmail.com [mailto:hydebyuh at gmail.com] On Behalf Of Scott
> Hyde
> Sent: Wednesday, June 03, 2009 9:30 PM
> To: r-help at r-project.org
> Subject: Re: Return variable assignments from a function
> 
> As a followup to my question yesterday, what if I were to return the
> argument as a list, and then "unwrap" the list with the function I've
> written called "objects".  Is there any problems with doing it?  It
> works to use it inside other functions.  For example:
> 
> =================================
> 
> > objects <- function(alist) {
>   for (vars in names(alist))
>     assign(vars,alist[[vars]],pos=sys.frame(-1))
> }
> 
> > simple <- function(m,n) {
>   A=matrix(c(3,3,2,3),2,2)
>   B=m
>   c=1:n
>   list(A=A,B=B,c=c)
> }
> > rm(A,B,c)  #just in case they exist
> > stuff=simple(2,3)
> > objects(stuff)
> > A
>      [,1] [,2]
> [1,]    3    2
> [2,]    3    3
> > B
> [1] 2
> > c
> [1] 1 2 3
> >
> 
> =================================
> 
> -Scott
> 
> 
> *****************************************************************
> Scott K. Hyde
> Assistant Professor of Statistics and Mathematics
> College of Math and Sciences
> Brigham Young University -- Hawaii
> Laie, HI  96762
> 
> 
> 
> On Tue, Jun 2, 2009 at 5:30 PM, Scott Hyde <hydes at byuh.edu> wrote:
> >
> > I'd like to perform return variable assignments like matlab.  For
> example, the following function would return A, B, and c to the script
> that called it.
> >
> > =================================
> > function  [A,B,c] = simple(m,n)
> > A=[ 3 2; 3 3]
> > B=m
> > c=1:n
> > =================================
> >
> > I'd like to do similar assignments in R, but I seem to be able to
> only return one variable.  I tried to use a list to return all the
> arguments, but then each has to be referred to using the list.  For
> example:
> >
> > =================================
> > simple <- function(m,n) {
> >   A=matrix(c(3,3,2,3),2,2)
> >   B=m
> >   c=1:n
> >   list(A=A,B=B,c=c)
> > }
> >
> > > stuff=simple(2,3)
> > > stuff
> > $A
> >      [,1] [,2]
> > [1,]    3    2
> > [2,]    3    3
> >
> > $B
> > [1] 2
> >
> > $c
> > [1] 1 2 3
> > =================================
> >
> > Then I could assign each variable like this (which is what I'd like
> to avoid):
> >
> > =================================
> > A=stuff$A
> > B=stuff$B
> > c=stuff$c
> > rm(stuff)   #stuff isn't needed anymore.
> > =================================
> >
> >
> > I've even toyed with the superassignment operator, which also works,
> but I think it doesn't work for functions of functions.  The following
> example works.
> >
> > =================================
> > simple2 <- function(m,n) {
> >   A <<- matrix(c(3,3,2,3),2,2)
> >   B <<- m
> >   c <<- 1:n
> > }
> >
> > > stuff2=simple2(2,3)
> > > stuff2
> > [1] 1 2 3
> > > A
> >      [,1] [,2]
> > [1,]    3    2
> > [2,]    3    3
> > > B
> > [1] 2
> > > c
> > [1] 1 2 3
> > =================================
> >
> > In the example below, I call the function ten inside the function
> nine.  I'm expecting that the variable b should change only in the
> function nine (and not in the global environment).  In other words, I
> think the line "(nine) b= 9" should be "(nine) b= 10".
> >
> > Can someone help me know how to do this correctly?
> >
> > -Scott
> >
> > =================================
> > nine = function(a) {
> >   b <- 9
> >   ten(a)
> >   print(paste("(nine) b=",b))
> > }
> >
> > ten = function(d) {
> >   b <<- 10
> >   print(paste("(ten) b=",b))
> >   print(paste("(ten) d=",d))
> >   d
> > }
> >
> > > nine(5)
> > [1] "(ten) b= 10"
> > [1] "(ten) d= 5"
> > [1] "(nine) b= 9"
> > > b
> > [1] 10
> > =================================
> >


More information about the R-help mailing list