2015-08-13 108 views
1

在下面的可重现示例中,我尝试为ggplot分布图创建函数并将其保存为R对象,目的是在网格中显示两个图。R ggplot2将绘图保存为R对象并在网格中显示

ggplothist<- function(dat,var1) 
{ 
     if (is.character(var1)) { 
      var1 <- which(names(dat) == var1) 
    } 
    distribution <- ggplot(data=dat, aes(dat[,var1])) 
    distribution <- distribution + geom_histogram(aes(y=..density..),binwidth=0.1,colour="black", fill="white") 
    output<-list(distribution,var1,dat) 
    return(output) 
} 

电话功能:

set.seed(100) 
df <- data.frame(x = rnorm(100, mean=10),y =rep(1,100))  
output1 <- ggplothist(dat=df,var1='x') 
output1[1] 

enter image description here

一切都很好,直到如今。

那我要进行第二次的情节,(注:平均= 100,而不是以前的10)

df2 <- data.frame(x = rep(1,1000),y = rnorm(1000, mean=100))  
output2 <- ggplothist(dat=df2,var1='y') 
output2[1] 

enter image description here

然后我试图重新绘制第一分布平均10

output1[1] 

enter image description here

我得到的SAM像以前一样分配? 但是,如果我使用函数中包含的信息,请将其返回并将其重置为其工作的全局变量。

var1=as.numeric(output1[2]);dat=as.data.frame(output1[3]);p1 <- output1[1] 
p1 

enter image description here

如果任何人都可以解释为什么出现这种情况,我想知道。看起来,为了绘制预期的分布,我必须将data.frame和variable重置为绘制图的内容。有没有办法将剧情保存为一个对象而不必这样做。幸运的是,我可以重新绘制第一个发行版。

,但我不能在同一时间

var1=as.numeric(output2[2]);dat=as.data.frame(output2[3]);p2 <- output2[1] 
grid.arrange(p1,p2) 

ERROR: Error in gList(list(list(data = list(x = c(9.66707664902549, 11.3631137069225, : only 'grobs' allowed in "gList"

在这个“Grid of multiple ggplot2 plots which have been made in a for loop”的答案画出他们都建议使用一个列表包含地块

ggplothist<- function(dat,var1) 
{ 
    if (is.character(var1)) { 
      var1 <- which(names(dat) == var1) 
    } 
    distribution <- ggplot(data=dat, aes(dat[,var1])) 
    distribution <- distribution + geom_histogram(aes(y=..density..),binwidth=0.1,colour="black", fill="white") 
    plot(distribution) 
    pltlist <- list() 
    pltlist[["plot"]] <- distribution 
    output<-list(pltlist,var1,dat) 
    return(output) 
} 

output1 <- ggplothist(dat=df,var1='x') 
p1<-output1[1] 

output2 <- ggplothist(dat=df2,var1='y') 
p2<-output2[1] 

output1[1] 

威尔再次产生均值= 100的分布而不是均值= 10 和:

grid.arrange(p1,p2) 

将产生相同的错误

错误为Glist(列表(列表(曲线=列表(数据=列表(X = C(9.66707664902549,: 仅在 “为Glist” 允许的 'grobs'

作为最后一次尝试,我尝试使用recordPlot()将关于绘图的所有内容记录到对象中。以下是现在的功能。

ggplothist<- function(dat,var1) 
{ 
    if (is.character(var1)) { 
      var1 <- which(names(dat) == var1) 
    } 
    distribution <- ggplot(data=dat, aes(dat[,var1])) 
    distribution <- distribution + geom_histogram(aes(y=..density..),binwidth=0.1,colour="black", fill="white") 
    plot(distribution) 
    distribution<-recordPlot() 
    output<-list(distribution,var1,dat) 
    return(output) 
} 

此功能会产生同样的错误和以前一样,依赖于重置DAT,和var1的变量,什么是需要绘制分布。同样不能放入网格中。

我已经试过类似的事情一样arrangeGrob()在这个问题上“R saving multiple ggplot2 plots as R-object in list and re-displaying in grid”,但没有运气。

我真的很喜欢创建一个包含绘图的R对象的解决方案,该对象可以自行重绘,并且可以在网格中使用,而不必在每次完成时重置用于绘制绘图的变量。我也想知道这是怎么回事,因为我根本不认为它很直观。

我能想到的唯一解决方案是将绘图绘制为png文件,保存在某处,然后让该函数返回路径,以便我可以重用 - 是其他人在做什么?

感谢您的阅读,并对长期质疑感到抱歉。

+0

您需要使用双括号而不是单个括号从列表中提取元素:例如'p1 = output1 [[1]]''。 – aosmith

回答

0

找到了解决办法

How can I reference the local environment within a function, in R?

通过插入

localenv <- environment() 

和引用,在ggplot

distribution <- ggplot(data=dat, aes(dat[,var1]),environment = localenv) 

使得它所有的工作!即使有网格布置!

+1

如果这是你所需要的,你可能一直在寻找'aes_string'来完成ggplot2的功能。 – aosmith

+0

我宁愿使可采取任何进来的数据,然后将其重新格式化,以任何适合的功能 的其余部分的代码,如果(is.character(VAR1)){ VAR1 < - 其中(名称(DAT)== VAR1) } – user2673238

+0

看来,我的核心假设是,r为在更新每个函数调用的DAT和VAR1变量,并使用本地功能环境,而不是使用功能以外的全球环境中。 – user2673238