[R] making changes to global variables in functions
Bert Gunter
gunter.berton at gene.com
Wed Dec 7 16:18:30 CET 2011
None of this pass by reference complexity is necessary. Here's how to
do it without references or environments.
A <- list(n=100,won=0)
B <- list(n=100,won=0)
f <- function(x,y)
{
nmx <- deparse(substitute(x))
nmy <- deparse(substitute(y))
x$n <-50; y$n <- 50
assign(nmx,x, pos=parent.frame())
assign(nmy,y,pos=parent.frame())
invisible(NULL)
}
## Does it work:
> A <- list(n=100,won=0)
> B <- list(n=100,won=0)
>
> A
$n
[1] 100
$won
[1] 0
> B
$n
[1] 100
$won
[1] 0
> f(A,B)
> A
$n
[1] 50
$won
[1] 0
> B
$n
[1] 50
$won
[1] 0
However, one may fairly ask whether doing things this way is wise --
and the answer is probably not: better to pass a list of lists, make
the changes in the passed copy, and then explicitly assign back the
results:
g <- function(l,...) {... your code ...}
z <- list(A,B)
z <- g(z)
Cheers,
Bert
On Wed, Dec 7, 2011 at 4:33 AM, Janko Thyson
<janko.thyson.rstuff at googlemail.com> wrote:
> Basically, I see two options here:
>
> 1) Using environments
>
> # Temp environment
> env <- new.env(parent=emptyenv())
> env$state1 <- list(n=100, won=0)
> env$state2 <- list(n=100, won=0)
>
> fight2 <- function(stateA, stateB, envir){
> # get(stateA, envir=envir)$n <- 50
> # The above is what you would want to do, but
> # 'get<-' is not defined, so:
> temp <- get(stateA, envir=envir)
> temp$n <- 50
> assign(stateA, value=temp, envir=envir)
>
> # Same for stateB
> temp <- get(stateB, envir=envir)
> temp$n <- 50
> assign(stateA, value=temp, envir=envir)
>
> return(TRUE)
> }
>
> fight2(stateA="state1", stateB="state2", envir=env)
>
> # Extract from environment
> state1 <- env$state1
> state1
> state2 <- env$state2
> state2
>
> 2) Using Reference Classes
>
> # Class Def
> setRefClass("State",
> fields=list(n="numeric", won="numeric"),
> methods=list(
> fight2=function(...){
> fight2Ref(.self=.self, ...)
> }
> )
> )
> # Set Generic
> setGeneric(name="fight2Ref", signature=".self", def=function(.self, ...)
> standardGeneric("fight2Ref"))
> # Set Method
> setMethod(f="fight2Ref", signature="State",
> definition=function(
> .self,
> value,
> ...
> ){
> .self$n <- value
> }
> )
> # Note:
> # You could also put the code inside 'fight2Ref' directly inside the
> class def,
> # but I don't want them to be too crowded, so I go by 'divide and conquer'
>
> # Instantiate objects
> state1 <- new("State", n=100, won=0)
> state1
> state2 <- new("State", n=100, won=0)
> state2
>
> # Apply method
> state1$fight2(value=50)
> state1
> state2$fight2(value=50)
> state2
>
> # Back to list
> stateToList <- function(obj, ...){
> fields <- names(getRefClass("State")$fields())
> out <- lapply(fields, function(x.field){
> obj$field(x.field)
> })
> names(out) <- fields
> return(out)
> }
> state1 <- stateToList(state1)
> state1
> state2 <- stateToList(state2)
> state2
>
> HTH,
> Janko
>
> On 06.12.2011 22:06, R. Michael Weylandt wrote:
>> No pointer functionality in R (that I know of), but if you want to
>> return two objects as one the standard way is to put them in a list
>> and to return that list.
>>
>> Michael
>>
>> On Tue, Dec 6, 2011 at 2:35 PM, Yev<kirpich at gmail.com> wrote:
>>> I'm trying to write a function that takes several objects with many
>>> different attributes and then changes their attributes. So what I wanted to
>>> happen in the simplified example below is for the function to change the
>>> attributes of the objects state1 and state2 that are passed to it. But
>>> because stateA and stateB are local, this isn't working. Are there any easy
>>> solutions?
>>>
>>> e.g., if I could combine the two objects stateA and stateB into a single
>>> object, I could return it and then assign it back to objects state1 and
>>> state2. Or if I could pass a pointer to the original object.. But I cannot
>>> find an easy way of doing either. Thanks in advance..
>>>
>>> state1<- list(n=100, won=0)
>>> state2<- list(n=100, won=0)
>>>
>>> fight2<- function(stateA, stateB){
>>> stateA$n<- 50
>>> stateB$n<-50
>>> }
>>>
>>> fight2(state1,state2)
>>>
>>> state1$n
>>> state2$n
>>>
>>> [[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 guidehttp://www.R-project.org/posting-guide.html
>>> and provide commented, minimal, self-contained, reproducible code.
>> ______________________________________________
>> R-help at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guidehttp://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>>
>
>
> --
> ------------------------------------------------------------------------
>
> *Janko Thyson*
> janko.thyson at ku-eichstaett.de <mailto:janko.thyson at ku-eichstaett.de>
>
> Catholic University of Eichstätt-Ingolstadt
> Ingolstadt School of Management
> Statistics and Quantitative Methods
> Auf der Schanz 49
> D-85049 Ingolstadt
>
> www.wfi.edu/lsqm <http://www.wfi.edu/lsqm>
>
> Fon: +49 841 937-1923
> Fax: +49 841 937-1965
>
> This e-mail and any attachment is for authorized use by the intended
> recipient(s) only. It may contain proprietary material, confidential
> information and/or be subject to legal privilege. It should not be
> copied, disclosed to, retained or used by any other party.
> If you are not an intended recipient then please promptly delete this
> e-mail and any attachment and all copies and inform the sender.
>
>
> [[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.
>
--
Bert Gunter
Genentech Nonclinical Biostatistics
Internal Contact Info:
Phone: 467-7374
Website:
http://pharmadevelopment.roche.com/index/pdb/pdb-functional-groups/pdb-biostatistics/pdb-ncb-home.htm
More information about the R-help
mailing list