46 votes

Variables locales dans aes

Je suis en train d'utiliser une variable locale dans aes quand je la parcelle avec ggplot. C'est mon problème se résumait à l'essence:

xy <- data.frame(x=1:10,y=1:10)

plotfunc <- function(Data,YMul=2){
    ggplot(Data,aes(x=x,y=y*YMul))+geom_line()
}

plotfunc(xy)

Cela se traduit dans le message d'erreur suivant:

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

Il me semble que je ne peut pas utiliser des variables locales (ou des arguments de la fonction) en aes. Se pourrait-il qu'il atteint son apogée en raison du contenu de aes être exécuté au plus tard lors de la variable locale est hors de portée? Comment puis-je éviter ce problème (autre que de ne pas utiliser la variable locale dans aes)?

39voto

baptiste Points 19677

Je capturerais l'environnement local,

 xy <- data.frame(x=1:10,y=1:10)

plotfunc <- function(Data, YMul = 2){
    .e <- environment()
    ggplot(Data, aes(x = x, y = y*YMul), environment = .e) + geom_line()
}

plotfunc(xy)
 

10voto

Josh O'Brien Points 68397

Voici une alternative qui vous permet de passer n'importe quelle valeur à travers l'argument YMul sans avoir à l'ajouter à Data data.frame ou à l'environnement global:

 plotfunc <- function(Data, YMul = 2){
    eval(substitute(
        expr = {
            ggplot(Data,aes(x=x,y=y*YMul)) + geom_line()
        }, 
        env = list(YMul=YMul)))
    }

plotfunc(xy, YMul=100)
 

Pour voir comment cela fonctionne, essayez la ligne suivante de manière isolée:

 substitute({ggplot(Data, aes(x=x, y=y*YMul))}, list(YMul=100))
 

5voto

jthetzel Points 2349

ggplot()s' aes prévoit YMul à une variable à l'intérieur de l' data bloc de données. Essayez d'inclure YMull y à la place:

Grâce à @Justin: ggplot()s' aes semble chercherYMul dans la data bloc de données en premier, et si non trouvé, puis dans l'environnement mondial. Je tiens à ajouter des variables à la trame de données, comme suit, comme il fait sens pour moi sur le plan conceptuel. J'ai aussi de ne pas avoir à vous soucier des changements de variables globales avoir des conséquences inattendues pour les fonctions. Mais toutes les autres réponses sont également correctes. Donc, utilisez celui qui vous convient le mieux.

require("ggplot2")
xy <- data.frame(x = 1:10, y = 1:10)
xy <- cbind(xy, YMul = 2)

ggplot(xy, aes(x = x, y = y * YMul)) + geom_line()

Ou, si vous voulez la fonction dans votre exemple:

plotfunc <- function(Data, YMul = 2)
{
    ggplot(cbind(Data, YMul), aes(x = x, y = y * YMul)) + geom_line()
}

plotfunc(xy)

1voto

BBrill Points 414

Avez-vous examiné la solution donnée par @wch (W. Chang)?

https://github.com/hadley/ggplot2/issues/743

Je pense que c'est le meilleur

est essentiellement comme celle de @baptiste mais incluez la référence à l'environnement directement dans l'appel à ggplot

Je le rapporte ici

 g <- function() {
  foo3 <- 4
  ggplot(mtcars, aes(x = wt + foo3, y = mpg),
         environment = environment()) +
    geom_point()
}

g()
# Works
 

0voto

Justin Points 19077

Si vous exécutez votre code en dehors de la fonction, cela fonctionne. Et si vous exécutez le code dans la fonction avec YMul défini globalement, cela fonctionne. Je ne comprends pas bien le fonctionnement interne de ggplot mais cela fonctionne ...

 YMul <- 2

plotfunc <- function(Data){
    ggplot(Data,aes(x=x,y=y*YMul))+geom_line()
}

plotfunc(xy)
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X