2010-11-17 13 views
6

que empecé a usar Sweave hace algún tiempo. Sin embargo, como la mayoría de las personas, muy pronto me encontré con un problema importante: la velocidad. Mojar un documento grande requiere años de funcionamiento, lo que hace que el trabajo eficiente sea todo un reto. El procesamiento de datos se puede acelerar mucho con cacheSweave. Sin embargo, las tramas, especialmente ggplot;) aún tardan demasiado en renderizarse. Así es como quiero usar pgfSweave.Problemas con ggplot y pgfSweave

Después de muchas, muchas horas, finalmente logré establecer un sistema en funcionamiento con Eclipse/StatET/Texlipse. Luego quise convertir un informe existente para utilizar con pgfSweave y tuve una sorpresa: la mayoría de mis ggplots ya no funcionan. El siguiente gráfico, por ejemplo, funciona perfectamente en la consola y Sweave:

pl <- ggplot(plot_info,aes(elevation,area)) 
pl <- pl + geom_point(aes(colour=que_id)) 
print(pl) 

Correr con pgfSweave, sin embargo, me sale este error:

Error in if (width > 0) { : missing value where TRUE/FALSE needed 
In addition: Warning message: 
In if (width > 0) { : 
    the condition has length > 1 and only the first element will be used 
Error in driver$runcode(drobj, chunk, chunkopts) : 
    Error in if (width > 0) { : missing value where TRUE/FALSE needed 

Cuando quito AES (...) de geom_point , la trama funciona perfectamente con pgfSweave.

pl <- ggplot(plot_info,aes(elevation,area)) 
pl <- pl + geom_point() 
print(pl) 

Editar: que investigaron más en el problema y podría reducir el problema a la TikZ-dispositivo.

Esto funciona muy bien:

quartz() 
pl <- ggplot(plot_info,aes(elevation,area)) 
pl <- pl + geom_point(aes(colour=que_id)) 
print(pl) 

Esto da el error anterior:

tikz('myPlot.tex',standAlone = T) 
pl <- ggplot(plot_info,aes(elevation,area)) 
pl <- pl + geom_point(aes(colour=que_id)) 
print(pl) 
dev.off() 

Esto funciona muy bien, así:

tikz('myPlot.tex',standAlone = T) 
pl <- ggplot(plot_info,aes(elevation,area)) 
pl <- pl + geom_point() 
print(pl) 
dev.off() 

pude repetir esto con 5 diferentes ggplots. Cuando no se usa color (o tamaño, alfa, ...) en la asignación, funciona con tikz.

Q1: ¿Alguien tiene alguna explicación para este comportamiento?

Además, el almacenamiento en caché de fragmentos de código que no son de trama no funciona muy bien. El siguiente fragmento de código no lleva mucho tiempo con Sweave. Con pgfSweave, toma aproximadamente 10 segundos.

<<plot.opts,echo=FALSE,results=hide,cache=TRUE>>= 
#colour and plot options are globally set 
pal1 <- brewer.pal(8,"Set1") 
pal_seq <- brewer.pal(8,"YlOrRd") 
pal_seq <- c("steelblue1","tomato2") 
opt1 <- opts(panel.grid.major = theme_line(colour = "white"),panel.grid.minor = theme_line(colour = "white")) 
sca_fill_cont_opt <- scale_fill_continuous(low="steelblue1", high="tomato2") 
ory <- geom_hline(yintercept=0,alpha=0.4,linetype=2) 
orx <- geom_vline(xintercept=0,alpha=0.4,linetype=2) 
ts1 <- 2.3 
ts2 <- 2.5 
ts3 <- 2.8 
ps1 <- 6 
offset_x <- function(x,y) 0.15*x/pmax(abs(x),abs(y)) 
offset_y <- function(x,y) 0.05*y/pmax(abs(x),abs(y)) 
plot_size <- 50*50 

Esto parece un comportamiento bastante extraño también, ya que solo algunas variables están configuradas para su uso posterior.

Q2: ¿Alguien tiene alguna explicación para eso?

Q3: En términos más generales, me gustaría preguntar si alguien está usando pgfSweave con éxito. Con éxito quiero decir que todas las cosas que funcionan en Sweave también funcionan en pgfSweave, con el beneficio adicional de fuentes bonitas y velocidad mejorada. ;)

Muchas gracias por las respuestas!

+1

No uso sweave así que no puedo comentar sobre eso pero puedo comentar que ggplot es lento, este es un problema conocido al trazar datos con> 1000 puntos (a veces menos). Si buscas gráficos "más rápidos" prueba Lattice o Base Graphics. Sin embargo, no serán tan bonitos como antes. –

+0

... y normalmente, la velocidad no es un problema al trazar. A menos que quiera usar Sweave ...;) – donodarazao

+1

Hola, donodarazo, soy uno de los autores del tikzDevice. Intentaré reproducir tus problemas de ggplot para ver si hay una solución. Si pudieras guardar 'elevation',' area' y 'que_id' en un archivo RData y enviar un enlace de descarga a la dirección de correo electrónico indicada en la entrada del paquete en CRAN, sería útil. También le enviaré esta pregunta a Cameron; puede que tenga algunas ideas sobre los problemas del pgfSweave. – Sharpie

Respuesta

4

Q1: Does anybody have any explanations for this behavior?

Estos son tres razones de por qué tikzDevice da un error cuando se trata de la construcción de su parcela:

  • Cuando se agrega una asignación de estética que crea una leyenda, como aes(colour=que_id), ggplot2 utilizará el nombre de variable como el título de la leyenda --- en este caso, que_id.

  • El dispositivo tikz pasa todas las cadenas, como los títulos de las leyendas, a LaTeX para la composición tipográfica.

  • En LaTeX, el carácter de subrayado, _, se usa para denotar un subíndice. Si un guión bajo se usa fuera del modo matemático, causa un error.

Cuando el tikzDevice intenta calcular la altura y la anchura del título de la leyenda, "que_id", que pasa la cadena de látex para la composición tipográfica y espera látex para devolver el ancho y la altura de la cadena. LaTeX sufre un error porque hay un guion bajo no escaneado en la cadena fuera del modo matemático. El dispositivo tikz recibe un NULL para el ancho de cadena en lugar de un número que hace que falle una comprobación if (width > 0).

Formas de evitar el problema

  1. Especificar un título de leyenda de usar mediante la adición de una escala de colores:

    p1 <- ggplot(plot_info, aes(elevation, area)) 
    p1 <- p1 + geom_point(aes(colour=que_id)) 
    
    
    # Add a name that is easier for humans to read than the variable name 
    p1 <- p1 + scale_colour_brewer(name="Que ID") 
    
    
    # Or, replace the underscore with the appropriate LaTeX escape sequence 
    p1 <- p1 + scale_colour_brewer(name="que\\textunderscore id") 
    
  2. uso del elemento de cadena de sanitización introducido en tikzDevice 0.5.0 (pero se rompió hasta 0.5.2). Actualmente, la sanitización de cadenas solo escapará a los siguientes caracteres: %, $, {, } y ^ de forma predeterminada. Sin embargo, puede especificar pares de sustitución adicionales a través de las opciones tikzSanitizeCharacters y tikzReplacementCharacters:

    # Add underscores to the sanitization list 
    options(tikzSanitizeCharacters = c('%','$','}','{','^', '_')) 
    options(tikzReplacementCharacters = c('\\%','\\$','\\}','\\{', 
        '\\^{}', '\\textunderscore')) 
    
    
    # Turn on string sanitization when starting the plotting device 
    tikz('myPlot.tex', standAlone = TRUE, sanitize = TRUE) 
    print(p1) 
    dev.off() 
    

Vamos a publicar la versión 0.5.3 del tikzDevice en el próximo par de semanas con el fin de hacer frente a algunos mensajes de advertencia molestos que ahora aparecen debido a cambios en la forma en que R maneja system(). Tengo que añadir los siguientes cambios en este siguiente versión:

  • mejor mensaje de advertencia cuando es widthNULL lo que indica que es probable que haya algo malo con el texto trama.

  • Agregue caracteres de subrayado y algunos otros caracteres al conjunto predeterminado de caracteres que busca el sanitizador de cadenas.

Hope this helps!

+0

¡Agradable! Apliqué los nombres ([df]) <- gsub ("_", ".", Names ([df])) a todos los marcos de datos después de leerlos y adopté el informe. El '_' se debe a que los datos se exportaron desde MS Access donde no '.' en los nombres de los campos son posibles. Ahora funciona bien ... todavía hay que hacer muchos ajustes, pero técnicamente, todo está bien. ¡Gracias por el apoyo y por investigar mis datos! :) – donodarazao

