Re: [R] questions about setMethod("Arith", ...)

From: John Chambers <jmc_at_research.bell-labs.com>
Date: Fri 09 Jul 2004 - 06:18:05 EST

The version of "distr" on CRAN at the time of this posting is seriously broken, in ways that are not directly related to Arith or to group generics in general, but which are enough to explain the problems you report (and much else besides).

You include a NAMESPACE file with this package. If you really want to use namespaces (somewhat questionable in this case), you must include exportMethods() directives for all functions in setMethod() calls. You have not done so, therefore in principle all your methods are private, except those for generic functions exported from distr itself.

(Because of the way primitive functions currently dispatch methods, you probably didn't see as much evidence as you should have showing the error. If you had used the showMethods() function recommended in "Programming with Data" to view methods, not the getMethods() function, you would have seen that distr created no public methods for "/" or the other arithmetic operators.)

The distr package has a couple of other obvious questionable features. It takes a very long time for library(distr) to be executed. For packages with substantial class and method definitions, the traditionally installed R package is slow to attach, because R does all the computations in the package source each time the library is attached. You should use the -s option to INSTALL to create a saved image. Also, package distr overrides the objects F and T in the base package, which is likely to cause problems for many users, especially those coming from S-Plus.

Your other comments below mostly come from not recognizing that methods for a specific member of the group ("/", "+") always take precedence over any methods for the group generic.

It's very desirable that reports to r-help (especially those implying a bug) be based on clear, self-contained examples using reliable packages only. Otherwise anyone trying to respond has to search through your code trying to find out what's going on, which will make a response to any further postings less likely. This posting is an example.

Sorry to be severe. Your package looks interesting--do persevere with it, but you should test future versions more thoroughly before submitting them to CRAN.

John Chambers

Matthias Kohl wrote:
>
> Hi,
>
> we have some questions concerning the definition of new arithmetic methods.
>
> In our package "distr" (on CRAN) we define some new arithmetic methods
> for "+", "-", "*", "/".
> After loading "distr" the corresponding arithmetic methods work. Now, if
> we define a new
> class and also a new method for one of the arithmetic methods "+", "-",
> "*", "/", still everything works fine. But, if we then define new
> methods for the whole group "Arith", the arithmetic methods of "distr"
> no longer work. (for more details see example code below)
> What are we missing?
>
> Moreover, there is a certain precendence; i.e., if one defines a single
> arithmetic method (e.g., "/") and alterwards defines a method for the
> whole group "Arith", the "old" method "/" remains valid.
> However, if we first define a method for the whole group "Arith" and
> afterwards define a new single arithmetic method (e.g., "+") the new one
> is valid. (for more details see example code below).
> Is this intended?
>
> Thanks for your help,
> Matthias, Thomas
>
> ###########################################################
> ## Example code
> ###########################################################
> require(distr)
> getMethods("/") # shows the corresponding methods of "distr"
>
> ## now define a new class "track" (see Chambers (1998))
> ## and define "/"
>
> setClass("track", representation(x = "numeric", y = "numeric"))
> setMethod("/", signature("track", "numeric"),
> function(e1, e2){ e1@y = e1@y/e2; e1 })
>
> getMethods("/") # shows the corresponding methods
> # of "distr" and class "track"
>
> (N <- Norm()) # creates an object of standard normal distribution
> (N1 <- N/3) # works
> (tr <- new("track", x = 1:3, y = 4:6))
> (tr1 <- tr/3) # works
>
> ## now define new methods for "Arith"
> setMethod("Arith", signature("track", "numeric"),
> function(e1, e2){
> e1@x = callGeneric(e1@x, e2)
> e1
> })
>
> getMethods("/") # "/" for "distr" is lost
> N2 <- N/3 # fails
> (tr2 <- tr/3) # works, "but" still the "old" method
> tr + 2 # works
>
> ## now a new method "+"
> setMethod("+", signature("track", "numeric"),
> function(e1, e2){ e1@y = e1@y+e2; e1 })
>
> tr + 2 # works, "but" with the "new" method
>
> ______________________________________________
> R-help@stat.math.ethz.ch mailing list
> https://www.stat.math.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html

-- 
John M. Chambers                  jmc@bell-labs.com
Bell Labs, Lucent Technologies    office: (908)582-2681
700 Mountain Avenue, Room 2C-282  fax:    (908)582-3340
Murray Hill, NJ  07974            web: http://www.cs.bell-labs.com/~jmc

______________________________________________
R-help@stat.math.ethz.ch mailing list
https://www.stat.math.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Received on Fri Jul 09 06:29:11 2004

This archive was generated by hypermail 2.1.8 : Wed 03 Nov 2004 - 22:54:47 EST