gpt4 book ai didi

r - R将ggplot对象分配给循环列表

转载 作者:行者123 更新时间:2023-12-01 09:17:16 25 4
gpt4 key购买 nike

我正在使用for loop将ggplots分配给list,然后将其传递给plot_grid()(包cowplot)。 plot_grid在单个图形中并排放置多个ggplots。手动可以很好地工作,但是当我使用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)

预期图:

enter image description here

来自 for loop的图:

enter image description here

我尝试将列表元素转换为grobs,如 question所述,如下所示:
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"

关于r - R将ggplot对象分配给循环列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39799886/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com