将ggplot对象存储在R中的循环内的列表中 [英] Storing ggplot objects in a list from within loop in R

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

问题描述

我的问题类似于这一个 ;当我在循环中生成绘图对象(在这种情况下是直方图)时,似乎它们都被最近的绘图覆盖。

为了在循环中进行调试,我打印了索引和生成的图,两者都正确显示。但是,当我查看存储在列表中的图表时,它们与标签完全相同。



(我使用多重分割来制作合成图像,但是如果您使用 print(myplots [[1]]) / code>
print(myplots [[4]])一次一个。)

因为我已经有了一个附加的数据框(与类似问题的海报不同),我不知道如何解决这个问题。

(btw,column类是我在这里近似的原始数据集中的因子,但是如果它们是整数,则会出现同样的问题)

这是一个可重现的示例:

  library(ggplot2)
source(http://peterhaschke.com/Code/multiplot.R)#load多点函数

#制作采样数据
col1 <-c(2,4,1,2,5,1,2,0,1, 3,6,5,3,6,4,3,4,4,3,4,
2,图4,3,3,5,3,5,5,0,0,3,3, 6,5,4,4,1,3,3,2,0,5,3,6,6,2,3,
3分配,1,5,3,4,6)
(2,4,4,4,4,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,25,25,27,27,28,29,31,33,34,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,36,36,36,39,31,32,34,35,35,36,38,39, 6,4,4,2,4,4,4,
1,1,2,2,3,3,5,0,3,4,2,4,5,5,4,4, 2,3,5,2,6,5,2,4,6,3,3,
3分配,1,4-,3,5,4)
COL3< - C(2, 5,4,1,4,2,3,0,1,3,4,2,5,1,4-,3,4,6,3,4,6,4,1,3,5,4, 3,
2,1,3,2,2,2,4,0,1,4,4,3,5,3,2,5,2,3,3,4,2,4, 2,4,5,1,3,
3分配,3,4,3,5,4)
COL4< - C(2,5,2,1,4,1,3, 4,1,3,5,2,4,3,5,3,4,6,3,4,6,4,3,2,5,5,4,
2,3,2, 2,3,3,4,0,1,4,3,3,5,4,4,4,3,3,5,4,3,5,3,6,6,4,2,
3,3,4,4,4,6)
data2 < - data.frame(col1,col2,col3,col4)
data2 [,1:4]< - lapply (A,B,C,D)

# (数据=数据帧(数据2),aes)生成绘图
myplots< - list()#新的空列表
(X = data2的[,I]))+
geom_histogram(填充= 浅绿)+
xlab(colnames(DATA2)[I])
print(i)
print(p1)
myplots [[i]]< - p1#将每个绘图添加到绘图列表
}
多图(plotlist = my plot,cols = 4)

当我查看绘图列表中的绘图对象的摘要时,这是我所看到的

 >总结(myplots [[1]])
data:A,B,C,D [60x4]
映射:x = data2 [,i]
faceting:facet_null()
-----------------------------------
geom_histogram:fill = lightgreen
stat_bin :
position_stack:(width = NULL,height = NULL)

我认为映射:x = data2 [,i] 是问题,但我很难过!我无法发布图片,因此如果我对问题的解释令人困惑,则需要运行我的示例并查看图表。



谢谢!

解决方案

除了其他优秀的答案外,这里还有一个解决方案,它使用正常评估而不是 eval 。由于循环没有独立的变量范围(即它们在目前的环境中进行),我们需要使用本地来将包装为块;此外,我们需要让的局部变量 - 我们可以通过简单地重新分配给它做的:



<$ ($ 1 $ 4)
本地({
i < - $ $ c> myplots< - list()#新空列表
$ b p1 < - ggplot(data = data.frame(data2),aes(x = data2 [,i]))+
geom_histogram(fill =lightgreen)+
xlab(colnames(数据2)[i])
print(i)
print(p1)
myplots [[i]] <-p1#将每个绘图添加到绘图列表
} )

然而,完全干净的方法是放弃 c $ c>完全循环,并使用列表函数来创建结果。这有几种可能的方式。以下是我认为最简单的方法:

$ $ $ $ $ $ $ c $ plot_data_column = function(data,column)
ggplot(data = data2 ,aes_string(x = column))+
geom_histogram(fill =lightgreen)+
xlab(column)

myplots< - lapply(colnames(data2),plot_data_column ,data = data2)

这有很多优点:它更简单并且不会混乱环境循环变量 i )。


My problem is similar to this one; when I generate plot objects (in this case histograms) in a loop, seems that all of them become overwritten by the most recent plot.

To debug, within the loop, I am printing the index and the generated plot, both of which appear correctly. But when I look at the plots stored in the list, they are all identical except for the label.

