2009-11-30 33 views
10

昨天我問this關於在對象中存儲圖的問題。我嘗試實施第一種方法(意識到我沒有指定我在原始問題中使用了qplot()),並注意到它沒有按預期工作。將列表對象存儲在列表中

library(ggplot2)    # add ggplot2 

string = "C:/example.pdf"  # Setup pdf 
pdf(string,height=6,width=9) 

x_range <- range(1,50)   # Specify Range 

# Create a list to hold the plot objects. 
pltList <- list() 
pltList[] 

for(i in 1 : 16){ 

# Organise data 
y = (1:50) * i * 1000      # Get y col 
x = (1:50)         # get x col 
y = log(y)         # Use natural log 

# Regression 
lm.0 = lm(formula = y ~ x)     # make linear model 
inter = summary(lm.0)$coefficients[1,1]  # Get intercept 
slop = summary(lm.0)$coefficients[2,1]  # Get slope 

# Make plot name 
pltName <- paste('a', i, sep = '') 

# make plot object  
p <- qplot(
    x, y, 
    xlab = "Radius [km]", 
    ylab = "Services [log]", 
    xlim = x_range, 
    main = paste("Sample",i) 
) + geom_abline(intercept = inter, slope = slop, colour = "red", size = 1)   

print(p)  

pltList[[pltName]] = p  
} 

# close the PDF file 
dev.off() 

我在這種情況下使用了示例編號,所以如果代碼只是被複制,就會運行。我花了幾個小時困惑這個,但我無法弄清楚什麼是錯的。它寫沒有問題的第一套pdf,所以我有16個pdf的正確情節。

後來,當我使用這段代碼:

string = "C:/test_tabloid.pdf" 
pdf(string, height = 11, width = 17) 

grid.newpage() 
pushViewport(viewport(layout = grid.layout(3, 3))) 

vplayout <- function(x, y){viewport(layout.pos.row = x, layout.pos.col = y)} 

counter = 1 

# Page 1 
for (i in 1:3){  
    for (j in 1:3){  
     pltName <- paste('a', counter, sep = '') 
     print(pltList[[pltName]], vp = vplayout(i,j)) 
     counter = counter + 1 
    } 
} 

dev.off() 

結果我得到的是在每個圖中的最後一個線性模型線(abline),但數據不會改變。當我查看我的地塊列表時,似乎它們全部被最近的地塊覆蓋(除了abline對象外)。

不太重要的第二個問題是如何在每個頁面上生成多頁圖表,但我的代碼的主要目標是將圖表存儲在我可以在以後訪問的列表中。

回答

10

好了,如果你的繪圖命令改爲

p <- qplot(data = data.frame(x = x, y = y), 
      x, y, 
      xlab = "Radius [km]", 
      ylab = "Services [log]", 
      xlim = x_range, 
      ylim = c(0,10), 
      main = paste("Sample",i) 
      ) + geom_abline(intercept = inter, slope = slop, colour = "red", size = 1)   

然後按預期工作的一切。這是我懷疑發生的事情(儘管哈德利可能會澄清事情)。當ggplot2「保存」數據時,它實際上做了什麼就是保存數據幀和參數的名稱。所以對於命令我給它,你就會得到

> summary(pltList[["a1"]]) 
data: x, y [50x2] 
mapping: x = x, y = y 
scales: x, y 
faceting: facet_grid(. ~ ., FALSE) 
----------------------------------- 
geom_point: 
stat_identity: 
position_identity: (width = NULL, height = NULL) 

mapping: group = 1 
geom_abline: colour = red, size = 1 
stat_abline: intercept = 2.55595281266726, slope = 0.05543539319091 
position_identity: (width = NULL, height = NULL) 

但是,如果沒有指定qplot一個data參數,所有的變量獲得當前範圍內評估,因爲沒有連接(讀:保存)數據幀。

data: [0x0] 
mapping: x = x, y = y 
scales: x, y 
faceting: facet_grid(. ~ ., FALSE) 
----------------------------------- 
geom_point: 
stat_identity: 
position_identity: (width = NULL, height = NULL) 

mapping: group = 1 
geom_abline: colour = red, size = 1 
stat_abline: intercept = 2.55595281266726, slope = 0.05543539319091 
position_identity: (width = NULL, height = NULL) 

所以當劇情產生第二次左右,而不是使用原始值,它使用的xy當前值。

+0

感謝RCS和Jonathan,這解決了這個問題。我不知道數據參數以及它如何用於存儲數據。我正在研究這本書的這一部分。 – womble 2009-11-30 22:19:38

1

關於第二個問題:多頁的PDF文件很容易 - 看看help(pdf)

onefile: logical: if true (the default) allow multiple figures in one 
      file. If false, generate a file with name containing the 
      page number for each page. Defaults to ‘TRUE’. 

爲了您的主要問題,我不明白,如果你想存儲情節輸入列表中用於後期處理,或繪圖輸出。如果是後者,我不確定plot()是否會返回可以存儲和檢索的對象。

+0

我希望能存儲繪圖輸出。如果我存儲繪圖輸入,是否包括特定時間的x和y的值? – womble 2009-11-30 16:13:01

+0

當然。只需將所有函數參數等存儲在一個列表中。這是非常標準的。但是你存儲_plot output_的假設不是。繪圖結果是依賴於設備的,並且很可能取決於操作系統。只需寫入一個文件,可能是一個位圖,並顯示該文件。或編寫GUI風格的應用程序。或者只是打開多個圖形窗口。 – 2009-11-30 16:22:11

+0

但是,'ggplot'可能會返回對象給你。在這種情況下,愛德華多的答案是你的關鍵。 – 2009-11-30 16:55:33

2

代碼中存在一個關於列表下標的錯誤。它應該是

pltList[[pltName]] 

pltList[pltName] 

注:

class(pltList[1]) 
[1] "list" 

pltList [1]是含有pltList的第一元素的列表

class(pltList[[1]]) 
[1] "ggplot" 

pltList [[1]]是pltList的第一元件

+0

對不起 - 我打算粘貼的內容有誤。我沒有完全理解這些語法之間的差異,並且一直在編輯它以查看差異。但是,我的錯誤仍然存​​在,正如我上面所述。 – womble 2009-11-30 18:49:19

1

關於第二個問題的另一個建議是使用Sweave或Brew,因爲它們將使您完全控制如何顯示多頁PDF。

看一看at this related question

4

我認爲你應該使用qplot中的data參數,即將你的向量存儲在數據框中。

查看哈德利的書,第4節。4:

對數據的限制很簡單:它必須是數據框。這是限制性的,與R.中的其他圖形軟件包不同。萊迪思函數可以採用可選的數據框或直接從全局環境使用矢量。 ...

數據作爲副本存儲在繪圖對象中,而不是參考。這有兩個重要的後果:如果你的數據改變了,情節不會;和ggplot2對象是完全自包含的,因此它們可以保存()到磁盤,然後加載()編輯和繪製,而不需要該會話中的任何其他內容。