2010-09-17 9 views
7

Tengo problemas para pasar un POSIXct almacenado en una variable como xmin/xmax para geom_rect. Intenté construir un ejemplo independiente sin trivializar lo que estoy tratando de hacer ...¿Cómo puedo pasar una estética ggplot2 de una variable?

La idea es tomar un objeto de trazado ggplot2, cuya x es una POSIXt, y "acercar" en un rango particular en el tiempo. El zoom está en el 80% superior y toda la serie en el 20% inferior con un indicador de qué parte se acerca.

Mi problema es que me parece que no puede conseguir el xmin/xmax pasado a geom_rect - cada cosa que he probado (que no sea el montaje de la trama a mano en vez de la función) me da un error diferente. Tengo intentos usando un algoritmo AES(), aes_string(), pasando como parámetros en lugar de la estética, pasando sólo cuerdas, etc.

El siguiente ejemplo me dice:

Error in eval(expr, envir, enclos) : object 'lims' not found 

Creo que mi problema es que el Las variables que estoy usando para establecer la estética no están en el alcance cuando se procesa la estética, pero no puedo entender cómo hacerlo. Ayuda.

library(ggplot2) 

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

anm_zoom <- function(limits, p) { 

    lims <- as.POSIXct(limits) 
    limlab <- paste(lims, collapse=" to ") 

    top <- p + scale_x_datetime(limlab, limits=lims, expand=c(0,0)) 

    bottom <- p; 
    bottom <- bottom + opts(title="") 
    bottom <- bottom + opts(legend.position="none") 
    bottom <- bottom + opts(axis.title.y=theme_blank()) 
    bottom <- bottom + scale_x_datetime("", expand=c(0,0)) 
    bottom <- bottom + geom_rect(aes(xmin=lims[1], xmax=lims[2]), 
ymin=-Inf, ymax=Inf, fill="grey80", alpha=0.01) 

    ## Render the plots 
    vplayout(1,5) 
    print(top, vp=subplot(1,c(1,2,3,4))) 
    print(bottom, vp=subplot(1,5)) 
} 


pdate <- seq.POSIXt(from=as.POSIXct("2010-09-09 00:00"), 
    to=as.POSIXct("2010-09-10 23:59"), by="2 mins") 
var1 <- rnorm(length(pdate)) 
var2 <- rnorm(length(pdate)) 
df1 <- data.frame(pdate, var1, var2) 

dm <- melt(df1, id="pdate") 

p <- ggplot(dm) + aes(x=pdate, y=value) + stat_summary(fun.y="sum", geom="line") 

anm_zoom(c("2010-09-09 12:15", "2010-09-09 12:30"), p) 

Respuesta

8

Hmmmm, creo que necesitas una nueva función aes que es un poco como aes (ya que no trata de analizar sus argumentos) y un poco como aes_string (en el que evalúa sus argumentos de inmediato en el entorno local):

aes_now <- function(...) { 
    structure(list(...), class = "uneval") 
} 

Entonces

bottom <- bottom + geom_rect(aes_now(xmin=lims[1], xmax=lims[2]), 
ymin=-Inf, ymax=Inf, fill="grey80", alpha=0.01) 

le da lo que quiere.

+0

Sí, hace exactamente lo que quise decir. Siempre me gusta una respuesta simple, aunque estoy un poco avergonzado de que sea casi un NOOP ... :) ¡Gracias! –

0

solo necesita cambiar el nombre de los límites de argumento de su función ya que creo que está creando un conflicto de alcance. Acabo de cambiarlo a limits1 y también a la primera línea de su código para leer lims = as.POSIXct (limits1) y funciona perfectamente. ¡¡Echale un vistazo!!

+0

se puede publicar su código de trabajo? Hice los cambios que sugirió y no vi ninguna diferencia. Los valores almacenados en lims [1: 2] parecen razonables cuando se imprimen desde el interior de la función, y eso es lo que intento pasar a geom_rect. ¡Aunque aprecio la sugerencia! –

1

reescritura: de Hadley 's respuesta

Debido a las actualizaciones de la versión más reciente ggplot2 por Hadley, una manera más intuitiva se trata de la evaluación no std de ggplot() en la función está usando aes_q() de la siguiente manera:

xminName <- substitute(lims[1]); xmaxName <- substitute(lims[2]) 
    bottom <- bottom + 
    geom_rect(aes_q(xmin=xminName, xmax=xmaxName), 
       ymin=-Inf, ymax=Inf, fill="grey80", alpha=0.01) 
+1

Parece que 'aes_' proporcionaría la respuesta también. [La ayuda] (http://docs.ggplot2.org/current/aes_.html) menciona que "aes_q' es un alias de' aes_' ". –

Cuestiones relacionadas