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 > ================================>