R分配ggplot对象以循环列出 [英] R assigning ggplot objects to list in loop

查看:164
本文介绍了R分配ggplot对象以循环列出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 for循环将ggplots分配给 list ,然后传递给 plot_grid()(包 cowplot )。 plot_grid 将多个ggplots并排放置在一个图中。这可以很好地工作,但是当我使用 for循环时,生成的最后一个图在图的每个子帧中重复(如下所示)。换句话说,所有子帧都显示相同的ggplot。



这是一个玩具的例子:

pre > require(cowplot)

dfrm < - data.frame(A = 1:10,B = 10:1)

v < - c(A,B)
dfmsize< - nrow(dfrm)
myplots< - vector(list,2)

count = 1 $ (i,v){
myplots [[count]] < - ggplot(dfrm,aes(x = 1:dfmsize,y = dfrm [,i]))+ geom_point()+ labs (y = i)
count = count +1

plot_grid(plotlist = myplots)

预计数字:



来自 for循环的图:



p>

我尝试转换列表el如此,像这样:

  mygrobs<  -  lapply(myplots,ggplotGrob )
plot_grid(plotlist = mygrobs)

但是我得到了同样的结果。



我认为问题在于循环分配,而不是 plot_grid(),但我看不到我是什么做错了。

解决方案

到目前为止,答案非常接近,但在我看来并不令人满意。问题在于以下 - 在您的 for 循环之后:

  myplots [ [1]] $ mapping 
#* x - > 1:dfmsize
#* y - > dfrm [,i]
myplots [[1]] $ plot_env
#< environment:R_GlobalEnv>

myplots [[2]] $ mapping
#* x - > 1:dfmsize
#* y - > dfrm [,i]
myplots [[2]] $ plot_env
#< environment:R_GlobalEnv>

i
#[1]B

其他答案中提到, ggplot 在绘图之前并不实际评估这些表达式,因为这些都在全局环境中,并且 i B,您会收到不理想的结果。

避免这个问题,其中最简单的实际上简化了你的表达式:

  myplots = lapply(v,function(col)
ggplot(dfrm,aes(x = 1:dfmsize,y = dfrm [,col]))+ geom_point()+ labs(y = col))

这个原因起作用的原因是,对于 lapply 不同的

  myplots [[1]] $ mapping 
#* x - > 1:dfmsize
#* y - > dfrm [,col]
myplots [[1]] $ plot_env
#< environment:0x000000000bc27b58>

myplots [[2]] $ mapping
#* x - > 1:dfmsize
#* y - > dfrm [,col]
myplots [[2]] $ plot_env
#< environment:0x000000000af2ef40>

eval(quote(dfrm [,col]),env = myplots [[1]] $ plot_env)
#[1] 1 2 3 4 5 6 7 8 9 10
eval(quote(dfrm [,col]),env = myplots [[2]] $ plot_env)
#[1] 10 9 8 7 6 5 4 3 2 1

所以即使表达式相同,结果也是不同的。



如果您想知道存储/复制到 lapply 环境的具体内容 - 毫不奇怪,它只是列名称:

  ls(myplots [[1]] $ plot_env)
#[1]col


I'm using a for loop to assign ggplots to a list, which is then passed to plot_grid() (package cowplot). plot_grid places multiple ggplots side by side in a single figure. This works fine manually, but when I use a for loop, the last plot generated is repeated in each subframe of the figure (shown below). In other words, all the subframes show the same ggplot.

Here is a toy example:

require(cowplot)

dfrm <- data.frame(A=1:10, B=10:1)

v <- c("A","B")
dfmsize <- nrow(dfrm)
myplots <- vector("list",2)

count = 1
for(i in v){
    myplots[[count]] <- ggplot(dfrm, aes(x=1:dfmsize, y=dfrm[,i])) + geom_point() + labs(y=i)
    count = count +1
}
plot_grid(plotlist=myplots)

Expected Figure:

Figure from for loop:

I tried converting the list elements to grobs, as described in this question, like this:

mygrobs <- lapply(myplots, ggplotGrob)
plot_grid(plotlist=mygrobs)

But I got the same result.

I think the problem lies in the loop assignment, not plot_grid(), but I can't see what I'm doing wrong.

解决方案

The answers so far are very close, but unsatisfactory in my opinion. The problem is the following - after your for loop:

myplots[[1]]$mapping
#* x -> 1:dfmsize
#* y -> dfrm[, i]
myplots[[1]]$plot_env
#<environment: R_GlobalEnv>

myplots[[2]]$mapping
#* x -> 1:dfmsize
#* y -> dfrm[, i]
myplots[[2]]$plot_env
#<environment: R_GlobalEnv>

i
#[1] "B"

As the other answers mention, ggplot doesn't actually evaluate those expressions until plotting, and since these are all in the global environment, and the value of i is "B", you get the undesirable results.

There are several ways of avoiding this issue, the simplest of which in fact simplifies your expressions:

myplots = lapply(v, function(col)
            ggplot(dfrm, aes(x=1:dfmsize, y=dfrm[,col])) + geom_point() + labs(y=col))

The reason this works, is because the environment is different for each of the values in the lapply loop:

myplots[[1]]$mapping
#* x -> 1:dfmsize
#* y -> dfrm[, col]
myplots[[1]]$plot_env
#<environment: 0x000000000bc27b58>

myplots[[2]]$mapping
#* x -> 1:dfmsize
#* y -> dfrm[, col]
myplots[[2]]$plot_env
#<environment: 0x000000000af2ef40>

eval(quote(dfrm[, col]), env = myplots[[1]]$plot_env)
#[1]  1  2  3  4  5  6  7  8  9 10
eval(quote(dfrm[, col]), env = myplots[[2]]$plot_env)
#[1] 10  9  8  7  6  5  4  3  2  1

So even though the expressions are the same, the results are different.

And in case you're wondering what exactly is stored/copied to the environment of lapply - unsurprisingly it's just the column name:

ls(myplots[[1]]$plot_env)
#[1] "col"

这篇关于R分配ggplot对象以循环列出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