[Rd] Methods package is now attached by default
Martin Maechler
Martin Maechler <maechler@stat.math.ethz.ch>
Wed Jan 22 10:41:02 2003
>>>>> "TL" == Thomas Lumley <tlumley@u.washington.edu>
>>>>> on Tue, 21 Jan 2003 14:49:58 -0800 (PST) writes:
TL> On Tue, 21 Jan 2003, Roger Peng wrote:
>> I was looking at the examples in the `optim' help page
>> and I think one of them does not quite work. In
>> particular, this example:
(Note to all readers : We are talking about "R-devel" (aka R-pre-pre-1.7.0)
>> ## "wild" function , global minimum at about -15.81515
>> fw <- function (x) 10*sin(0.3*x)*sin(1.3*x^2) + 0.00001*x^4
>> + 0.2*x+80
>> plot(fw, -50, 50, n=1000, main = "optim() minimising `wild function'")
>>
>> While it executes, I think it produces the wrong plot.
>> The call to plot indicates that it should be plotted from
>> x values of -50 to 50 but the resulting plot goes from 0
>> to 50. However, if I call
>>
>> plot.function(fw,-50,50, n=1000, main="optim() minimising ..")
>>
>> then that plot appears to be correct. I figured this had
>> something to do with the method dispatching on functions.
TL> Not quite, because it doesn't use method dispatching --
TL> it calls plot.function explicitly.
{ yeah, but Roger is right "in spirit": The reason it is called
explicitly from the generic, is the fact that plot.function()'s
arg.list doesn't match the generic at all...
}
TL> I think it's a thinko in editing. plot() went from
plot<- function (x, ...)
{
if (is.null(attr(x, "class")) && is.function(x)) {
if ("ylab" %in% names(list(...)))
plot.function(x, ...)
else plot.function(x, ylab = paste(deparse(substitute(x)),
"(x)"), ...)
}
else UseMethod("plot")
}
TL> to
plot<-function (x, y, ...)
{
if (is.null(attr(x, "class")) && is.function(x)) {
if ("ylab" %in% names(list(...)))
plot.function(x, ...)
else plot.function(x, ylab = paste(deparse(substitute(x)),
"(x)"), ...)
}
else UseMethod("plot")
}
>> but the extra argument `y' never got passed down to plot.function. It
>> should be something like
plot <- function (x, y, ...)
{
if (is.null(attr(x, "class")) && is.function(x)) {
if ("ylab" %in% names(list(...)))
plot.function(x,y, ...)
else plot.function(x, y, ylab = paste(deparse(substitute(x)),
"(x)"), ...)
}
else UseMethod("plot")
}
----
Good idea {been there, tried other stuff many months ago...}
but it doesn't solve the compatibility problem completely:
Try, e.g.,
plot(sin, 4, 6)
plot(sin, to = 10) ## old behavior would have plotted from 0 to 10
and I think John Chambers and/or I found out quite a while ago that
it's almost impossible to become really compatible to the old behavior
when you include the automatically generated `ylab' and consider
named and positional arguments their defaults.
Since March 2002, I have the following
in src/library/methods/R/plot.R
and I think found to work it (almost ? entirely?) correctly,
but had never committed it since I always found it was really an
ugly hack for a generic function definition:
## 2-argument (dispatching)
plot <- function (x, y, ...)
{
if (is.null(attr(x, "class")) && is.function(x)) {
nms <- names(list(...))
## need to pass `y' to plot.function() when positionally matched
if(missing(y)) # set to defaults {could use formals(plot.default)}:
y <- { if (!"from" %in% nms) 0 else
if (!"to" %in% nms) 1 else
if (!"xlim" %in% nms) NULL }
if ("ylab" %in% nms)
plot.function(x, y, ...)
else plot.function(x, y,
ylab = paste(deparse(substitute(x)), "(x)"), ...)
}
else UseMethod("plot")
}
---
maybe I should commit this version to R-devel after all?
Martin Maechler <maechler@stat.math.ethz.ch> http://stat.ethz.ch/~maechler/
Seminar fuer Statistik, ETH-Zentrum LEO C16 Leonhardstr. 27
ETH (Federal Inst. Technology) 8092 Zurich SWITZERLAND
phone: x-41-1-632-3408 fax: ...-1228 <><