2012-07-11 55 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