cgenolin at u-paris10.fr
2008-May-02 14:40 UTC
[Rd] S4: what to put in initialize, validity and constructor?
Hi the list, I have some trouble using validity, intialize and the constructor. More precisely, what should go where? Here is a toy exemple (seams long, but the code is very simple): I want to define an object with two slots a and b with the properties that b will be either empty or the scare of a. Example of valid object : a= b a=2 b a=3 b=9 So I define my object and the validity function : setClass( "A", representation(a="numeric",b="numeric"), validity=function(object){ cat("Validity\n") if(length(object at b)!=0){ if(length(object at a)==0){stop("Can not have empty a and non emty b")}else{} if(object at a^2!=object at b){stop("b is not the scare of a")}else{} }else{} return(TRUE) } ) It works: new("A") new("A",a=2,b=4) try(new("A",b=4)) new("A",a=2) try(new("A",a=2,b=3)) Then I define the initialize function. When b is givent but not a, the initialise function set a to sqrt(b). setMethod( "initialize", "A", function(.Object,a,b){ if(missing(a)&!missing(b)){ .Object at b <- b .Object at a <- sqrt(b) }else{} if(!missing(a)&missing(b)){ .Object at a <- a }else{} if(!missing(a)&!missing(b)){ .Object at a <- a .Object at b <- b }else{} validObject(.Object) return(.Object) } ) It is fine: new("A") new("A",a=2,b=4) new("A",b=9) new("A",a=2) try(new("A",a=2,b=3)) Then I want to set the constructor A <- function(a,b){ return(new("A",a,b)) } But this does not work: A() A(a=2,b=4) A(b=9) A(a=2) The following does not work either: A <- function(a=numeric(),b=numeric()){ return(new("A",a,b)) } A() A(a=2,b=4) A(b=9) A(a=2) So is there a way to define the constructor A without dealing again with all the missing&missing staff like in initialize? Christophe
Sklyar, Oleg (MI London)
2008-May-02 15:11 UTC
[Rd] S4: what to put in initialize, validity and constructor?
setClass("A", representation(a="numeric",b="numeric"), validity = function(object) { if (length(object at a)!=length(object at b)) return("different lengths of a and b") if (length(object at a)==0) return("object length is zero") TRUE } ) Do not change initialize! Define constructors: setGeneric("A", function(a,b,...) standardGeneric("A")) setMethod("A", signature(a="missing",b="missing"), function(a,b,...) A(as.numeric(1:10),...) ## calls the one below ) setMethod("A", signature(a="A",b="missing"), function(a,b,...) a ) setMethod("A", signature(a="ANY",b="ANY"), function(a,b,...) new("A",a=as.numeric(a),b=as.numeric(b),...) ) setMethod("A", signature(a="ANY",b="missing"), function(a,b,...) A(a,a,...) ## Calls the one above ) etc. In words: 1) validity should return a character in case of errors 2) default initializer usually does the job 3) define constructors as methods to allow different signatures and conversions from other classes 4) If you derive your class from numeric, rather than add slots, the performance will be much better and you will get default behaviour of numeric, i.e. setClass("A", representatiom("numeric", b="numeric") etc 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 > cgenolin at u-paris10.fr > Sent: 02 May 2008 15:41 > To: r-devel at r-project.org > Subject: [Rd] S4: what to put in initialize, validity and constructor? > > Hi the list, > > I have some trouble using validity, intialize and the > constructor. More precisely, what should go where? > Here is a toy exemple (seams long, but the code is very simple): > > I want to define an object with two slots a and b with the > properties that b will be either empty or the scare of a. > Example of valid object : > a= b> a=2 b> a=3 b=9 > > So I define my object and the validity function : > > setClass( > "A", > representation(a="numeric",b="numeric"), > validity=function(object){ > cat("Validity\n") > if(length(object at b)!=0){ > if(length(object at a)==0){stop("Can not have empty > a and non emty b")}else{} > if(object at a^2!=object at b){stop("b is not the scare > of a")}else{} > }else{} > return(TRUE) > } > ) > > It works: > > new("A") > new("A",a=2,b=4) > try(new("A",b=4)) > new("A",a=2) > try(new("A",a=2,b=3)) > > > Then I define the initialize function. When b is givent but > not a, the initialise function set a to sqrt(b). > > setMethod( > "initialize", > "A", > function(.Object,a,b){ > if(missing(a)&!missing(b)){ > .Object at b <- b > .Object at a <- sqrt(b) > }else{} > if(!missing(a)&missing(b)){ > .Object at a <- a > }else{} > if(!missing(a)&!missing(b)){ > .Object at a <- a > .Object at b <- b > }else{} > validObject(.Object) > return(.Object) > } > ) > > It is fine: > > new("A") > new("A",a=2,b=4) > new("A",b=9) > new("A",a=2) > try(new("A",a=2,b=3)) > > > Then I want to set the constructor > > A <- function(a,b){ > return(new("A",a,b)) > } > > But this does not work: > A() > A(a=2,b=4) > A(b=9) > A(a=2) > > > The following does not work either: > > A <- function(a=numeric(),b=numeric()){ > return(new("A",a,b)) > } > > A() > A(a=2,b=4) > A(b=9) > A(a=2) > > So is there a way to define the constructor A without dealing > again with all the missing&missing staff like in initialize? > > Christophe > > ______________________________________________ > 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...{{dropped:22}}
cgenolin at u-paris10.fr
2008-May-02 18:45 UTC
[Rd] S4: what to put in initialize, validity and constructor?
> Do not change initialize!As I sat, this is a toy example. In my real example, initialize does a lot of things like calculation of quality indice (b is not the scare of a, but B1, B2 and B3 are the the within matrix of A after imputation with 3 differents methods), giving names to some matrix column and so on. So I seams costfull to not use an initialize.> Define constructors: > > setGeneric("A", function(a,b,...) standardGeneric("A")) > > setMethod("A", signature(a="missing",b="missing"), > function(a,b,...) A(as.numeric(1:10),...) ## calls the one below > ) > > setMethod("A", signature(a="A",b="missing"), > function(a,b,...) a > ) > > setMethod("A", signature(a="ANY",b="ANY"), > function(a,b,...) new("A",a=as.numeric(a),b=as.numeric(b),...) > ) > > setMethod("A", signature(a="ANY",b="missing"), > function(a,b,...) A(a,a,...) ## Calls the one above > ) > > etc. > > In words: > 1) validity should return a character in case of errors > 2) default initializer usually does the job > 3) define constructors as methods to allow different signatures and > conversions from other classes > 4) If you derive your class from numeric, rather than add slots, > the performance will be much better and you will get default > behaviour of numeric, i.e. > > setClass("A", > representatiom("numeric", b="numeric") etc > > 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 >> cgenolin at u-paris10.fr >> Sent: 02 May 2008 15:41 >> To: r-devel at r-project.org >> Subject: [Rd] S4: what to put in initialize, validity and constructor? >> >> Hi the list, >> >> I have some trouble using validity, intialize and the >> constructor. More precisely, what should go where? >> Here is a toy exemple (seams long, but the code is very simple): >> >> I want to define an object with two slots a and b with the >> properties that b will be either empty or the scare of a. >> Example of valid object : >> a= b>> a=2 b>> a=3 b=9 >> >> So I define my object and the validity function : >> >> setClass( >> "A", >> representation(a="numeric",b="numeric"), >> validity=function(object){ >> cat("Validity\n") >> if(length(object at b)!=0){ >> if(length(object at a)==0){stop("Can not have empty >> a and non emty b")}else{} >> if(object at a^2!=object at b){stop("b is not the scare >> of a")}else{} >> }else{} >> return(TRUE) >> } >> ) >> >> It works: >> >> new("A") >> new("A",a=2,b=4) >> try(new("A",b=4)) >> new("A",a=2) >> try(new("A",a=2,b=3)) >> >> >> Then I define the initialize function. When b is givent but >> not a, the initialise function set a to sqrt(b). >> >> setMethod( >> "initialize", >> "A", >> function(.Object,a,b){ >> if(missing(a)&!missing(b)){ >> .Object at b <- b >> .Object at a <- sqrt(b) >> }else{} >> if(!missing(a)&missing(b)){ >> .Object at a <- a >> }else{} >> if(!missing(a)&!missing(b)){ >> .Object at a <- a >> .Object at b <- b >> }else{} >> validObject(.Object) >> return(.Object) >> } >> ) >> >> It is fine: >> >> new("A") >> new("A",a=2,b=4) >> new("A",b=9) >> new("A",a=2) >> try(new("A",a=2,b=3)) >> >> >> Then I want to set the constructor >> >> A <- function(a,b){ >> return(new("A",a,b)) >> } >> >> But this does not work: >> A() >> A(a=2,b=4) >> A(b=9) >> A(a=2) >> >> >> The following does not work either: >> >> A <- function(a=numeric(),b=numeric()){ >> return(new("A",a,b)) >> } >> >> A() >> A(a=2,b=4) >> A(b=9) >> A(a=2) >> >> So is there a way to define the constructor A without dealing >> again with all the missing&missing staff like in initialize? >> >> Christophe >> >> ______________________________________________ >> 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 > > ********************************************************************** > >
Oleg Sklyar
2008-May-03 09:08 UTC
[Rd] S4: what to put in initialize, validity and constructor?
cgenolin at u-paris10.fr wrote:> >> Do not change initialize! > > As I sat, this is a toy example. In my real example, initialize does a > lot of things like calculation of quality indice (b is not the scare of > a, but B1, B2 and B3 are the the within matrix of A after imputation > with 3 differents methods), giving names to some matrix column and so > on. So I seams costfull to not use an initialize.This all can be done in one of the constructors, which is then called by the other, as in my example below. I do not see a contradiction.> >> Define constructors: >> >> setGeneric("A", function(a,b,...) standardGeneric("A")) >> >> setMethod("A", signature(a="missing",b="missing"), >> function(a,b,...) A(as.numeric(1:10),...) ## calls the one below >> ) >> >> setMethod("A", signature(a="A",b="missing"), >> function(a,b,...) a >> ) >> >> setMethod("A", signature(a="ANY",b="ANY"), >> function(a,b,...) new("A",a=as.numeric(a),b=as.numeric(b),...) >> ) >> >> setMethod("A", signature(a="ANY",b="missing"), >> function(a,b,...) A(a,a,...) ## Calls the one above >> ) >> >> etc. >> >> In words: >> 1) validity should return a character in case of errors >> 2) default initializer usually does the job >> 3) define constructors as methods to allow different signatures and >> conversions from other classes >> 4) If you derive your class from numeric, rather than add slots, >> the performance will be much better and you will get default >> behaviour of numeric, i.e. >> >> setClass("A", >> representatiom("numeric", b="numeric") etc >> >> 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 >>> cgenolin at u-paris10.fr >>> Sent: 02 May 2008 15:41 >>> To: r-devel at r-project.org >>> Subject: [Rd] S4: what to put in initialize, validity and constructor? >>> >>> Hi the list, >>> >>> I have some trouble using validity, intialize and the >>> constructor. More precisely, what should go where? >>> Here is a toy exemple (seams long, but the code is very simple): >>> >>> I want to define an object with two slots a and b with the >>> properties that b will be either empty or the scare of a. >>> Example of valid object : >>> a= b>>> a=2 b>>> a=3 b=9 >>> >>> So I define my object and the validity function : >>> >>> setClass( >>> "A", >>> representation(a="numeric",b="numeric"), >>> validity=function(object){ >>> cat("Validity\n") >>> if(length(object at b)!=0){ >>> if(length(object at a)==0){stop("Can not have empty >>> a and non emty b")}else{} >>> if(object at a^2!=object at b){stop("b is not the scare >>> of a")}else{} >>> }else{} >>> return(TRUE) >>> } >>> ) >>> >>> It works: >>> >>> new("A") >>> new("A",a=2,b=4) >>> try(new("A",b=4)) >>> new("A",a=2) >>> try(new("A",a=2,b=3)) >>> >>> >>> Then I define the initialize function. When b is givent but >>> not a, the initialise function set a to sqrt(b). >>> >>> setMethod( >>> "initialize", >>> "A", >>> function(.Object,a,b){ >>> if(missing(a)&!missing(b)){ >>> .Object at b <- b >>> .Object at a <- sqrt(b) >>> }else{} >>> if(!missing(a)&missing(b)){ >>> .Object at a <- a >>> }else{} >>> if(!missing(a)&!missing(b)){ >>> .Object at a <- a >>> .Object at b <- b >>> }else{} >>> validObject(.Object) >>> return(.Object) >>> } >>> ) >>> >>> It is fine: >>> >>> new("A") >>> new("A",a=2,b=4) >>> new("A",b=9) >>> new("A",a=2) >>> try(new("A",a=2,b=3)) >>> >>> >>> Then I want to set the constructor >>> >>> A <- function(a,b){ >>> return(new("A",a,b)) >>> } >>> >>> But this does not work: >>> A() >>> A(a=2,b=4) >>> A(b=9) >>> A(a=2) >>> >>> >>> The following does not work either: >>> >>> A <- function(a=numeric(),b=numeric()){ >>> return(new("A",a,b)) >>> } >>> >>> A() >>> A(a=2,b=4) >>> A(b=9) >>> A(a=2) >>> >>> So is there a way to define the constructor A without dealing >>> again with all the missing&missing staff like in initialize? >>> >>> Christophe >>> >>> ______________________________________________ >>> 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 >> >> ********************************************************************** >> >> > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel-- Dr Oleg Sklyar * EBI-EMBL, Cambridge CB10 1SD, UK * +44-1223-494466