[R] Modify objects in function

Barry Rowlingson b.rowlingson at lancaster.ac.uk
Thu Jan 31 15:49:31 CET 2013


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