R中通用`plot`函数的方法调度 [英] Method dispatch for generic `plot` function in R

查看:165
本文介绍了R中通用`plot`函数的方法调度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

R如何派遣 plot 函数?标准泛型定义为:

  plot < -  function(x,y,...)UseMethod(plot) 

通常情况下,所有绘图方法都需要参数 x y 。然而,还有其他各种不同论点的功能。一些函数只有参数 x

  plot.data.frame< ;  - 函数(x,...)

其他甚至没有 x 也 y

  plot.formula <  - 函数(formula,data = parent.frame(),...,subset,
ylab = varnames [response],ask = dev.interactive())

这是如何工作的,以及它在何处被记录下来?




背景



在我的包中 papeR 参见GitHub )我想替换函数 plot.data.frame ,它在R包图形与我自己的版本。然而,这通常是不允许的


请勿从基本/推荐软件包中替换注册的S3方法,
不允许的东西通过CRAN政策,并且意味着
每个人都可以获得你的方法,即使你的名字空间被卸载了。


正如Brian Ripley let我上次知道我试图做这样的事情。一个可能的解决方案如下:


如果你想改变一个泛型的行为,比如 predict() ,对于
是一个或两个现有类,您可以使用默认方法 stats :: predict 在您自己的
包中添加如通用类型

对于其他方法,我需要注册修改后的
方法(在您自己的包中)。可以很容易地实现这个(例如 toLatex ),但是, plot 我遇到了问题。我将以下内容添加到我的代码中:

  ##覆盖标准通用
plot < - function(x,y ,...)
UseMethod(plot)

##默认回退到标准通用
plot.default< - function(x,y,.. )
graphics :: plot(x,y,...)

##现在为数据帧指定修改的绘图函数
plot.data.frame< - 函数(x,variables = names(x),...)

这适用于数据框架和图表与 x y 。然而,如果我试图绘制一个公式等,它就不起作用:

  eval中的错误(expr,envir,enclos):
参数y缺失,没有默认

我也尝试使用

  plot.default<  -  function(x,y,... )
UseMethod(graphics :: plot)

但是我得到

  UseMethod(graphics :: plot)中的错误:
适用于'graphics :: plot'的方法适用于对象类公式

所以后续问题是我如何解决这个问题?






使用我的解决方案修复了包内的问题。然而, plot.formula 之后被破坏:

  library(devtools )
install_github(hofnerb / papeR)
示例(plot.formula,package =graphics)##仍然有效

library(papeR)
示例(plot,package =papeR)## works
### BUT
示例(plot.formula,package =graphics)##现在被破坏
code>


解决方案

感谢@Roland,我解决了一部分问题。

似乎参数的位置用于方法调度(而不仅仅是名称)。但是名称部分使用。因此,以Rolands为例

 > plot.myclass<  -  function(a,b,...)
>打印(b)
> x< - 1
> y< - 2
> class(x)< - myclass

我们有

 > plot(x,y)
[1] 2
> plot(a = x,b = y)
[1] 2

但如果我们使用标准参数名称

 > plot(x = x,y = y)
打印错误(b)(来自#1):参数b丢失,没有默认

不起作用。可以看到 x 正确用于分派,但是 b 然后是缺失。此外,我们不能交换 a b

 > plot(b = y,a = x)
在plot.default(b = y,a = x)中的错误:
参数2匹配多个形式参数

然而,如果要派发的参数是没有名称的第一个(?)元素,可以使用不同的顺序:

 > plot(b = y,x)
[1] 2






解决真正的问题:



我不得不使用

  plot.default<  -  function(x,y,...)
graphics :: plot(x,y,...)

真正的问题出现在我的 plot.data.frame 方法的内部在那里我沿用了一些东西:

  plot(x1〜y1)

不指定数据。通常这个默认情况下工作为 data = parent.frame()。不知何故,在这种情况下,这是行不通的。我现在用 plot(y1,x1),它就像一个魅力一样。所以这是我的sl。。


How does R dispatch plot functions? The standard generic is defined as

plot <- function (x, y, ...)  UseMethod("plot")

So usually, all plot methods need arguments x and y. Yet, there exists a variety of other functions with different arguments. Some functions only have argument x:

plot.data.frame <- function (x, ...)

others even have neither x nor y:

plot.formula <- function(formula, data = parent.frame(), ..., subset,
                         ylab = varnames[response], ask = dev.interactive()) 

How does this work and where is this documented?


Background

In my package papeR (see GitHub) I want to replace the function plot.data.frame, which is defined in the R package graphics with my own version. Yet, this is usually not allowed

Do not replace registered S3 methods from base/recommended packages, something which is not allowed by the CRAN policies and will mean that everyone gets your method even if your namespace is unloaded.

as Brian Ripley let me know last time I tried to do such a thing. A possible solution is as follows:

If you want to change the behaviour of a generic, say predict(), for an existing class or two, you could add such as generic in your own package with default method stats::predict, and then register modified methods for your generic (in your own package).

For other methods I could easily implement this (e.g. toLatex), yet, with plot I am having problems. I added the following to my code:

## overwrite standard generic
plot <- function(x, y, ...)
    UseMethod("plot")

## per default fall back to standard generic
plot.default <- function(x, y, ...)
    graphics::plot(x, y, ...)

## now specify modified plot function for data frames
plot.data.frame <- function(x, variables = names(x), ...)

This works for data frames and plots with x and y. Yet, it does not work if I try to plot a formula etc:

Error in eval(expr, envir, enclos) : 
  argument "y" is missing, with no default

I also tried to use

plot.default <- function(x, y, ...) 
    UseMethod("graphics::plot")

but then I get

Error in UseMethod("graphics::plot") : 
  no applicable method for 'graphics::plot' applied to an object of class "formula"

So the follow up question is how I can fix this?


[Edit:] Using my solution below fixes the problems within the package. Yet, plot.formula is broken afterwards:

library("devtools")
install_github("hofnerb/papeR")
example(plot.formula, package="graphics") ## still works

library("papeR")
example(plot, package = "papeR") ## works
### BUT
example(plot.formula, package="graphics") ## is broken now

解决方案

Thanks to @Roland I solved part of my problem.

It seems that the position of the arguments are used for method dispatch (and not only the names). Names are however partially used. So with Rolands example

> plot.myclass <- function(a, b, ...) 
>    print(b) 
> x <- 1
> y <- 2
> class(x) <- "myclass"

we have

> plot(x, y)
[1] 2
> plot(a = x, b = y)
[1] 2

but if we use the standard argument names

> plot(x = x, y = y)
Error in print(b) (from #1) : argument "b" is missing, with no default

it doesnt't work. As one can see x is correctly used for the dispatch but b is then "missing". Also we cannot swap a and b:

> plot(b = y, a = x)
Error in plot.default(b = y, a = x) : 
  argument 2 matches multiple formal arguments

Yet, one could use a different order if the argument one wants to dispatch for is the first (?) element without name:

> plot(b = y, x)
[1] 2


Solution to the real problem:

I had to use

plot.default <- function(x, y, ...)
    graphics::plot(x, y, ...)

The real issue was internally in my plot.data.frame method where I was using something along the lines of:

plot(x1 ~ y1)

without specifying data. Usually this works as data = parent.frame() per default. Somehow in this case this wasn't working. I now use plot(y1, x1) which works like a charm. So this was my sloppiness.

这篇关于R中通用`plot`函数的方法调度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