理解do.call语义基于" plot"

时间:2016-11-21 12:58:04

标签: r do.call

我和do.call鬼混。

I = iris
do.call(what = "plot", args = c(I$Sepal.Length ~ I$Sepal.Width))
# This seems fine

p = list(x = I$Sepal.Length, y = I$Sepal.Width)
do.call(what = "plot", args = p)
# This looks weird

p1 = list(x = I$Sepal.Length, y = I$Sepal.Width, xlab = "")
do.call(what = "plot", args = p1)
# A bit less weird


p2 = list(x = I$Sepal.Length, y = I$Sepal.Width, xlab = "", ylab = "")
do.call(what = "plot", args = p2)
# And this gives the same as the first do.call

那么为什么我必须提供轴标签来压制我在使用do.call时获得的所有数字?

2 个答案:

答案 0 :(得分:3)

首先,您需要了解plotS3 generic,它根据第一个参数调用方法。如果您执行plot(y ~ x)此方法为plot.formula,则根据公式推断轴标签。如果你plot(x, y)(注意x和y的不同顺序),方法是plot.default,轴标签是从作为参数传递的符号中推断出来的。

现在,如果您执行a <- 1:2; y <- 3:4; plot(x = a, y = b),标签为ab。但是,如果您使用do.call魔法,则do.call(plot, list(x = a, y = b)会扩展为plot(x = 1:2, y = 3:4),因此标签为1:23:4。我建议将公式方法与data参数一起使用,例如:

do.call(what = "plot", args = list(formula = Sepal.Length ~ Sepal.Width,
                                   data = I))

答案 1 :(得分:1)

当你无法从参数中获取任何其他命名信息时,你看到的是什么是R放在轴标签上。如果你这样做:

plot(x=c(1,2,3,4,5,6,7,8),y=c(1,2,3,4,3,2,3,4))

然后绘图必须使用矢量值作为轴标签。

使用do.call时,list参数中的名称与所调用函数的参数名称匹配。因此,轴标签没有剩下的名称,只有值。那时数据来自I$Sepal.width的事实早已不复存在,它只是一个值向量。