问题 使用“数据”和“公式”关键字参数时,为什么订单很重要?


[R,为什么是顺序呢 data 和 formula 关键词在绘图时很重要?我以为 命名参数 订购  应该重要......

有关我的意思的示例,请查看此代码:

library(MASS)
data(menarche)

# Correct formulation (apparently):
plot(formula=Menarche/Total ~ Age, data=menarche)

# In contrast, note how the following returns an error:
plot(data=menarche, formula=Menarche/Total ~ Age)  

这只是一个怪癖 plot 功能还是这种行为也表现在其他功能中?


11396
2017-07-22 17:24


起源

graphics:::plot.default(data=menarche, formula=Menarche/Total ~ Age) VS graphics:::plot.formula(data=menarche, formula=Menarche/Total ~ Age) - rawr
@rawr对;它是S3调度处理参数并调度到不同的方法而不是导致错误的顺序。但是,第一个应该是 graphics:::plot.data.frame 如 traceback() 显示实际被调用的是这个方法。 - Gavin Simpson


答案:


它与S3泛型的S3方法有关 plot()。 S3基于第一个参数调度方法,但是确切的功能是复杂的,因为 formula 允许作为通常的泛型参数的特殊例外 plot(), 哪个是 x 和 y 加 ...

> args(plot)
function (x, y, ...) 
NULL

因此,在第一种情况下发生的是 plot.formula() 运行方法,因为提供的第一个参数是一个公式,并且匹配参数 plot.formula()

> args(graphics:::plot.formula)
function (formula, data = parent.frame(), ..., subset, ylab = varnames[response], 
    ask = dev.interactive()) 
NULL

例如:

> debugonce(graphics:::plot.formula)
> plot(formula=Menarche/Total ~ Age, data=menarche)
debugging in: plot.formula(formula = Menarche/Total ~ Age, data = menarche)
debug: {
    m <- match.call(expand.dots = FALSE)
[...omitted...]

相反,当你打电话 plot(data=menarche, formula=Menarche/Total ~ Age),第一个参数是数据框,因此是 graphics:::plot.data.frame 方法被称为:

> plot(data=menarche, formula=Menarche/Total ~ Age)
Error in is.data.frame(x) : argument "x" is missing, with no default
> traceback()
3: is.data.frame(x)
2: plot.data.frame(data = menarche, formula = Menarche/Total ~ Age)
1: plot(data = menarche, formula = Menarche/Total ~ Age)

但是因为那个方法需要一个参数 x,你没有提供,你得到关于失踪的错误 x

所以从某种意义上说,命名参数的排序不会也不应该重要,但是当S3泛型处于播放方法中时,调度首先决定将哪个方法传递给参数,然后提供参数 - 而不是排序 - 是什么经常会让你失望,特别是在混合时 formula 方法与其他非formula 方法。


11
2017-07-22 17:34



+1。我不知道你怎么能这么快就做到这一切。事实上,它让我想知道我是如何浪费这么多时间寻找答案的。现在,如果你原谅我,我必须处理所有这些...... - Steve S
@JoshO'Brien正在打电话 plot()  - > plot.formula()  - > plot.default();这似乎解释了 HERRINGS 作为传球 Total 至 x 和 Age 至 y 因此你得到一个实际的情节然后 HERRINGS 作为公式保留在呼叫中,因此多次警告。为了准确了解发生了什么,我们必须研究这些步骤 plot.formula 看看它是如何解释公式或只是从中提取数据 data = menarche。 - Gavin Simpson
@GavinSimpson - 知道了,谢谢。事情发生了变化 plot.formula()的号召 stats::model.frame.default, - 没有任何公式来指导它 - 只返回一个带有“Age”,“Total”和“Menarche”列的模型框架。 (同 引导它的公式参数,它将产生一个两列模型框架,其中包含“Menarche / Total”和“Age”列。稍后的, plot.formula() 提取模型框架的第一列 mf把它传递给 plot.default()的 y 参数和模型框架的其余部分 x 论据。 - Josh O'Brien
(为了记录,在一条已删除的评论中,我曾问过Gavin他是否知道为什么要打电话 plot(HERRINGS=Menarche/Total ~ Age, data=menarche) 给出它的结果。) - Josh O'Brien
+1 @ JoshO'Brien这是我认为可能发生的变量分配方式 x 和 y,但我没有机会亲自检查,因为午餐非常叫我:-) - Gavin Simpson