Although there is  not enough information to be sure, this may be 
related to an issue uncovered in other testing, for which a patch has 
just been committed.

The issue arises if the same generic function is defined in several 
packages.  For example, Matrix and msbase both have methods for the 
plot() function in graphics.  Since that function is not a generic, 
creating methods causes a generic function to be saved in the two 
packages' export environment.

So attaching both packages gives 3 versions of plot(), two generic and 
one not.

 > find("plot")
[1] "package:msbase"   "package:Matrix"   "package:graphics"

Note that this is NOT a question of having DIFFERENT generics with the 
same name; both these generics have package slot equal to "graphics" and 
therefore they refer to the same function.

The issue that arose was that, while a cached generic for plot() had all 
the methods, the methods table in the individual packages generally did 
not.  So here, a call to plot() picks up the generic from msbase, which 
may not have the methods defined in Matrix.  The symptom is that plot(x) 
from the global environment fails to find a method, say for "coef.lmer" 
defined in Matrix, even though showMethods("plot") and 
selectMethod("plot", "coef.lmer")  show the method.

The version committed today copies the cached version of the generic 
into the exported environment of the individual packages, so that all 
methods are available regardless of the order of the packages in the 
search list.

Again, remember that this is only when the package slot matches.  The 
following should work, although the sanity of the programmer is  in doubt.

 > plot <- function(theta) theta+1
 > setGeneric("plot", package="myPackage", 
function(theta)standardGeneric("plot"))
[1] "plot"
 > showMethods("plot")
Function: plot (package myPackage)
theta="ANY"

The user now would have to disambiguate:

 > Matrix::plot(1:10)
Hit <Return> to see next plot:
 > plot(1:10)
 [1]  2  3  4  5  6  7  8  9 10 11

The programmer should usually set up the imports for a package so that 
there is no ambiguity about which version is meant.  Also, with 2.4.x 
one should be able to supply the generic _function_ rather than just its 
name as the argument to setMethod().  But it's not claimed that 
something like the above works completely as one would expect.

The caching mechanism only applies to globally visible generic 
functions.  At the moment, non-exported (and so private) versions of a 
generic like plot are not cached.  Primitives unfortunately are always 
global.

There's some related discussion on the web page 
http://developer.r-project.org/howMethodsWork.pdf

John

One more comment:  For the future, I believe that the right attitude is 
that there is one version of this generic function, and it lives in the 
"graphics" package (yet one more time, _this_ generic function, 
identified by its name and package slot).  However, to implement that 
view cleanly needs a couple of things we don't have:

1.  a centralized dispatch for all generic functions, somewhat as is 
done now for primitives.

2.  methods labeled by the full reference to the classes--the class name 
plus the package where the definition of the class exists.  Otherwise, 
we can't be completely general about method selection.  Right now the 
system does not allow the same generic to have _public_ methods for two 
classes of the same name.

These changes are a bit too much for the few weeks left for 2.4.0.


