[R] Modify objects in function

2013-01-31 Thread Simon Zehnder
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@att1 - producesomething()
o2@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@att1 - producesomething()
o2@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.

2. Change the objects of the global environment inside the function:

foo - function(o1, o2) {
o1@att1 - producesomething()
o2@att2 - producesomethingelse()

assign(o1, o1, .GlobalEnv)
assign(o2, o2, .GlobalEnv)
}

This is for users very practical, as the symbols used before refer now to 
objects with changed attributes and can be used immediately. BUT: It is not 
intended to be done like this.

I spared any solution using one function for every single object type, as this 
becomes even more cumbersome than choice 1 above, in my opinion.

What is your opinion on the trade-off between user-friendly handling of objects 
and R-intended programming style? Do I miss another choice, combining both?


Best 
Simon
__
R-help@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.


Re: [R] Modify objects in function

2013-01-31 Thread Barry Rowlingson
On Thu, Jan 31, 2013 at 11:52 AM, Simon Zehnder szehn...@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@att1 - producesomething()
 o2@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@att1 - producesomething()
 o2@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@att=bar()
o12$o2@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

__
R-help@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.


Re: [R] Modify objects in function

2013-01-31 Thread Barry Rowlingson
  it lets you do:

  (a~b~c) = foo()

Mistook. should be:

(a~b~c) %=% foo()

 because it defines the %=% operator.

Barry

__
R-help@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.


Re: [R] Modify objects in function

2013-01-31 Thread Barry Rowlingson
On Thu, Jan 31, 2013 at 3:00 PM, Simon Zehnder szehn...@uni-bonn.de wrote:
 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.


 Hadley W asked for implementations of 'unstructuring assignments' the
other day, and I bashed this out to a gist:

https://gist.github.com/4543212

 it lets you do:

 (a~b~c) = foo()

and if foo() returns a list with three components it assigns them to
a, b, and c. Equivalent to:

tmp = foo()
a=tmp[[1]]
b=tmp[[2]]
c=tmp[[3]]

whether its any use to your use case or even works properly under all
circumstances or even just serves to obfuscate things is a point for
discussion...

Barry

__
R-help@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.


Re: [R] Modify objects in function

2013-01-31 Thread Gabor Grothendieck
On Thu, Jan 31, 2013 at 6:52 AM, Simon Zehnder szehn...@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@att1 - producesomething()
 o2@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@att1 - producesomething()
 o2@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.

 2. Change the objects of the global environment inside the function:

 foo - function(o1, o2) {
 o1@att1 - producesomething()
 o2@att2 - producesomethingelse()

 assign(o1, o1, .GlobalEnv)
 assign(o2, o2, .GlobalEnv)
 }

 This is for users very practical, as the symbols used before refer now to 
 objects with changed attributes and can be used immediately. BUT: It is not 
 intended to be done like this.

 I spared any solution using one function for every single object type, as 
 this becomes even more cumbersome than choice 1 above, in my opinion.

 What is your opinion on the trade-off between user-friendly handling of 
 objects and R-intended programming style? Do I miss another choice, combining 
 both?



Another possibility is to create an environment component in your S4
class since those can be passed around as references:

OO - setClass(OO, representation(env = environment))

setMethod(initialize, OO, function(.Object) {
.Object@env - new.env()
.Object
})

setMethod(show, OO, function(object) show(object@env$a))

o1 - OO()
o1@env$a - 1

o2 - OO()
o2@env$a - 2

o1 # 1
o2 # 2

swap - function(o1, o2) {
   tmp - o1@env$a
   o1@env$a - o2@env$a
   o2@env$a - tmp
}

swap(o1, o2)
o1 # 2
o2 # 1

or if its feasible for you to change class systems Reference Classes
already use environments:

R - setRefClass(R, fields = a,
methods = list(
   swap = function(o2) {
  tmp - o2$a
  o2$a - a
  a - tmp
   },
   show = function() methods::show(a)
)
)
r1 - R$new(a = 1)
r2 - R$new(a = 2)

r1 # 1
r2 # 2
r1$swap(r2)

r1 # 2
r2 # 1

--
Statistics  Software Consulting
GKX Group, GKX Associates Inc.
tel: 1-877-GKX-GROUP
email: ggrothendieck at gmail.com

__
R-help@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.


Re: [R] Modify objects in function

2013-01-31 Thread Simon Zehnder
Dear Barry,

thank you very much for this information. This looks pretty interesting! 

Best

Simon
On Jan 31, 2013, at 4:09 PM, Barry Rowlingson b.rowling...@lancaster.ac.uk 
wrote:

 it lets you do:
 
 (a~b~c) = foo()
 
 Mistook. should be:
 
 (a~b~c) %=% foo()
 
 because it defines the %=% operator.
 
 Barry

__
R-help@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.


Re: [R] Modify objects in function

2013-01-31 Thread Simon Zehnder
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.rowling...@lancaster.ac.uk 
wrote:

 On Thu, Jan 31, 2013 at 11:52 AM, Simon Zehnder szehn...@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@att1 - producesomething()
o2@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@att1 - producesomething()
o2@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@att=bar()
o12$o2@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

__
R-help@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.