(I'm using multiplot to make a composite image, but you get same outcome if you print (myplots[[1]]) through print(myplots[[4]]) one at a time.)

Because I already have an attached dataframe (unlike the poster of the similar problem), I am not sure how to solve the problem.

(btw, column classes are factor in the original dataset I am approximating here, but same problem occurs if they are integer)

Here is a reproducible example:

library(ggplot2)
source("http://peterhaschke.com/Code/multiplot.R") #load multiplot function

#make sample data
col1 <- c(2, 4, 1, 2, 5, 1, 2, 0, 1, 4, 4, 3, 5, 2, 4, 3, 3, 6, 5, 3, 6, 4, 3, 4, 4, 3, 4, 
          2, 4, 3, 3, 5, 3, 5, 5, 0, 0, 3, 3, 6, 5, 4, 4, 1, 3, 3, 2, 0, 5, 3, 6, 6, 2, 3, 
          3, 1, 5, 3, 4, 6)
col2 <- c(2, 4, 4, 0, 4, 4, 4, 4, 1, 4, 4, 3, 5, 0, 4, 5, 3, 6, 5, 3, 6, 4, 4, 2, 4, 4, 4, 
          1, 1, 2, 2, 3, 3, 5, 0, 3, 4, 2, 4, 5, 5, 4, 4, 2, 3, 5, 2, 6, 5, 2, 4, 6, 3, 3, 
          3, 1, 4, 3, 5, 4)
col3 <- c(2, 5, 4, 1, 4, 2, 3, 0, 1, 3, 4, 2, 5, 1, 4, 3, 4, 6, 3, 4, 6, 4, 1, 3, 5, 4, 3, 
          2, 1, 3, 2, 2, 2, 4, 0, 1, 4, 4, 3, 5, 3, 2, 5, 2, 3, 3, 4, 2, 4, 2, 4, 5, 1, 3, 
          3, 3, 4, 3, 5, 4)
col4 <- c(2, 5, 2, 1, 4, 1, 3, 4, 1, 3, 5, 2, 4, 3, 5, 3, 4, 6, 3, 4, 6, 4, 3, 2, 5, 5, 4,
          2, 3, 2, 2, 3, 3, 4, 0, 1, 4, 3, 3, 5, 4, 4, 4, 3, 3, 5, 4, 3, 5, 3, 6, 6, 4, 2, 
          3, 3, 4, 4, 4, 6)
data2 <- data.frame(col1,col2,col3,col4)
data2[,1:4] <- lapply(data2[,1:4], as.factor)
colnames(data2)<- c("A","B","C", "D")

#generate plots
myplots <- list()  # new empty list
for (i in 1:4) {
  p1 <- ggplot(data=data.frame(data2),aes(x=data2[ ,i]))+ 
    geom_histogram(fill="lightgreen") +
    xlab(colnames(data2)[ i])
  print(i)
  print(p1)
  myplots[[i]] <- p1  # add each plot into plot list
}
multiplot(plotlist = myplots, cols = 4)

When I look at a summary of a plot object in the plot list, this is what I see

> summary(myplots[[1]])
data: A, B, C, D [60x4]
mapping:  x = data2[, i]
faceting: facet_null() 
-----------------------------------
geom_histogram: fill = lightgreen 
stat_bin:  
position_stack: (width = NULL, height = NULL)

I think that mapping: x = data2[, i] is the problem, but I am stumped! I can't post images, so you'll need to run my example and look at the graphs if my explanation of the problem is confusing.

Thanks!

解决方案

In addition to the other excellent answer, here’s a solution that uses "normal"-looking evaluation rather than eval. Since for loops have no separate variable scope (i.e. they are performed in the current environment) we need to use local to wrap the for block; in addition, we need to make i a local variable — which we can do by simply re-assigning it:

myplots <- list()  # new empty list
for (i in 1:4)
    local({
        i <- i
        p1 <- ggplot(data=data.frame(data2),aes(x=data2[ ,i]))+ 
            geom_histogram(fill="lightgreen") +
            xlab(colnames(data2)[ i])
        print(i)
        print(p1)
        myplots[[i]] <<- p1  # add each plot into plot list
    })

However, an altogether cleaner way is to forego the for loop entirely and use list functions to build the result. This works in several possible ways. The following is the easiest in my opinion:

plot_data_column = function (data, column)
    ggplot(data = data2, aes_string(x = column)) +
        geom_histogram(fill = "lightgreen") +
        xlab(column)

myplots <- lapply(colnames(data2), plot_data_column, data = data2)

This has numerous advantages: it’s simpler and it won’t clutter the environment (with the loop variable i).

这篇关于将ggplot对象存储在R中的循环内的列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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