Skip to content

S4 methods for rbind()

3 messages · robin hankin, Martin Morgan

#
Hello.

I am trying to write an S4 method for rbind(). I have a class of objects
called 'mdm', and I want to be able to rbind() them to one another.

I do not want the method for rbind() to coerce anything to an mdm object.
I want rbind(x1,x2,x1,x2) to work as expected [ie rbind() should take any
number of arguments].

This is what I have so far:


setGeneric(".rbind_pair", function(x,y){standardGeneric(".rbind_pair")})
setMethod(".rbind_pair", c("mdm", "mdm"), function(x,y){.mdm.cPair(x,y)})
setMethod(".rbind_pair", c("mdm", "ANY"),
function(x,y){.mdm_rbind_error(x,y)})
setMethod(".rbind_pair", c("ANY", "mdm"),
function(x,y){.mdm_rbind_error(x,y)})
setMethod(".rbind_pair", c("ANY", "ANY"),
function(x,y){.mdm_rbind_error(x,y)})

".mdm_rbind_error" <- function(x,y){
stop("an mdm object may only be rbinded to another mdm object")
}

".mdm.rbind_pair" <- function(x,y){
stopifnot(compatible(x,y))
mdm(rbind(xold(x),xold(y)),c(types(x),types(y))) # this is the "meat" of
the rbind functionality
}

setGeneric("rbind")
setMethod("rbind", signature="mdm", function(x, ...) {
if(nargs()<3)
.mdm_rbind_pair(x,...)
else
.mdm_rbind_pair(x, Recall(...))
})


But


LE223:~/packages% sudo R CMD INSTALL ./multivator
[snip]
Creating a new generic function for "tail" in "multivator"
Error in conformMethod(signature, mnames, fnames, f, fdef, definition) :
in method for ?rbind? with signature ?deparse.level="mdm"?: formal
arguments (... = "mdm", deparse.level = "mdm") omitted in the method
definition cannot be in the signature
Error : unable to load R code in package 'multivator'
ERROR: lazy loading failed for package ?multivator?
* removing ?/usr/local/lib64/R/library/multivator?
* restoring previous ?/usr/local/lib64/R/library/multivator?
LE223:~/packages%


I can't understand what the error message is trying to say.

Can anyone advise on a fix for this?
#
On 10/26/2010 03:53 AM, Robin Hankin wrote:
Hi Robin

try getGeneric("rbind") and showMethods("rbind") after your setGeneric;.
The generic is dispatching on 'deparse.level'. 'deparse.level' is
missing from your method definition, and so can't be used as the
signature for your method. Try to set the ... explicitly as the
signature to be used for dispatch.

setGeneric("rbind",
    function(..., deparse.level=1) standardGeneric("rbind"),
    signature = "...")

Martin

  
    
#
Thank you very much for this Martin.

It works!

There were two gotchas:

1.  One has to add 'deparse.level=1' to the setMethod() function
argument list

2.  Adding deparse.level=1 increments nargs() ...so the 3 should be 4.

But now it works!

Best wishes

Robin
On 26/10/10 13:49, Martin Morgan wrote: