ggplot2:从ggplot-Object创建一个独立的副本

时间:2012-07-11 11:40:44

标签: r oop ggplot2

我不知道如何把它放在OO-Speech中。但是当你创建一个ggplot时,它将依赖于源data.frame。那么如何在没有这种依赖性的情况下保存ggplot呢?

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 $以便可以更改数据?

我知道这不是一个好习惯,但我得到了一些很长的代码,我不想这样做。

2 个答案:

答案 0 :(得分:5)

就个人而言,我认为@Joshua的答案太复杂了(如果我理解你想做什么的话)。

我认为更改存储在绘图对象中的数据框没有任何意义,因为 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

当然,这不仅可以改变原始数据框的版本,还可以使用全新的数据框,前提是它具有所有必需的变量(并且它们的名称相同)。

答案 1 :(得分:3)

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

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

我最喜欢的选择是为代码创建一个简单的函数包装器。然后,只要您需要更改数据,只需将新数据传递给您的函数,它就会将其提供给ggplot并创建新图表。这是灵活的,并且对问题相当稳健。它也是可扩展的,因为如果你以后决定你也想改变标题,你也可以在你的函数中添加一个title参数。

## 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