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)
b9" 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
================================
[[alternative HTML version deleted]]
I don't know why you want to do this. But you can try _assign_
simple <- function(m,n) {
assign("A",matrix(c(3,3,2,3),2,2),env=.GlobalEnv)
assign("B",m,env=.GlobalEnv)
assign("c",1:n,env=.GlobalEnv)
}> simple(5,4)
> A
[,1] [,2]
[1,] 3 2
[2,] 3 3> B
[1] 5
Ronggui
2009/6/3 Scott Hyde <hydes at byuh.edu>:> 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
> ================================>
> ? ? ? ?[[alternative HTML version deleted]]
>
> ______________________________________________
> 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.
>
--
HUANG Ronggui, Wincent
PhD Candidate
Dept of Public and Social Administration
City University of Hong Kong
Home page: http://asrr.r-forge.r-project.org/rghuang.html
For your last question, the function 10 needs to be defined inside of function
nine (lexical scoping), something like:
nine <- function(a) {
ten <- function(d) {
b <<- 10
print(paste("(ten) b=",b))
print(paste("(ten) d=",d))
d
}
b <- 9
ten(a)
print(paste("(nine) b=",b))
}
For the question on returning multiple variables from a function, this has been
discussed on the list before and some solutions posted, so if you really want to
do it, you can search the archives and find the solution. But, I would
recommend against going that route. The standard way to return multiple
variables from a function in R is to use a list (as you found).
Using assign or <<- you can write variables to the global workspace, but
this is generally a bad idea. Remember that R is a data analysis environment in
addition to a programming language, it is likely at some point that you will run
the function a second time (if not, then it is not worth the effort to get
fancy) and then the assign approaches will overwrite your previous results (see
fortune(181)).
The list approach has many advantages, your A, B, and c variables presumably are
somehow related to each other, in a list they are grouped and that relationship
is clear (it is also easier housekeeping to delete/save/copy/etc them as a group
rather than individually). If you save them as separate variables then you lose
that grouping and it can be difficult remembering which A goes with which B.
Before I learned to use lists, I would often have a workspace with x and y that
went together, then xx and yy, x1 and x2 with yyyy, etc. and it became very
confusing very fast, much simpler to have lists/data frames with x and y
variables. Having the separate variables at the global level seems more
convenient at first, but functions like "with" and "within"
give much of the same convenience and many tools work on lists/data frames
easily.
<dismount soapbox>
Hope this helps,
--
Gregory (Greg) L. Snow Ph.D.
Statistical Data Center
Intermountain Healthcare
greg.snow at imail.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 Scott Hyde
> Sent: Tuesday, June 02, 2009 9:30 PM
> To: r-help at r-project.org
> Subject: [R] Return variable assignments from a function
>
> 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
> ================================>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> 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.
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 > ================================>