【已解决】plot 函数的 xlab 和 ylab 的参数设置是否不一样
Cloud2016 只看明白了一点:确实是对 ylab 经过了特殊处理。xlab 和 ylab 确实待遇不一样。其他的我就看不懂了。
PS. ggplot 对方法 1 是支持的。
gg <- ggplot(anscombe) + geom_point(aes(x1, y1))
gg +
xlab(substitute(x[i], list(i = 1))) +
ylab(substitute(y[i], list(i = 1)))
gg +
xlab(as.expression(substitute(x[i], list(i = 1)))) +
ylab(as.expression(substitute(y[i], list(i = 1))))
我之前没好好注意这个问题,就是 plot 是一个泛型函数,对于不同的数据对象,它有不同的方法。我之前说 xlab 和 ylab 没什么不同是对 plot.default
说的,而在 plot.formula
中确实对 ylab 做了特别处理
methods(plot)
[1] plot.acf* plot.data.frame* plot.decomposed.ts*
[4] plot.default plot.dendrogram* plot.density*
[7] plot.ecdf plot.factor* plot.formula*
[10] plot.function plot.hclust* plot.histogram*
[13] plot.HoltWinters* plot.isoreg* plot.lm*
[16] plot.medpolish* plot.mlm* plot.ppr*
[19] plot.prcomp* plot.princomp* plot.profile.nls*
[22] plot.raster* plot.spec* plot.stepfun
[25] plot.stl* plot.table* plot.ts
[28] plot.tskernel* plot.TukeyHSD*
see '?methods' for accessing help and source code
Cloud2016 Base R 的源代码说实话不读也罢,它并不适合学习。在 plot.formula
中,我怀疑是这句 do.call
将 ylab
从 call 运行为实际值了:https://github.com/wch/r-source/blob/540cb48/src/library/graphics/R/plot.R#L207 因为 do.call()
默认不保护表达式。对比:
> do.call(c, list(a = substitute(cars[i, 1], list(i = 1)))) # 默认不保护
a
4
> do.call(c, list(a = substitute(cars[i, 1], list(i = 1))), quote = TRUE) # 保护表达式
$a
cars[1, 1]
quote()
/ enquote()
这些概念比较难理解,我至今也没完全搞明白,也没太大兴趣去深究。
yihui
关于 quote()
/ enquote()
,只知道 enquote()
是表达式再额外加个quote
, 例子如下:
> quote(AA(c(10.5, 15.2, 12.3))) # AA 未定义, 保护表达式
AA(c(10.5, 15.2, 12.3))
> enquote(call("AA", c(10.5, 15.2, 12.3))) # 进一步保护表达式?基本上没用过这块。
quote(AA(c(10.5, 15.2, 12.3)))
关于 quote()
和 call()
的区别,call()
不保护 arguments,比如:
> quote(round(BB)) ## BB未定义,保护所有表达式
round(BB)
> call("round", BB) ## 保护 "round", 不保护 BB
Error: object 'BB' not found
- 已编辑
Cloud2016 这个千年老漏洞在最新的 R 4.0.1中终于修正了:https://stat.ethz.ch/pipermail/r-announce/2020/000655.html
yihui 哇,07 年就有人提交了 BUG 报告。最近看到 Michael Chirico 把 BUG 报告同步到 Github 了 https://github.com/MichaelChirico/r-bugs 这无疑搜索起来很方便,减少重复提交 BUG 的工作