r - R中通用 `plot`函数的方法调度

标签 r generics graphics plot

R 如何调度 plot 函数?标准泛型定义为

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

通常,所有绘图方法都需要参数 xy。然而,存在各种具有不同参数的其他函数。一些函数只有参数 x:

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

其他人甚至既没有x也没有y:

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

这是如何工作的,记录在哪里?


背景

在我的包 papeR ( see GitHub ) 中,我想替换函数 plot.data.frame,它在 R 包 graphics< 中定义/strong> 用我自己的版本。然而,这通常是不允许的

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.

正如 Brian Ripley 上次尝试做这样的事情时告诉我的那样。一种可能的解决方案如下:

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).

对于其他方法,我可以很容易地实现它(例如 toLatex),但是,使用 plot 我遇到了问题。我在我的代码中添加了以下内容:

## 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), ...)

这适用于带有 xy 的数据框和绘图。然而,如果我尝试绘制一个 formula 等,它就不起作用:

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

我也试过用

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

但后来我明白了

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

那么接下来的问题是我该如何解决这个问题?


[编辑:]使用我下面的解决方案修复了包中的问题。然而,plot.formula 之后被破坏了:

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

最佳答案

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

似乎参数的位置用于方法分派(dispatch)(而不仅仅是名称)。然而,名称被部分使用。所以以 Rolands 为例

> plot.myclass <- function(a, b, ...) 
>    print(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)
Error in print(b) (from #1) : argument "b" is missing, with no default

这是行不通的。可以看到 x 被正确地用于调度,但是 b 然后“丢失”了。我们也不能交换 ab:

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

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

> 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) ,它就像一个魅力。所以这是我的草率。

关于r - R中通用 `plot`函数的方法调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32222368/

相关文章:

r - 在 R 中使用 MODISTools 找不到函数 "validate_key"

performance - 为什么在 data.frame 中预先指定类型会更慢?

javascript - 我可以在 Javascript 中识别(绘图板)Pen Pressure 吗?

java - 读取图像时如何保持透明度不变? ( java )

ios - 如何只重绘一个特定的图层? (IOS,SWIFT)

r - 如何为时间序列中的缺失数据创建 "NA"

r - 将 YEARQT 格式的字符转换为 R 中的季度 "date"

java 泛型与使用 Class.forName() 动态加载类

java - 重写 super 方法时的 ClassCastException (Comparable<T>)

c# - C# 扩展方法中的泛型约束