From osklyar at maninvestments.com  Tue Dec 23 17:09:09 2008
From: osklyar at maninvestments.com (Sklyar, Oleg (London))
Date: Tue, 23 Dec 2008 16:09:09 -0000
Subject: [Rd] ... (dotMethods) and cbind/rbind: how to give the
	signature?
In-Reply-To: <200812221526.50379.cbeleites@units.it>
References: <200812221526.50379.cbeleites@units.it>
Message-ID: <1A68FCB28DE72F4BA3B967E6506CCE43047DF512@mildnpexmb01.maninvestments.ad.man.com>

I find it easier to use S3 methods for cbind and rbind even for S4 classes. The reason is that first you won't have different classes in the signature for cbind/rbind and second is that ... signatures are only allowed if ALL arguments are of the same class, whereas setGeneric("cbind") will force you to specify deparse.level of a different class -- it does not work for me. If you however try to redefine the cbind generic (as it is not generic initially) without deparse.level you first face a compatibility problem and cbind for matrices stops working.

If anybody has a working S4 solution I would be grateful for a hint:


setClass("ClassA", representation("matrix", comment="character"))

a = new("ClassA", matrix(runif(10),ncol=2), comment="aa")
b = new("ClassA", matrix(runif(15),ncol=3), comment="bb")

cbind.ClassA = mycbind = function(...) {
	dots = list(...)
	if (length(dots)<2) return(dots[[1]])
	data = lapply(dots, function(x) x at .Data)
	data = if (length(data)>1) do.call("cbind",data) else data[[1]]
	comment = sapply(dots, function(x) x at comment)
	comment = paste(comment, collapse="; ")
	new("ClassA", data, comment=comment)
}

cbind(a,b)
cbind(a at .Data, b at .Data)

With respect to your second question on S4 methods -- it gives room for extendability and type checking, otherwise there is no good reason to define functions as methods if you will only have one single implementation of functionality with the same name.


Dr Oleg Sklyar
Research Technologist
AHL / Man Investments Ltd
+44 (0)20 7144 3107
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 Claudia Beleites
> Sent: 22 December 2008 14:27
> To: r-devel at r-project.org
> Subject: [Rd] ... (dotMethods) and cbind/rbind: how to give 
> the signature?
> 
> Dear List,
> 
> I'm struggling with the signature writing cbind/rbind 
> functions for a S4 
> class.
> 
> First of all, I'm very happy that it is now possible to 
> dispatch on ...
> I follow the example for "paste" in ?dotMethods, which works 
> as far as this:
> 
> ### start example
> setClass ("cbtest",
>           representation = representation (data = "data.frame"),
>           prototype = prototype (data = data.frame (spc = I 
> (matrix (rnorm 
> (15) , 3, 5)))
>             )
>  )
> 
> a <- new ("cbtest")
> a
> 
> setMethod("cbind2", signature (x = "cbtest", y  = "cbtest"),
>           function (x, y){
>             x at data$spc <- cbind (x at data$spc, y at data$spc) 
>             x
>           }
>           )
> 
> 
> setMethod("cbind2", signature (x = "cbtest", y = "missing"), 
> function (x, y) 
> x)
> 
> cb.cbind <- function (..., deparse.level){
>   dots <- list (...) 
>   for (i in seq_along (dots)[-1])
>     dots[[1]] <- cbind2 (dots[[1]], dots[[i]])
> 
>   dots[[1]]
> } 
> 
> 
> cbind2 (a, a)
> cb.cbind (a, a, a)
> 
> 
> cbind (a, a, a)
> setGeneric ("cbind", signature = signature("...")) 
> setMethod ("cbind", "cbtest",
>            function (..., deparse.level) cb.cbind (...))
> cbind (a, a, a)
> cbind (a, a, a, deparse.level = 1)
> 
> ### end example
> 
> 
> However, I get the following message:
> with setGeneric 
> 
> Creating a generic for "cbind" in package  ".GlobalEnv"
>     (the supplied definition differs from and overrides the 
> implicit generic in 
> package "base": Signatures differ:  (...), (deparse.level))
> 
> How do I specify the correct signature? 
> 
> Furthermore: as I do not want to do anything with 
> "deparse.level", I'd rather 
> specify it as "missing" in setMethod. But again, I don't get 
> the signature 
> correct.
> 
> I tried 
> setGeneric ("cbind", signature = signature (...="...", 
> deparse.level = 
> "integer"))
> and 
> setGeneric ("cbind", signature = signature ("...", 
> deparse.level = "integer"))
> 
> both give: 
> Fehler in makeGeneric(name, fdef, fdeflt, group = group, valueClass = 
> valueClass,  : 
>   Nicht-Argumente in der Signatur: integer
> 
> What is my mistake?
> 
> Thanks a lot for your help!
> 
> Claudia
> 
> 
> > version
>                _                           
> platform       i486-pc-linux-gnu           
> arch           i486                        
> os             linux-gnu                   
> system         i486, linux-gnu             
> status                                     
> major          2                           
> minor          8.0                         
> year           2008                        
> month          10                          
> day            20                          
> svn rev        46754                       
> language       R                           
> version.string R version 2.8.0 (2008-10-20)
> 
> 
> -- 
> Claudia Beleites
> Dipartimento dei Materiali e delle Risorse Naturali
> Universit? degli Studi di Trieste
> Via Alfonso Valerio 6/a
> I-34127 Trieste
> 
> phone: +39 (0 40) 5 58-34 47
> email: cbeleites at units.it
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 

**********************************************************************
Please consider the environment before printing this email or its attachments.
The contents of this email are for the named addressees ...{{dropped:19}}



[Rd] ... (dotMethods) and cbind/rbind: how to give the signature?
Sklyar, Oleg (London