2010-11-17 36 views
6

J'ai commencé à utiliser Sweave il y a quelque temps. Cependant, comme la plupart des gens j'ai rencontré très vite un problème majeur: la vitesse. Le transfert d'un document volumineux prend plusieurs années, ce qui rend le travail efficace très difficile. Le traitement des données peut être accéléré avec cacheSweave. Cependant, les graphiques - en particulier ggplot;) - prennent encore trop de temps à rendre. C'est comme ça que je veux utiliser pgfSweave.Problèmes avec ggplot et pgfSweave

Après de nombreuses heures, j'ai finalement réussi à mettre en place un système de travail avec Eclipse/StatET/Texlipse. J'ai alors voulu convertir un rapport existant à utiliser avec pgfSweave et j'ai eu une mauvaise surprise: la plupart de mes ggplots ne semblent plus fonctionner. L'intrigue suivante par exemple fonctionne parfaitement dans la console et Sweave:

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

Courir avec pgfSweave, cependant, je reçois cette erreur:

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 

Quand je retire aes (...) de geom_point , l'intrigue fonctionne parfaitement avec pgfSweave.

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

Edit: Je enquêté sur plus sur le problème et pourrait réduire le problème au périphérique tikz.

Cela fonctionne très bien:

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

Cela donne à l'erreur ci-dessus:

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

Cela fonctionne très bien ainsi:

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

Je pourrais répéter avec 5 ggplots. Lorsque vous n'utilisez pas de couleur (ou de taille, alpha, ...) dans le mapping, cela fonctionne avec tikz.

Q1: Quelqu'un at-il des explications pour ce comportement?

En outre, la mise en cache de blocs de code non-plot ne fonctionne pas très bien. Le fragment de code suivant ne prend pas du tout de temps avec Sweave. Avec pgfSweave, cela prend environ 10 secondes.

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

Cela semble un comportement assez étrange, car seules certaines variables sont définies pour une utilisation ultérieure.

Q2: Quelqu'un at-il des explications pour cela? Q3: Plus généralement, j'aimerais savoir si quelqu'un utilise pgfSweave avec succès? Avec succès, je veux dire que tout ce qui fonctionne dans Sweave fonctionne également dans pgfSweave, avec l'avantage supplémentaire de belles polices et une vitesse améliorée. ;)

Merci beaucoup pour les réponses!

+1

Je n'utilise pas sweave donc je ne peux pas commenter cela mais je peux commenter que ggplot est lent, c'est un problème connu en traçant des données avec> 1000 points (parfois moins). Si vous cherchez des graphismes "plus rapides", essayez Lattice ou Base Graphics. Ils ne seront pas aussi beaux hors de la boîte cependant. –

+0

... et normalement, la vitesse n'est pas vraiment un problème lors du traçage. Sauf si vous voulez utiliser Sweave ...;) – donodarazao

+1

Salut donodarazo, je suis l'un des auteurs du tikzDevice. Je vais essayer de reproduire vos problèmes ggplot pour voir s'il y a un correctif. Si vous pouviez enregistrer 'elevation',' area' et 'que_id' dans un fichier RData et envoyer un lien de téléchargement vers l'adresse e-mail indiquée dans l'entrée du paquet sur CRAN cela aiderait. Je transmettrai également cette question à Cameron --- il pourrait avoir quelques idées concernant les problèmes de pgfSweave. – Sharpie

Répondre

4

Q1: Does anybody have any explanations for this behavior?

Ce sont trois raisons pour lesquelles tikzDevice donne une erreur en essayant de construire votre terrain:

  • Lorsque vous ajoutez une cartographie esthétique qui crée une légende, comme aes(colour=que_id), ggplot2 utilisera la nom de la variable comme titre de la légende --- dans ce cas, que_id.

  • Le tikzDevice transmet toutes les chaînes, telles que les titres de légende, à LaTeX pour la composition.

  • Dans LaTeX, le caractère de soulignement, _, est utilisé pour désigner un indice. Si un trait de soulignement est utilisé en dehors du mode mathématique, cela provoque une erreur.

