218 votes

Comment puis-je gérer les notes de vérification CMD R "pas de liaison visible pour la variable globale" lorsque ma syntaxe ggplot2 est raisonnable?

EDIT: Hadley Wickham points que je me suis mal exprimée. R CMD check est en train de jeter des NOTES, pas de mises en garde. Je suis terriblement désolé pour la confusion. C'était mon contrôle.

La version courte

R CMD check lance cette remarque à chaque fois que je utiliser sensible parcelle de création de syntaxe dans ggplot2:

no visible binding for global variable [variable name]

Je comprends pourquoi la R CMD vérifier le fait, mais il semble être la criminalisation de toute une veine de autrement sensible de la syntaxe. Je ne suis pas sûr de ce que les mesures à prendre pour obtenir mon paquet à transmettre R CMD check et admis à CRAN.

L'arrière-plan

Sascha Epskamp précédemment publié sur essentiellement la même question. La différence, je pense, c'est qu' subset()'s man dit qu'il est conçu pour une utilisation interactive.

Dans mon cas, le problème n'est pas sur subset() , mais sur une caractéristique essentielle de l' ggplot2: data = argument.

Un exemple de code que j'ai écris qui génère ces notes

Voici une sous-fonction de mon colis qui ajoute des points à un complot:

JitteredResponsesByContrast <- function (data) {
  return(
    geom_point(
             aes(
               x = x.values, 
               y = y.values
             ),
             data     = data,
             position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
    )
  )
}

R CMD check, sur l'analyse de ce code, va dire

granovagg.contr : JitteredResponsesByContrast: no visible binding for
  global variable 'x.values'
granovagg.contr : JitteredResponsesByContrast: no visible binding for
  global variable 'y.values'

Pourquoi la R CMD check est à droite

Le chèque est techniquement correcte. x.values et y.values

  • Ne sont pas définies localement dans la fonction JitteredResponsesByContrast()
  • Ne sont pas pré-définis dans le formulaire x.values <- [something] soit globalement ou en l'appelant.

Au lieu de cela, ils sont variables au sein d'un dataframe que défini précédemment et est passé dans la fonction JitteredResponsesByContrast().

Pourquoi ggplot2 rend difficile pour apaiser R CMD check

ggplot2 semble encourager l'utilisation d'un data argument. Les données argument, sans doute, est pourquoi ce code s'exécute

library(ggplot2)
p <- ggplot(aes(x = hwy, y = cty), data = mpg)
p + geom_point()

mais ce code va produire un objet n'est pas trouvé d'erreur:

library(ggplot2)
hwy # a variable in the mpg dataset

Deux solutions de rechange, et pourquoi je suis heureux avec ni

Le Micropression stratégie

Matthieu Dowle recommande définition de la problématique des variables à NULL en premier, ce qui dans mon cas ressemble à ceci:

JitteredResponsesByContrast <- function (data) {
  x.values <- y.values <- NULL # Setting the variables to NULL first
  return(
    geom_point(
             aes(
               x = x.values, 
               y = y.values
             ),
             data     = data,
             position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
    )
  )
}

J'apprécie cette solution, mais je n'aime pas cela pour trois raisons.

  1. il ne sert aucun but supplémentaire au-delà de l'apaisement R CMD check.
  2. elle ne reflète pas l'intention. Il soulève l'espoir que l' aes() appel voir notre maintenant NULL variables (il ne va pas), tout en occultant le véritable but (faire de la recherche CMD check conscient de variables apparemment, il serait autrement pas possible de savoir ont été tenus de le faire)
  3. Les problèmes 1 et 2 se multiplier parce que chaque fois que vous écrivez une fonction qui retourne un élément de l'intrigue, vous devez ajouter une source de confusion Micropression déclaration

La avec la (les) stratégie

Vous pouvez utiliser with() explicitement signal que les variables en question peut être trouvé à l'intérieur de certains des plus grands de l'environnement. Dans mon cas, à l'aide de with() ressemble à ceci:

JitteredResponsesByContrast <- function (data) {
  with(data, {
      geom_point(
               aes(
                 x = x.values, 
                 y = y.values
               ),
               data     = data,
               position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
      )
    }
  )
}

Cette solution fonctionne. Mais, je n'aime pas cette solution car elle ne fonctionne même pas la façon dont je voudrais attendre d'elle. Si with() étaient vraiment résoudre le problème de pointage de l'interprète à l'endroit où les variables sont, ensuite, je n'aurais même pas besoin de l' data = argument. Mais, with() ne fonctionne pas de cette façon:

library(ggplot2)
p <- ggplot()
p <- p + with(mpg, geom_point(aes(x = hwy, y = cty)))
p # will generate an error saying `hwy` is not found

Donc, encore une fois, je pense que cette solution a les mêmes défauts à la Micropression stratégie:

  1. J'ai encore à parcourir chaque parcelle de l'élément de la fonction et de l'enveloppement de la logique dans un with() appel
  2. L' with() appel est trompeuse. J'ai encore besoin de fournir un data = de l'argument; tous with() fait à l'apaisement R CMD check.

Conclusion

La façon dont je le vois, il y a trois options que j'ai pu prendre:

  1. Hall d'CRAN pour ignorer la note, en affirmant qu'ils sont "fausses" (en vertu de l' CRAN de la politique), et de le faire à chaque fois que je soumettre un package
  2. Correction de mon code avec l'un des deux indésirables stratégies (Invalide ou with() blocs)
  3. Hum vraiment fort et j'espère que le problème disparaît

Aucun des trois me faire plaisir, et je me demandais ce que les gens suggèrent je (et d'autres paquets les développeurs souhaitent puiser dans ggplot2) faut le faire. Merci à tous à l'avance. J'apprécie vraiment votre même la lecture par le biais de ce :-)

103voto

hadley Points 33766

Ignorez simplement les notes. Ils n'empêcheront pas la soumission de votre colis, et ils sont fallacieux.

52voto

Harlan Points 5486

Avez-vous essayé avec aes_string au lieu de aes ? Cela devrait fonctionner, même si je ne l'ai pas essayé:

 aes_string(x = 'x.values', y = 'y.values')
 

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