2012-07-11 53 views
4

我不知道如何把它放在OO-Speech中。但是当你创建一个ggplot时,它将依赖于源数据框架。那么如何保存没有这种依赖关系的ggplot呢?ggplot2:从ggplot-Object创建一个独立副本

dat <- data.frame(x=runif(10),y=runif(10)) 
g <- ggplot(dat, aes(x,y)) + geom_point() 
g 

dat <- NULL 
g 

第二个$ g $不会产生一个图,因此dat是$ NULL $。我如何保存$ g $,以便更改dat?

我知道这不是很好的做法,但我得到了一些我不想摆弄的很长的代码。

+1

难道你不只是保存,然后加载工作区? – 2012-07-11 11:44:40

+2

实际上,无论dat是否设置为NULL,“第二个g”都会生成一个图。并且g包含数据:尝试输入g $数据。 – neilfws 2012-07-11 12:10:18

+1

我们需要版本号码,人员! packageDescription(“ggplot2”)$ Version = 0.9.1,g有一个$ data元素中数据的副本。我不敢相信这会改变。要保留对数据的引用,以便在数据发生变化时绘图发生变化将是一件非常奇怪的事情... – Spacedman 2012-07-11 14:52:32

回答

3

我认为有几种选择,我按照我的喜好显示。

## setup 
require(ggplot2) 
set.seed(10) # make reproducible 
dat <- data.frame(x=1:10,y=runif(10)) 

我最喜欢的选择是为您的代码创建一个简单的函数包装。然后,无论何时您需要更改数据,只需将新数据传递给您的函数,它就会将其提供给ggplot并创建新图形。这是灵活的,相当强大的问题。它也是可扩展的,因为如果后来你决定你也希望能够改变标题,那么你也可以为你的函数添加一个标题参数。

## my favorite option 
myplot <- function(data) { 
    ggplot(data, aes(x, y)) + geom_point() 
} 

## use it 
myplot(data = dat) 

first plot

## change it 
dat <- data.frame(x = 11:20, y = runif(10)) 
myplot(data = dat) 

second plot

另一种方法是你要ggplot调用保存为一个表达式,这是未评估。然后你只需要评估它。这几乎就像每次输入代码(它在某些方面有所不同,但这是我能想到的最好的比喻)。

## not wild about this one 
myplotcall <- expression(ggplot(dat, aes(x,y)) + geom_point()) 

## look at it (literally just the input) 
myplotcall 
expression(ggplot(dat, aes(x, y)) + geom_point()) 

## use it 
eval(myplotcall) 

third plot

## change it 
dat <- data.frame(x = 21:30, y = runif(10)) 
eval(myplotcall) 

fourth plot

您可以更改ggplot对象本身的数据。我认为这种方法是最容易出问题的,因为你正在使用一个对象内部的东西,而这个内部对象并没有真正被用户改变(也就是说,因为我们不能说我们应该这样做)。这是更为恰当的%+%操作完成(见joran的答案)

## not wild about this either 
g <- ggplot(dat, aes(x,y)) + geom_point() 
g ## use it 

fifth plot

## change it 
dat <- data.frame(x = 31:40, y = runif(10)) 
g$data <- dat 
g 

sixth plot

5

就个人而言,我认为,@约书亚的答案是太复杂了(如果我了解你想要做什么)。

我不认为这有什么意义改变存储在剧情对象的数据帧,因为GGPLOT2有专门设计一个新的数据帧适用于一个给定的剧情对象特殊管道符:%+%

dat <- data.frame(x=runif(10),y=runif(10)) 
g <- ggplot(dat, aes(x,y)) + geom_point() 
g 

enter image description here

#Change the data frame 
dat$y <- rexp(10) 
#Replot g using the altered data frame 
g %+% dat 

enter image description here

这个工作,当然,与原始数据帧的不只是更改后的版本,而是一个全新的数据帧,只要它具有所有必要的变量(并且它们被命名为相同)。

+0

此外,您可以创建一个具有与原始数据相同结构的虚拟空data.frame(例如,'dat [FALSE,]'),并将该数据分配给图,保存结果,然后当您想使用其他结构数据,分配新的数据;保存的图将是无数据的,但不是无数据结构的。 – 2012-07-12 18:08:52

+0

好点,我没想到更新它。 – Joshua 2012-07-13 14:59:45