som*_*hat 2 loops r ggplot2 cowplot
我正在使用 afor loop将 ggplots 分配给 a list,然后将其传递给plot_grid()(package cowplot)。plot_grid将多个 ggplots 并排放置在一个图中。这手动工作正常,但是当我使用 a 时for loop,生成的最后一个图在图的每个子帧中重复(如下所示)。换句话说,所有子帧都显示相同的 ggplot。
这是一个玩具示例:
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)
Run Code Online (Sandbox Code Playgroud)
预期图:
图自for loop:
我尝试将列表元素转换为 grobs,如本问题所述,如下所示:
mygrobs <- lapply(myplots, ggplotGrob)
plot_grid(plotlist=mygrobs)
Run Code Online (Sandbox Code Playgroud)
但我得到了同样的结果。
我认为问题在于循环分配,而不是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"
Run Code Online (Sandbox Code Playgroud)
正如其他答案所提到的,ggplot在绘图之前实际上不会评估这些表达式,并且由于这些都在全局环境中,并且iis的值"B",您会得到不想要的结果。
有几种方法可以避免这个问题,其中最简单的方法实际上可以简化您的表达式:
myplots = lapply(v, function(col)
ggplot(dfrm, aes(x=1:dfmsize, y=dfrm[,col])) + geom_point() + labs(y=col))
Run Code Online (Sandbox Code Playgroud)
这样做的原因是因为循环中每个值的环境都不同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
Run Code Online (Sandbox Code Playgroud)
所以即使表达相同,结果也不同。
如果您想知道究竟是什么存储/复制到环境中lapply- 不出所料,它只是列名:
ls(myplots[[1]]$plot_env)
#[1] "col"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3986 次 |
| 最近记录: |