Lorsque le tikzDevice essaie de calculer la hauteur et la largeur du titre de la légende, « que_id », il passe la chaîne LATEX pour la composition et attend pour revenir la LATEX largeur et la hauteur de la chaîne. LaTeX souffre d'une erreur car il y a un soulignement non échappé utilisé dans la chaîne en dehors de mathmode. Le tikzDevice reçoit un NULL pour la largeur de chaîne au lieu d'un nombre qui provoque l'échec de la vérification if (width > 0).

façons d'éviter le problème

  1. Spécifiez un titre de légende à utiliser en ajoutant une échelle de couleurs:

    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. Utilisez la fonction string sanitization introduite dans tikzDevice 0.5.0 (mais a été cassé jusqu'à 0.5.2). Actuellement, la désinfection des chaînes n'échappera que les caractères suivants: %, $, {, } et ^ par défaut. Cependant, vous pouvez spécifier des paires de substitution supplémentaires via les tikzSanitizeCharacters et tikzReplacementCharacters Options:

    # 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() 
    

Nous allons la version publierons 0.5.3 du tikzDevice dans les deux prochaines semaines afin de répondre à certains messages d'avertissement ennuyeux qui apparaissent maintenant en raison de changements dans la façon dont R gère system(). Je vais ajouter les modifications suivantes à cette prochaine version:

  • meilleur message d'avertissement lorsque width est NULL indiquant qu'il ya probablement quelque chose de mal avec le texte de l'intrigue.

  • Ajoutez des caractères de soulignement et quelques autres caractères à l'ensemble de caractères par défaut que le désinfectant de chaîne recherche.

Espérons que cela aide!

+0

Nice! J'ai appliqué des noms ([df]) <- gsub ("_", ".", Noms ([df])) à toutes les trames de données après les avoir lues et j'ai adopté le rapport. Le '_' était parce que les données ont été exportées de MS Access où aucun '.' dans les noms de champs sont possibles. Maintenant, ça marche bien ... il y a encore beaucoup de réglages à faire, mais techniquement, tout va bien. Merci pour le support et pour regarder dans mes données! :) – donodarazao

+0

+1 pour le nettoyage du personnage tikz! – jupp0r

1

Q2: Utilisez-vous \pgfrealjobname{<DOCUMENTNAME>} dans l'en-tête et l'option external=TRUE pour les segments graphiques? J'ai trouvé que cela augmente beaucoup la vitesse (pas pour la première compilation, mais pour les suivantes si les graphismes sont inchangés). Vous trouverez plus d'informations dans la vignette pgfSweave.Q3: Tout fonctionne bien pour moi, j'utilise Windows + Eclipse/StatEt/Texlipse comme vous.

+0

Merci pour la réponse. Q2: Oui, j'ai utilisé pgfrealname {} et external = TRUE. Quoi qu'il en soit, le problème de vitesse au T2 était avec un morceau non-graphique. Q3: C'est agréable d'entendre que, apparemment, il est vraiment possible de tout configurer de manière satisfaisante ... Je suppose que je dois juste faire plus d'essayer d'y arriver. ;) – donodarazao

3

Q2: Je suis le mainteneur de pgfsweave.

Voici les résultats d'un test j'ai couru:

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 

Je crois que les il y a 2 raisons de la différence de temps, mais il faudrait plus de travail pour les vérifier exactement:

  • pgfSweave fait une tonne de vérification et de double vérification pour s'assurer qu'il ne refait pas des calculs coûteux. L'objectif est de rendre possible de faire des calculs plus coûteux et de traçage dans un document. L'échelle de «cher» dans ce cas est beaucoup plus que la deuxième ou deux à faire des contrôles supplémentaires.

À titre d'exemple de la mise en cache considèrent le fichier de test ci-dessous pour voir les réels avantages de la mise en cache:

\documentclass{article} 

\begin{document} 

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

\end{document} 

Et les résultats:

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 a subi quelques changements dans R 2.12. Les modifications ont peut-être accéléré le processus d'évaluation du bloc de code et laissé pgfSweave derrière pour ces calculs plus petits. A voir dans

Q3: J'utilise pgfSweave moi-même tout le temps pour mon propre travail. Il y a eu quelques changements dans Sweave dans R 2.12 qui ont causé quelques problèmes mineurs avec pgfSweave mais une nouvelle version est à venir qui corrige tout. La version de développement sur github (https://github.com/cameronbracken/pgfSweave) a déjà les changements. Si vous avez des problèmes supplémentaires, je serais heureux de vous aider.