2015-08-13 52 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