R分配ggplot对象以循环列出 [英] R assigning ggplot objects to list in loop
问题描述
我使用 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 $ c中的每个值,环境都是不同的
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
$ c
所以即使表达式相同,结果也是不同的。
如果您想知道存储/复制到 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屋!