当试图调用grid.arrange将多个图放在同一个ggplot2图上时,我首先构建一个我想要的图表列表。然后我构建相应的参数列表来调用grid.arrange,如解释in a previous question所述。这是我的代码(我的数据框称为操作):
args.list <- NULL;
plot.list <- NULL;
for (m in names(manip[2:10])) {
plot.list <- c(plot.list, list(qplot(manip$side, y=manip[,m],ylab=m))
}
args.list <- c(plot.list, 1, 9)
names(args.list) <- c(names(manip)[2:10], list("nrow","ncol"))
do.call(grid.arrange, args.list)
这是有效的,除了9个图表完全相同!检查后,结果表明数据始终是与m=10
对应的数据。所以我的猜测是m
的值没有在循环中分配,而是稍后评估。但是,标签ylab=m
是正确分配的,并且所有图表都不同。
因此,我并没有真正了解差异是什么以及解释器如何选择何时评估m的情节。谁能解释一下?
答案 0 :(得分:4)
这种行为是由于R的懒惰评估。
这是一个最小的(?)示例:
d <- 1:3
args.list <- NULL;
plot.list <- NULL;
for (m in 1:3) {
plot.list <- c(plot.list, list(qplot(d[m], d[m], ylab=letters[m])))
}
args.list <- c(plot.list, nrow=1, ncol=3)
do.call(grid.arrange, args.list)
在这种情况下,d[m]
会在do.call
的调用时进行评估。所有小组m
为3。
这是一个解决方法:
d <- 1:3
args.list <- NULL;
plot.list <- NULL;
for (m in 1:3) {
plot.list <- c(plot.list,
list(qplot(d, d, data=data.frame(d=d[m]), ylab=letters[m])))
}
args.list <- c(plot.list, nrow=1, ncol=3)
do.call(grid.arrange, args.list)
在这种情况下,d[m]
在qplot
的调用下进行评估,d[m]
存储在qplot的输出对象中。
所以,简单的解决方案是将数据传递给qplot()
或ggplot()
。
答案 1 :(得分:3)
我将首先回答您的问题,然后使用分面图显示替代方案。
<强>被修改强>
以下简化的代码似乎有效:
library(gridExtra)
manip <- mtcars
plot.list <- lapply(2:11,
function(x)qplot(manip$mpg, y=manip[, x],
ylab=names(manip)[x]))
do.call(grid.arrange, c(plot.list, nrow=10))
它产生了这个丑陋的情节:
我知道,如果不了解你的目标,尝试提供建议是危险的。但是,你有没有考虑过为你的情节使用facet?
以下代码更简单,执行quiker并生成更易于理解的图表:
library(reshape2)
manip <- mtcars
mmanip <- melt(manip, id.vars="mpg")
str(mmanip)
ggplot(mmanip, aes(x=mpg, y=value)) +
geom_point(stat="identity") +
facet_grid(.~variable, scales="free")
答案 2 :(得分:2)
也许最好是融合数据并使用分面?
library(ggplot2)
manip <- data.frame(car = row.names(mtcars), mtcars)
manip.m <- melt(manip)
qplot(car, value, data = manip.m) + facet_wrap(~variable, scales = "free_y")
需要在xlab中进行一些抛光
last_plot() + opts(axis.text.x = theme_text(angle = 90))
HTH