在R中按值传递

时间:2011-08-12 14:02:09

标签: r ggplot2

当试图调用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的情节。谁能解释一下?

3 个答案:

答案 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))

它产生了这个丑陋的情节: enter image description here


我知道,如果不了解你的目标,尝试提供建议是危险的。但是,你有没有考虑过为你的情节使用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")

enter image description here

答案 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))

enter image description here

HTH