[R] Bug? plot.formula does need support plot.first / plot.last param in plot.default

Ivan Krylov |kry|ov @end|ng |rom d|@root@org
Sat Jul 6 16:24:38 CEST 2024


В Fri, 05 Jul 2024 14:35:40 +0300
"Erez Shomron" <r-mails using erezsh.org> пишет:

> This works as expected:

> with(mtcars, plot(wt, mpg, plot.first = {
>     plot.window(range(wt), range(mpg))
>     arrows(3, 15, 4, 30)
> }))

I think you meant panel.first, not plot.first. At least I cannot find
any mention of plot.first in the R source code. In this example,
plot.first ends up being an argument of an internal call from
plot.default() to plot.window(), which evaluates its ellipsis
arguments. If your plot.first expression returned a non-NULL value, you
would also have received a warning:

plot.window(0:1, 0:1, plot.first = message('hello'))
# hello
plot.window(0:1, 0:1, plot.first = 123)
# Warning message:
# In plot.window(0:1, 0:1, plot.first = 123) :
#   "plot.first" is not a graphical parameter

It is indeed documented that "passing [panel.first] from other ‘plot’
methods may well not work since it may be evaluated too early". The
plot.formula method deliberately evaluates the arguments in the
ellipsis, and the workaround suggested in
https://bugs.r-project.org/show_bug.cgi?id=14591 doesn't help because
the expression is then evaluated in an undesired environment (parent
frame, not data).

You are correct that plot.formula tries to evaluate all its remaining
arguments in the context of the data passed to the method. In order for
the lazy evaluation to work, plot.formula would have to (1) know and
skip all such arguments by name on line 6, minding partial matching, (2)
rewrite them into the form evalq(original_argument_expression,
model_frame, parent_frame) so that they would be able to access both
the data and the variables visible in the frame of the caller, and (3)
give these expressions to do.call() in place of the original ones.

(1) sounds especially brittle since plot.formula() may dispatch to
other plot.* methods. Additionally, great care will need to be taken
not to break existing code that calls plot.formula, even if it's
already full of workarounds for plot.formula's behaviour.

-- 
Best regards,
Ivan



More information about the R-help mailing list