From maechler at stat.math.ethz.ch  Tue Aug 29 12:11:23 2006
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Tue, 29 Aug 2006 12:11:23 +0200
Subject: [Rd] vector S4 classes
In-Reply-To: <AC7EC9F8-ECDC-4E6A-BB8D-7C53A4A7605F@soc.soton.ac.uk>
References: <AC7EC9F8-ECDC-4E6A-BB8D-7C53A4A7605F@soc.soton.ac.uk>
Message-ID: <17652.4811.806532.129240@stat.math.ethz.ch>

>>>>> "Robin" == Robin Hankin <r.hankin at noc.soton.ac.uk>
>>>>>     on Tue, 29 Aug 2006 10:42:21 +0100 writes:

    Robin> In the Green Book, section 7.5 discusses new vector classes and uses  
    Robin> quaternions
    Robin> as an example of a vector class that needs more than one number per  
    Robin> element.

    Robin> I would like to define a new class that has a numeric vector and a  
    Robin> logical
    Robin> vector of the same length that specifies whether the measurement was  
    Robin> accurate.

    Robin> The following code does not behave as desired:

    >> setClass("thing",representation("vector",accurate="logical"))
    Robin> [1] "thing"
    >> dput(x <- new("thing",1:10,accurate=rep(T,10)))
    Robin> structure(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), accurate = c(TRUE,
    Robin> TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE), class =  
    Robin> structure("thing", package = ".GlobalEnv"))
    >> x[1:3]
    Robin> [1] 1 2 3
    >> dput(x[1:3])
    Robin> c(1, 2, 3)
    >> 

    Robin> because, although the "accurate" slot is filled as desired in "x",  
    Robin> when extracting the first
    Robin> three elements, it seems to be lost.

and you would really expect that ``R'' magically knows to it
also must subset the accurate slote ?

    Robin> What is the appropriate setClass() call to do what I want?  Or indeed  
    Robin> is making "thing"
    Robin> a vector class as sensible idea here?

I think you need to define at least a  subset and subassign
method for your class as well.

Defining it as "vector" will automatically inherit all the
method definitions for "vector" --- none of which will ``know anything''
about the accuracy slot.
Therefore, I tend to think you rather define a class with "all slots"

  setClass("Thing", representation(x = "numeric", accurate = "logical"))

and then you probably have to define many methods for that
class, notably for "[" and also "[<-" where the latter should
happen via setReplaceMethod("Thing",

Also, I'd define a validity method, where you have to decide if
'accurate' must have the same length as 'x' -- or what it should
mean if not.

Martin




[Rd] vector S4 classes
Martin Maechler