From osklyar at maninvestments.com  Wed Apr  2 16:38:27 2008
From: osklyar at maninvestments.com (Sklyar, Oleg (MI London))
Date: Wed, 2 Apr 2008 15:38:27 +0100
Subject: [Rd] "[<-" plus drop-type extra argument
In-Reply-To: <6E7FF74C-4FBE-4AEA-B8D7-8C4F27CD47C0@noc.soton.ac.uk>
References: <6E7FF74C-4FBE-4AEA-B8D7-8C4F27CD47C0@noc.soton.ac.uk>
Message-ID: <1A68FCB28DE72F4BA3B967E6506CCE4302294808@mildnpexmb01.maninvestments.ad.man.com>

Robin:

two points:

first for convenience and performance it has sense to derive your class from numeric rather than introduce a numeric slot, i.e.

setClass("foo",
  representation(
    "numeric",
    NC="numeric"
  ),
  prototype(
    NC=NA_real_
  )
)

or

setClass("foo",
  representation(
    NC="numeric"
  ),
  prototype(
    NC=NA_real_
  ),
  contains="numeric"
)

In this way your data is in the .Data slot by default and all the functions defined for numeric work out of the box (you just need to redefine those that have to return foo rather than numeric).

Second, your setReplaceMethod seems to be wrong in the definition, try the following adding signature for value and ... in the function call. You cannot simply drop the ... . Probably you will also need to include j="missing" in the signature. There is also no need to construct a new object on return and I do not think drop is a part of generic for replacement, it is for extraction though

setReplaceMethod("[", signature(x="foo", value="ANY"),
  function(x, i,j, ..., recalculate=FALSE, value) {
    x at .Data[i] = value
    if (recalculate) x at NC = sum(x at .Data)
    x
  })

Here is the output:
> a = new("foo", 1:15)
> a
An object of class ???foo???
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
Slot "NC":
[1] NA

> a[5,recalculate=TRUE] = 25
> a
An object of class ???foo???
 [1]  1  2  3  4 25  6  7  8  9 10 11 12 13 14 15
Slot "NC":
[1] 140


Dr Oleg Sklyar
Technology Group
Man Investments Ltd
+44 (0)20 7144 3803
osklyar at maninvestments.com 

> -----Original Message-----
> From: r-devel-bounces at r-project.org 
> [mailto:r-devel-bounces at r-project.org] On Behalf Of Robin Hankin
> Sent: 02 April 2008 09:51
> To: R-devel at r-project.org
> Subject: [Rd] "[<-" plus drop-type extra argument
> 
> Hello
> 
> I am writing a replacement method for an S4 class and want to 
> pass an additional argument to  "[<-"() along the lines of  
> "["()'s  "drop"  
> argument.
> 
> Specifically, I have an S4  class, call it "foo", with a slot  'x'  
> that is a
> vector and a slot  'NC' that  is a scalar.
> 
> I want to be able to pass a Boolean argument to the 
> replacement method which specifies whether or not to 
> recalculate  NC (which is time-consuming and often not 
> needed).  I want the default behaviour to be "don't recalculate NC".
> 
> Toy example follows, in which 'NC' is the sum of x (in my 
> application, calculating NC is an expensive multidimensional 
> integral).
> 
> 
> setClass("foo",
>           representation = representation(x="numeric" , NC="numeric"),
>           prototype      = list(x=double() , NC=NA_real_)
>           )
> 
> setReplaceMethod("[",signature(x="foo"),
>                   function(x,i,j,recalculate=FALSE,value){
>                     jj <- x at x
>                     jj[i] <- value
>                     if(recalculate){
>                       return(new("foo" , x=jj , NC=sum(jj)))
>                     } else {
>                       return(new("foo" , x=jj , NC=NA_real_))
>                     }
>                   }
>                   )
> 
> 
> 
> 
> Then
> 
> 
> 
>  >
>  > a <- new("foo", x=1:10,NC=45)
> 
> 
>  > a[4,recalculate=FALSE] <- 10000
>  > a
> An object of class ?foo?
> Slot "x":
>   [1]     1     2     3 10000     5     6     7     8     9    10
> 
> Slot "NC":
> [1] NA
> 
> #  Desired behaviour: NC not recalculated
> 
> 
>  >
>  > a[4,recalculate=TRUE] <- 10000
>  > a
> An object of class ?foo?
> Slot "x":
>   [1]     1     2     3 10000     5     6     7     8     9    10
> 
> Slot "NC":
> [1] 10051
> 
> 
> # Desired behaviour: NC recalculated
> 
>  >
>  > a[4] <- 10000
> Error in .local(x, i, j, ..., value) :
>    argument "value" is missing, with no default  >
> 
> # Undesired behaviour:  I wanted 'recalculate' to take its 
> default value of FALSE, and 'NC' not be recalculated.
> 
> 
> How to do this?
> 
> 
> 
> 
> 
> --
> Robin Hankin
> Uncertainty Analyst and Neutral Theorist, National 
> Oceanography Centre, Southampton European Way, Southampton 
> SO14 3ZH, UK
>   tel  023-8059-7743
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 


**********************************************************************
The contents of this email are for the named addressee(s) only.
It contains information which may be confidential and privileged.
If you are not the intended recipient, please notify the sender
immediately, destroy this email and any attachments and do not
otherwise disclose or use them. Email transmission is not a
secure method of communication and Man Investments cannot accept
responsibility for the completeness or accuracy of this email or
any attachments. Whilst Man Investments makes every effort to keep
its network free from viruses, it does not accept responsibility
for any computer virus which might be transferred by way of this
email or any attachments. This email does not constitute a request,
offer, recommendation or solicitation of any kind to buy, subscribe,
sell or redeem any investment instruments or to perform other such
transactions of any kind. Man Investments reserves the right to
monitor, record and retain all electronic communications through
its network to ensure the integrity of its systems, for record
keeping and regulatory purposes. 

Visit us at: www.maninvestments.com

**********************************************************************



[Rd] "[<-" plus drop-type extra argument
Sklyar, Oleg (MI London