+0

+1 para el carácter desinfectante tikz! – jupp0r

1

Q2: ¿Utiliza \pgfrealjobname{<DOCUMENTNAME>} en el encabezado y la opción external=TRUE para los fragmentos de gráficos? He descubierto que eso aumenta mucho la velocidad (no para la primera compilación, pero para las posteriores si los gráficos no se modifican). Encontrará más antecedentes en la viñeta de pgfSweave.

Q3: Todo funciona bien para mí, uso Windows + Eclipse/StatEt/Texlipse como usted.

+0

Gracias por la respuesta. P2: Sí, utilicé pgfrealname {} y external = TRUE. De todos modos, el problema de velocidad en Q2 fue con un fragmento no gráfico. P3: Es agradable escuchar que, aparentemente, ES REALMENTE posible configurar todo de una manera satisfactoria ... Creo que tengo que hacer más para tratar de llegar allí. ;) – donodarazao

3

Q2: soy el encargado del mantenimiento de pgfsweave.

Éstos son los resultados de una prueba me encontré:

time R CMD Sweave time-test.Rnw 

real 0m1.133s 
user 0m1.068s 
sys  0m0.054s 

time R CMD pgfsweave time-test.Rnw 

real 0m2.941s 
user 0m2.413s 
sys  0m0.364s 

