- 已编辑
dapengde 我发现点什么东西了
- 正确的做法是将 call 类型强制转化为 expression 类型,虽然它们看起来好像一样
plot(y1 ~ x1,
data = anscombe,
xlab = as.expression(substitute(x[i], list(i = 1))),
ylab = as.expression(substitute(y[i], list(i = 1)))
)
xsub <- substitute(x[i], list(i = 1))
xsub
x[1]
class(xsub)
[1] "call"
is.expression(xsub)
[1] FALSE
?substitute
这个地方好像切入 R 比较高深的内容了,参考了 <https://adv-r.hadley.nz/environments.html> 目前似懂非懂状态。
我之前一直以为 substitute
返回一个表达式类型,因为 print
的结果看起来一样,其实是错的,应该要 is.expression
判断一下,人眼不好使!!
as.expression
attempts to coerce its argument into an expression object. It is generic, and only the default method is described here. (The default method callsas.vector(type = "expression")
and so may dispatch methods for as.vector.)NULL
,calls
,symbols
(seeas.symbol
) andpairlists
are returned as the element of a length-one expression vector. Atomic vectors are placed element-by-element into an expression vector (without using any names): lists are changed type to an expression vector (keeping all attributes). Other types are not currently supported.
以方法1为例,最后一个疑问:返回的 call 对象怎么找的 8.04,其调用栈是怎么运行的?
substitute
works on a purely lexical basis. There is no guarantee that the resulting expression makes any sense.
不知这句话是否对回答这个疑问有意义
- latex2exp 或者调用 tikzDevice 包,我倒是也知道,只是这里不想把问题避开,觉着应该有直接的办法
- 这里要开始一点题外话,我最初是翻数据集 anscombe 的帮助文档
help(anscombe)
,在文档最后说我有一个魔法可以在一个 for 循环内完成四个线性回归(我看好久没看明白魔法的优雅之处,遂动手实现一个,毕竟批量地跑模型似乎有点用)
我的优雅版本是这样的,完全没有魔法##-- now some "magic" to do the 4 regressions in a loop: ff <- y ~ x mods <- setNames(as.list(1:4), paste0("lm", 1:4)) for(i in 1:4) { ff[2:3] <- lapply(paste0(c("y","x"), i), as.name) ## or ff[[2]] <- as.name(paste0("y", i)) ## ff[[3]] <- as.name(paste0("x", i)) mods[[i]] <- lmi <- lm(ff, data = anscombe) print(anova(lmi)) } ## See how close they are (numerically!) sapply(mods, coef) lapply(mods, function(fm) coef(summary(fm))) ## Now, do what you should have done in the first place: PLOTS op <- par(mfrow = c(2, 2), mar = 0.1+c(4,4,1,1), oma = c(0, 0, 2, 0)) for(i in 1:4) { ff[2:3] <- lapply(paste0(c("y","x"), i), as.name) plot(ff, data = anscombe, col = "red", pch = 21, bg = "orange", cex = 1.2, xlim = c(3, 19), ylim = c(3, 13)) abline(mods[[i]], col = "blue") } mtext("Anscombe's 4 Regression data sets", outer = TRUE, cex = 1.5) par(op)
data(anscombe) form <- paste(paste0("y", seq(4)), paste0("x", seq(4)), sep = "~") fit <- lapply(form, lm, data = anscombe) op <- par(mfrow = c(2, 2), mar = 0.1 + c(4, 4, 1, 1), oma = c(0, 0, 2, 0)) for (i in seq(4)) { plot(as.formula(form[i]), data = anscombe, col = hcl.colors(11), pch = 19, cex = 1.2, xlim = c(3, 19), ylim = c(3, 13), xlab = as.expression(substitute(x[i], list(i = i))), ylab = as.expression(substitute(y[i], list(i = i))) ) abline(fit[[i]], col = "red", lwd = 2) } mtext("Anscombe's 4 Regression data sets", outer = TRUE, cex = 1.5) par(op)