2010-11-17 11 views
6

Ho iniziato a utilizzare Sweave qualche tempo fa. Tuttavia, come la maggior parte delle persone, ho riscontrato abbastanza presto un problema importante: la velocità. La scansione di un documento di grandi dimensioni richiede anni di lavoro, il che rende il lavoro efficiente piuttosto impegnativo. L'elaborazione dei dati può essere accelerata molto con cacheSweave. Tuttavia, i grafici, in particolare ggplot;) richiedono ancora troppo tempo per essere visualizzati. Questo è il modo in cui voglio usare pgfSweave.Problemi con ggplot e pgfSweave

Dopo molte, molte ore, sono finalmente riuscito a impostare un sistema funzionante con Eclipse/StatET/Texlipse. Poi ho voluto convertire un rapporto esistente da usare con pgfSweave e ho avuto una brutta sorpresa: la maggior parte dei miei ggplot non sembra funzionare più. La trama segue per esempio, funziona perfettamente nella console e Sweave:

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

Esecuzione con pgfSweave, tuttavia, ottengo questo errore:

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 

Quando rimuovo AES (...) da geom_point , la trama funziona perfettamente con pgfSweave.

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

Edit: ho studiato più nel problema e potrebbe ridurre il problema al tikz-dispositivo.

Questo funziona bene:

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

Questo dà l'errore precedente:

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

Questo funziona bene così:

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

potrei ripetere questo con 5 differenti ggplots. Quando non si utilizza il colore (o dimensione, alpha, ...) nella mappatura, funziona con tikz.

Q1: Qualcuno ha qualche spiegazione per questo comportamento?

Inoltre, il caching di blocchi di codice non di trama non funziona molto bene. Il seguente codice pezzo non richiede assolutamente tempo con Sweave. Con pgfSweave, ci vogliono circa 10 secondi.

<<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 

questo sembra un comportamento molto strano, così, come solo alcune variabili sono impostate per un uso successivo.

Q2: Qualcuno ha qualche spiegazione per questo?

Q3: Più in generale, vorrei chiedere se qualcuno sta usando pgfSweave con successo? Con successo intendo dire che tutte le cose che funzionano in Sweave funzionano anche in pgfSweave, con l'ulteriore vantaggio di font carini e velocità migliorata. ;)

Grazie mille per le risposte!

+1

Non uso il sweave quindi non posso commentare ma posso commentare che ggplot è lento, questo è un problema noto durante la stampa di dati con> 1000 punti (a volte meno). Se stai cercando un grafico "più veloce" prova Lattice o Base Graphics. Comunque non saranno così graziosi fuori dagli schemi. –

+0

... e normalmente, la velocità non è tanto un problema durante la stampa. A meno che tu non voglia usare Sweave ...;) – donodarazao

+1

Ciao donodarazo, sono uno degli autori del tikzDevice. Proverò a riprodurre i tuoi problemi ggplot per vedere se c'è una soluzione. Se fosse possibile salvare 'elevazione',' area' e 'que_id' in un file RData e inviare un collegamento per il download all'indirizzo di posta elettronica elencato nella voce del pacchetto su CRAN, sarebbe di aiuto. Inoltrerò anche questa domanda a Cameron --- potrebbe avere qualche idea riguardante i problemi pgfSweave. – Sharpie

risposta

4

Q1: Does anybody have any explanations for this behavior?

Queste sono tre ragioni per cui tikzDevice dà un errore quando si cerca di costruire la vostra trama:

  • Quando si aggiunge un mapping estetica che crea una leggenda, come ad esempio aes(colour=que_id), ggplot2 utilizzerà il nome della variabile come titolo della legenda --- in questo caso, que_id.

  • Il tikzDevice passa tutte le stringhe, come i titoli delle legende, a LaTeX per la composizione.

  • In LaTeX il carattere di sottolineatura, _, viene utilizzato per indicare un indice. Se un carattere di sottolineatura viene utilizzato al di fuori della modalità matematica, provoca un errore.

Quando il tikzDevice cerca di calcolare l'altezza e la larghezza del titolo di legenda, "que_id", passa la stringa di lattice per la composizione tipografica e si aspetta LaTeX per restituire la larghezza e l'altezza della stringa. LaTeX subisce un errore perché è presente un carattere di sottolineatura senza escape nella stringa all'esterno di mathmode. Il tikzDevice riceve uno NULL per la larghezza della stringa anziché un numero, il che causa il fallimento di un controllo if (width > 0).