time R CMD pgfsweave time-test.Rnw 

real 0m2.457s 
user 0m2.112s 
sys  0m0.283s 

Creo que la hay 2 razones de la diferencia de tiempo pero se necesitaría más trabajo para verificar exactamente:

  • pgfSweave hace un montón de comprobaciones y comprobaciones dobles para asegurarse de que no está volviendo a hacer costosos cálculos. El objetivo es hacer factible hacer cálculos y trazar más costosos dentro de un documento. La escala de "costoso" en este caso es mucho más que el segundo o segundo adicional para hacer los controles.

Como un ejemplo de la caché de considerar el archivo de prueba siguiente para ver los beneficios reales de almacenamiento en caché:

\documentclass{article} 

\begin{document} 

<<plot.opts,cache=TRUE>>= 
x <- Sys.sleep(10) 
@ 

\end{document} 

y los resultados:

time R CMD Sweave time-test2.Rnw 

real 0m10.334s 
user 0m0.283s 
sys  0m0.047s 

time R CMD pgfsweave time-test2.Rnw 

real 0m12.032s 
user 0m1.356s 
sys  0m0.349s 

time R CMD pgfsweave time-test2.Rnw 

real 0m1.423s 
user 0m1.121s 
sys  0m0.266s 
  • Sweave ha sufrido algunos cambios en R 2.12. Los cambios pueden haber acelerado el proceso de evaluación del fragmento de código y dejar atrás a pgfSweave para estos cálculos más pequeños. Vale la pena investigar

Q3: Uso pgfSweave todo el tiempo para mi propio trabajo. Ha habido algunos cambios en Sweave en R 2.12 que han estado causando algunos problemas menores con pgfSweave, pero una nueva versión llegará próximamente que arregla todo. La versión de desarrollo en github (https://github.com/cameronbracken/pgfSweave) ya tiene los cambios. Si tiene problemas adicionales, me complacería ayudarlo.