2011-10-15 18 views
7

En lugar de preguntar cómo trazar grandes conjuntos de datos, quiero envolver plot para que el código que produce muchas parcelas no se golpee cuando es trazando un objeto grande. ¿Cómo puedo ajustar plot de una manera muy simple para que se conserve toda su funcionalidad, pero las primeras pruebas para determinar si el objeto que se pasa es demasiado grande o no?Envolviendo la función de trazado de R (o ggplot2) para evitar el trazado de grandes conjuntos de datos

Este código funciona para llamadas muy simples a plot, pero le falta la misma generalidad que plot (ver a continuación).

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) 

Un ejemplo donde esto falla:

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

¿Hay alguna forma fácil de envolver plot para habilitar esta comprobación de los datos que se pintarán, sin dejar de pasar por todos los argumentos? Si no, entonces ¿qué hay de ggplot2? Soy una oportunidad igual sin trazador. (En los casos en que el conjunto de datos es grande, voy a utilizar hexbin, submuestreo, gráficos de densidad, etc., pero eso no es el foco aquí.)


Nota 1: Al probar las ideas, recomiendo la prueba para el tamaño> 100 (o establecer una variable, por ejemplo, myThreshold <- 1000), en lugar de frente a un tamaño de> 1 M - de lo contrario, habrá un gran dolor al golpear el trazado lento. :)

Respuesta

6

El problema que tienes es que, como está codificado actualmente, myplot() supone x es un objeto de datos, pero luego intentas pasarle una fórmula. R's plot() logra esto a través de métodos - cuando x es una fórmula, se envía el método plot.formula() en lugar del método básico plot.default().

que tiene que hacer el mismo:

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, ...) 
} 

Se puede robar el código de plot.formula() a utilizar en el código necesario para procesar x en un objeto. Alternativamente, puede hacer su propio seguimiento al standard non-standard evaluation rules (PDF).

+0

+1 para publicar la respuesta correcta. – Andrie

+0

+1 Para obtener información sobre lo que está sucediendo y para el puntero muy útil a la referencia estándar no estándar. ¿Puedes aclarar dónde puedo encontrar el código para 'plot.formula'? Supongo que cualquier código que extraiga objetos de una fórmula funcionará, así que también estoy buscando eso. – Iterator

+1

@Iterator 'graphics ::: plot.formula' o' getAnywhere (plot.formula) 'mostrará el código. 'methods (plot)' mostrará qué métodos S3 están disponibles para la trama genérica. Tenga en cuenta que 'plot.formula' se muestra con un' * 'en la salida de' methods() ', lo que indica que la función en sí misma no se exporta desde el espacio de nombres; en su lugar, está registrado como un método S3 para el envío. –

Cuestiones relacionadas