[R] Modify objects in function

Simon Zehnder szehnder at uni-bonn.de
Thu Jan 31 16:00:24 CET 2013


Hi Barry,

this actually a good idea, to put them together! Probably even creating an object containing both of them. Haven't thought about it before. 

Best
Simon
On Jan 31, 2013, at 3:49 PM, Barry Rowlingson <b.rowlingson at lancaster.ac.uk> wrote:

> On Thu, Jan 31, 2013 at 11:52 AM, Simon Zehnder <szehnder at uni-bonn.de> wrote:
>> Dear R community,
>> 
>> I do know, that an R function is constructing a copy of any object passed as argument into a function. I program on a larger S4 project for a package, and I arrived at a point where I have to think a little harder on implementation style (especially to spare users complex object handling).
>> 
>> I have a function foo(), taking as input arguments two S4 objects of different class type
>> 
>> foo <- function(o1, o2) {
>>        o1 at att1 <- producesomething()
>>        o2 at att2 <- producesomethingelse()
>> 
>> }
>> 
>> Of course, this functions does not change the objects in the global environment. Now I have two choices
>> 
>> 1. Change the objects and return a list with both objects:
>> 
>>        foo <- function(o1, o2) {
>>                o1 at att1 <- producesomething()
>>                o2 at att2 <- producesomethingelse()
>> 
>>                l <- list(O1 = o1, O2 = o2)
>>                return(l)
>>        }
>> 
>> This is cumbersome for users, as they have then to assign the objects inside the returned list to the symbols used in the global environment. But it is the way intended by R.
> 
> By cumbersome you mean the following (anti-?) pattern has to be used,
> for example in a loop:
> 
> o1 = something()
> o2 = somethingelse()
> o12 = foo(o1,o2)
> o1 = o12$o1
> o2 = o12$o2
> 
> so that at the end of it you have a modified o1 and o2?
> 
> I suggest that if you have a function that modifies more than one of
> its arguments, then there is a strong case for making those arguments
> a single argument. So that you'd do:
> 
> foo = function(o12){
>    o12$o1 at att=bar()
>    o12$o2 at att=baz()
>    return(o12)
>  }
> 
> o12 = list(something(), somethingelse())
> o12 = foo(o12)
> 
> and there you are, a modified o12 object. no packing/unpacking needed.
> 
> I suspect that either your o1 and o2 are so closely related that you
> should pack them in a list (or ideally, an object) or differently
> related such that you should treat them separately and not tweak both
> of them within the same function. That approach is binding behaviour
> very tightly to two structures, and probably won't give you very
> debuggable modular code.
> 
> 
> B



More information about the R-help mailing list