modi per evitare il problema

  1. Specificare un titolo di legenda da utilizzare con l'aggiunta di una scala di colori:

    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. Utilizzare la funzione di stringa di sanificazione introdotta in tikzDevice 0.5.0 (ma è stato rotto fino a 0.5.2). Attualmente, la disinfezione delle stringhe sfugge solo ai seguenti caratteri: %, $, {, } e ^ per impostazione predefinita. Tuttavia, è possibile specificare le coppie di sostituzione aggiuntivi tramite le opzioni tikzSanitizeCharacters e 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() 
    

Noi pubblicheremo la versione 0.5.3 del tikzDevice nel prossimo paio di settimane al fine di affrontare alcuni messaggi di avviso fastidiosi che ora appaiono a causa di cambiamenti nel modo in cui R gestisce system(). Vorrei aggiungere le seguenti modifiche a questa prossima versione:

  • Meglio messaggio di avviso quando è widthNULL che indica che probabilmente c'è qualcosa di sbagliato con il testo trama.

  • Aggiungere caratteri di sottolineatura e alcuni altri caratteri al set predefinito di caratteri che viene ricercato dallo strumento di pulizia delle stringhe.

Spero che questo aiuti!

+0

Bello! Ho applicato nomi ([df]) <- gsub ("_", ".", Nomi ([df])) a tutti i frame di dati dopo averli letti e adottato il report. Il '_' era perché i dati sono stati esportati da MS Access dove nessun '.' nei nomi dei campi sono possibili. Ora funziona bene ... c'è ancora un sacco di ritocchi da fare, ma tecnicamente, tutto è buono. Grazie per il supporto e per l'analisi dei miei dati! :) – donodarazao

+0

+1 per il carattere tikz sanificante! – jupp0r

1

Q2: Si utilizza \pgfrealjobname{<DOCUMENTNAME>} nell'intestazione e l'opzione external=TRUE per i blocchi grafici? ho trovato che che aumenta la velocità molto (non per la prima compilazione, ma per quelli successivi se la grafica è invariato). Troverai più sfondo nella vignetta di pgfSweave.

Q3: Tutto funziona per me, io uso Windows + Eclipse/StatEt/Texlipse come te.

+0

Grazie per la risposta. Q2: Sì, ho usato pgfrealname {} e external = TRUE. Ad ogni modo, il problema della velocità in Q2 era con un blocco grafico privo di grafici. Q3: È bello sentire che a quanto pare è davvero possibile configurare tutto in modo soddisfacente ... Credo che dovrò fare ancora un po 'di tentativi per arrivarci. ;) – donodarazao

3

Q2: Sono il manutentore di pgfsweave.

Ecco i risultati di un test mi sono imbattuto:

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 

credo la ci sono 2 ragioni per la differenza di tempo ma ci vorrebbe più lavoro per verificare esattamente:

  • pgfSweave fa una tonnellata di controllo e doppio controllo per assicurarsi che non stia rifacendo costosi calcoli. L'obiettivo è rendere fattibile eseguire calcoli più costosi e tracciare all'interno di un documento. La scala di "costoso" in questo caso è molto più che il secondo o il secondo aggiuntivo da eseguire.

Come esempio del caching Si consideri il seguente file di prova per vedere i reali benefici di caching:

\documentclass{article} 

\begin{document} 

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

\end{document} 

E i risultati:

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 subito alcune modifiche in R 2.12. Le modifiche potrebbero aver velocizzato il processo di valutazione del chunk di codice e lasciato pgfSweave dietro per questi calcoli più piccoli. Vale la pena esaminare

Q3: Io uso pgfSweave me stesso tutto il tempo per il mio lavoro. Ci sono stati alcuni cambiamenti in Sweave in R 2.12 che hanno causato alcuni problemi minori con pgfSweave ma una nuova versione è imminente che corregge tutto. La versione di sviluppo su github (https://github.com/cameronbracken/pgfSweave) ha già le modifiche. Se hai problemi aggiuntivi, sarei felice di aiutarti.