【问题标题】:Why does order matter when using "data" and "formula" keyword arguments?为什么使用“数据”和“公式”关键字参数时顺序很重要?
【发布时间】:2014-09-13 15:46:26
【问题描述】:

R中,为什么dataformula关键字的顺序在绘图时很重要?我认为对于 命名参数,顺序 应该很重要......

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

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 函数的一个怪癖,还是其他函数也有这种行为?

【问题讨论】:

  • graphics:::plot.default(data=menarche, formula=Menarche/Total ~ Age)graphics:::plot.formula(data=menarche, formula=Menarche/Total ~ Age)
  • @rawr 对;是 S3 分派处理参数并分派到不同的方法,而不是导致错误的顺序。但是,第一个应该是 graphics:::plot.data.frame,因为 traceback() 表明实际调用的是这个方法。

标签: r plot arguments


【解决方案1】:

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

> 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 方法混合时。

【讨论】:

  • +1。我不知道你怎么能这么快就做完这一切。事实上,这让我想知道我最初是如何浪费这么多时间寻找答案的。现在,请原谅我,我必须处理所有这些......
  • @JoshO'Brien 它正在调用plot() -> plot.formula() -> plot.default();这似乎将HERRINGS 解释为将Total 传递给xAge 传递给y,因此你得到一个实际的情节,然后HERRINGS 作为公式保留在调用中,因此会出现多个警告。要准确了解发生了什么,我们必须研究plot.formula 中的步骤,看看它是如何解释公式的,或者只是从data = menarche 中提取数据。
  • @GavinSimpson - 明白了,谢谢。在plot.formula()stats::model.frame.default 的调用中,事情偏离了轨道——没有任何公式来指导它——只返回一个模型框架,其中包含“年龄”、“总”和“月经初潮”列。 (使用一个公式参数来指导它,它会产生一个两列模型框架,其中包含列“Menarche/Total”和“Age”)。稍后,plot.formula() 提取模型框架mf 的第一列,将其传递给plot.default()y 参数,并将模型框架的其余部分传递给x 参数。
  • (作为记录,在一条已删除的评论中,我曾问 Gavin 他是否知道为什么调用 plot(HERRINGS=Menarche/Total ~ Age, data=menarche) 会得到这样的结果。)
  • +1 @JoshO'Brien 考虑到变量被分配给xy 的方式,我认为这可能会发生,但我没有机会自己检查它午餐非常喜欢我:-)
猜你喜欢
  • 2020-11-22
  • 1970-01-01
  • 2013-05-18
  • 1970-01-01
  • 2019-05-25
  • 1970-01-01
  • 2015-03-10
  • 2022-01-06
相关资源
最近更新 更多