Oosting, J. (PATH) wrote:
> Your suggestions worked ok in the example, but in my case there is yet 
> another package that implements a plot method.
> Now the plotting from within the package works, but plotting from outside the 
> package, on the console, gives an error as if plot.default is invoked.
>   
>> class(myplot)
>>     
> [1] "gt.barplot"
> attr(,"package")
> [1] "globaltest"
>   
>> plot(myplot)
>>     
> Error in xy.coords(x, y, xlabel, ylabel, log) : 
>         'x' and 'y' lengths differ
>
>
> Rgraphviz implements a plot method on 2 classes: graph and Ragraph
> multtest implements a plot method on 1 class: MTP
>
> globaltest, the package i'm working on, depends on multtest, and suggests 
> Rgraphviz. Class gt.barplot implements a plot method
>
>
> the output of showMethods("plot")
>   
>> showMethods("plot")
>>     
> Function: plot, (package graphics)
> x="ANY"
> x="graph"
> x="gt.barplot"
> x="MTP"
> x="Ragraph"
>
> Rgraphviz has a proper NAMESPACE and I created one for multtest that imports 
> plot from graphics, and exports plot as a method, because they are not 
> dependent on each other that does seem ok.
> In globaltest I import the plot method from multtest.
>
> How to deal with this.
>
>   
>> sessionInfo()
>>     
> R version 2.4.0 alpha (2006-09-11 r39258) 
> i386-pc-mingw32 
>
> locale:
> LC_COLLATE=Dutch_Netherlands.1252;LC_CTYPE=Dutch_Netherlands.1252;LC_MONETARY=Dutch_Netherlands.1252;LC_NUMERIC=C;LC_TIME=Dutch_Netherlands.1252
>
> attached base packages:
> [1] "splines"   "tools"     "methods"   "stats"     "graphics"  "grDevices"
> [7] "utils"     "datasets"  "base"     
>
> other attached packages:
>   Rgraphviz geneplotter     GOstats    Category    hgu95av2  genefilter 
>   "1.11.10"    "1.11.8"    "1.7.11"     "1.5.9"    "1.13.0"    "1.11.8" 
>        RBGL    annotate       graph       Ruuid          GO        KEGG 
>     "1.9.9"    "1.11.5"   "1.11.14"    "1.11.2"    "1.13.0"    "1.13.0" 
>      hu6800  globaltest    multtest    survival         vsn  golubEsets 
>    "1.13.0"     "4.3.5"    "1.11.2"      "2.28"    "1.11.2"     "1.3.1" 
>     Biobase 
>   "1.11.34" 
>  
>
> ===========================================================
> John Chambers wrote: 
>   
>> Good example.
>>
>> The basic problem is in the NAMESPACE file:
>>
>> importFrom(graphics, plot)
>>
>> But the version of plot() in the graphics package is not a generic function. 
>>  Therefore, when your mpplot() calls it there is no >method dispatch.
>>
>> You need to import the generic version of plot() from minipkg2 (notice that 
>> there's a message about creating a new generic for >plot() when you install 
>> minipkg2).
>>
>> The line in the NAMESPACE file should be:
>>
>> importFrom(minipkg2, plot)
>>
>> In your mini-example, there are some additional steps needed, not directly 
>> related to the problem & possibly not true in the >real example.
>>
>> 1.  minipkg2 also needs a NAMESPACE, in which it imports from methods and 
>> graphics and exports plot and the class mp2.plot >(example attached).
>>
>> 2.  Highly recommended though maybe not required here is to use some form of 
>> saved image, e.g. by including "LazyLoad:yes" in >the two DESCRIPTION files. 
>>
>> John
>>     
>
>
> Oosting, J. (PATH) wrote: 
>
>       I use 2 packages that both implement a S4 plot method, where one package
>       depends on the other (the bioconductor package globaltest which depends
>       on multtest). When the plot method is used from within the package, it
>       seems the default plot method is used, and an error is generated. When
>       the method is invoked from the console, the plot is created correctly. I
>       have reproduced this with 2 small packages (minipkg and minipkg2)
>       implementing just this part.
>       I've seen a thread about a similar problem, but that seemed mostly due
>       to already installed packages not handling the new S4 stuff.
>       
>       mpplot() is a function that creates a class instance and (usually)
>       invokes the plot immediately. When the dependency on minipkg2 is removed
>       from the DESCRIPTION file the first call to mpplot() gives no error and
>       shows the plot.
>       
>       
>       Jan Oosting
>       
>         
>
>               library(minipkg)
>                   
>
>       Loading required package: minipkg2
>       Creating a new generic function for 'plot' in 'minipkg2'
>         
>
>               mpplot(1:10)
>                   
>
>       Error in as.vector(x, "double") : cannot coerce to vector
>         
>
>               plot(mpplot(1:10,plot=FALSE)) # this shows a proper plot
>               showMethods("plot")
>                   
>
>       Function: plot, (package graphics)
>       x="ANY"
>       x="mp.plot"
>       x="mp2.plot"
>         
>
>               sessionInfo()
>                   
>
>       R version 2.4.0 Under development (unstable) (2006-09-04 r39086) 
>       i386-pc-mingw32 
>       
>       locale:
>       LC_COLLATE=Dutch_Netherlands.1252;LC_CTYPE=Dutch_Netherlands.1252;LC_MON
>       ETARY=Dutch_Netherlands.1252;LC_NUMERIC=C;LC_TIME=Dutch_Netherlands.1252
>       
>       attached base packages:
>       [1] "methods"   "stats"     "graphics"  "grDevices" "utils"
>       "datasets" 
>       [7] "base"     
>       
>       other attached packages:
>        minipkg minipkg2 
>        "1.0.0"  "1.0.0" 
>         
>
>               
>               
> ________________________________
>
>
>               ______________________________________________
>               R-devel@r-project.org mailing list
>               https://stat.ethz.ch/mailman/listinfo/r-devel
>                   
>
>
>
>       [[alternative HTML version deleted]]
>
> ______________________________________________
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>   

        [[alternative HTML version deleted]]

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to