2011-10-15 142 views
7

與其詢問如何繪製大數據集,我想包裝plot,以便生成大量繪圖的代碼在得到時不會敲擊繪製一個大對象。我怎麼能用一種非常簡單的方式來包裝plot,以便保留它的所有功能,但首先測試以確定傳遞的對象是否太大?包裝R的繪圖函數(或ggplot2)以防止繪製大型數據集

此代碼適用於撥打plot的非常香草的電話,但缺少與plot(見下文)相同的通用性。

myPlot <- function(x, ...){ 
    isBad <- any((length(x) > 10^6) || (object.size(x) > 8*10^6) || (nrow(x) > 10^6)) 
    if(is.na(isBad)){isBad = FALSE} 
    if(isBad){ 
     stop("No plots for you!") 
    } 
    return(plot(x, ...)) 
} 

x = rnorm(1000) 
x = rnorm(10^6 + 1) 

myPlot(x) 

一個例子,其中失敗:

x = rnorm(1000) 
y = rnorm(1000) 
plot(y ~ x) 
myPlot(y ~ x) 

有一些簡單的方法來包裝plot使要繪製的數據的這種檢查,同時還經過所有的爭論?如果沒有,那麼ggplot2怎麼樣?我是一個平等機會的非繪圖員。 (在數據集較大的情況下,我會用hexbin,子採樣,密度圖等,但在這裏,這不是重點。)


注1:當測試的想法,我建議測試對於大小> 100(或設置一個變量,例如myThreshold <- 1000),而不是相對於一個大小爲> 1M - 否則會有很大的痛苦在擊中緩慢繪圖。 :)

回答

6

你的問題是,按照目前的編碼,myplot()假定x是一個數據對象,但你試圖通過它的公式。的r plot()經由方法實現了這一 - 當x是一個公式,plot.formula()方法被分派的,而不是基本的方法plot.default()

你需要做的是相同的:

myplot <- function(x, ...) 
    UseMethod("myplot") 

myplot.default <- function(x, ....) { 
    isBad <- any((length(x) > 10^6) || (object.size(x) > 8*10^6) || 
        (nrow(x) > 10^6)) 
    if(is.na(isBad)){isBad = FALSE} 
    if(isBad){ 
     stop("No plots for you!") 
    } 
    invisible(plot(x, ...)) 
} 

myplot.formula <- function(x, ...) { 
    ## code here to process the formula into a data object for plotting 
    .... 
    myplot.default(processed_x, ...) 
} 

您可以從plot.formula()竊取代碼來處理x成一個對象所需的代碼中使用。或者,您可以按照standard non-standard evaluation rules (PDF)推出自己的產品。

+0

+1張貼了正確的答案。 – Andrie

+0

+1瞭解正在發生的事情以及非常有用的指向標準非標準引用的指針。你能澄清我在哪裏可以找到'plot.formula'的代碼嗎?我想任何從公式中提取對象的代碼都可以工作,所以我也在尋找。 – Iterator

+1

@Iterator'graphics ::: plot.formula'或'getAnywhere(plot.formula)'將顯示代碼。 '方法(繪圖)'將顯示哪些S3方法可用於繪圖通用。請注意''plot.formula'在'methods()'的輸出中顯示爲'*',表示該函數本身不從命名空間導出;相反,它被註冊爲調度的S3方法。 –