循环中多个图的列表(ggplot2)- 列表元素被覆盖

6

目标:编写一个循环,使我能够绘制多个地图,在其中显示网格单元的密度数据(D),覆盖多个月份和季节。每个月、季节等的数据都在8个单独的列中;循环将遍历数据框(DF)的列。

尝试过:将每次循环迭代的图形添加到列表中,以便可以调用所有图形以显示在多面板图形中。

out <- NULL
 for(i in 1:8){

  D <- DF[,i]
  x <- names(DF)[i]

  p <-ggplot() + geom_polygon(data=DF, aes(x=long, y=lat, group=Name, fill=D), colour    = "lightgrey") +labs(title=x)

out[[i]]<- p

print(p)

}

问题:尽管print(p)在每次迭代中产生了正确的图形,但列表out中的图形仅显示最后一次循环的数据。
因此,当我尝试使用grid.arrange与“out”中的图形时,所有图形都显示相同的数据(来自第8列); 但是,这些绘图确实保留了正确的标题。 当我尝试调用每个图 - 例如,print(out [[1]]),显示与print(out [[8]])相同的图 - 除了标题标签外。
似乎先前列表中的元素正在被每次循环覆盖? 但是,这些图的标题似乎显示正确。
我的out列表构造是否存在明显错误? 如何避免覆盖每个先前的图?

你尝试过不使用out[[i]]<- pprint(p),也不分配p吗? - Rich Scriven
4
我建议你使用 aes_string,但在我看来更好的方法是将数据从宽格式转换为长格式,使用melt()函数。 - baptiste
1个回答

12
问题不在于每个项目都被覆盖,而是ggplot()等待打印图表才能解析aes()命令中的变量。循环正在将所有fill=参数分配给D。并且D的值在每次循环中都会更改。但是,在循环结束时,D只会保留最后一个值。因此,列表中的每个图形都将以相同的着色打印。
这也会产生相同的问题。
require(ggplot2)

#sample data
dd<-data.frame(x=1:10, y=runif(10), g1=sample(letters[1:2], 10, replace=T), g2=sample(letters[3:4], 10, replace=T))

plots<-list()
g<-dd$g1
plots[[1]]<-ggplot(data=dd, aes(x=x, y=y, color=g)) + geom_point()

g<-dd$g2
plots[[2]]<-ggplot(data=dd, aes(x=x, y=y, color=g)) + geom_point()

#both will print with the same groups.
print(plots[[1]])
print(plots[[2]])

解决这个问题的一种方法(正如 @baptiste 也提到的)是使用 aes_string()。这样可以更快地解析变量的值,因此应该有效。

plots<-list()
g<-"g1"
plots[[1]]<-ggplot(data=dd, aes(x=x, y=y)) + geom_point(aes_string(color=g))
g<-"g2"
plots[[2]]<-ggplot(data=dd, aes(x=x, y=y)) + geom_point(aes_string(color=g))

#different groupings (as desired)
print(plots[[1]])
print(plots[[2]])

这与 aes() 函数最直接相关,因此您设置标题的方式非常好,这就是为什么您会看到不同的标题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接