EDIT: Hadley Wickham souligne que je me suis mal exprimé. Le contrôle R CMD lance des NOTES, pas des avertissements. Je suis terriblement désolé pour la confusion. C'était ma faute.
La version courte
R CMD check
jette cette note chaque fois que j'utilise une syntaxe de création de tracé sensible dans ggplot2:
no visible binding for global variable [variable name]
Je comprends pourquoi R CMD check fait cela, mais cela semble criminaliser toute une veine de syntaxe autrement sensée. Je ne sais pas quelles mesures prendre pour que mon colis soit accepté R CMD check
et admis au CRAN.
L'arrière-plan
Sascha Epskamp a déjà publié essentiellement sur le même problème . La différence, je pense, est que subset()
la page de manuel dit qu'elle est conçue pour une utilisation interactive .
Dans mon cas, la question n'est pas terminée, subset()
mais sur une caractéristique essentielle de ggplot2
: l' data =
argument.
Un exemple de code que j'écris qui génère ces notes
Voici une sous-fonction dans mon package qui ajoute des points à un tracé:
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
, en analysant ce code, dira
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'x.values'
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'y.values'
Pourquoi le contrôle R CMD est correct
Le contrôle est techniquement correct. x.values
ety.values
- Ne sont pas définis localement dans la fonction
JitteredResponsesByContrast()
- Ne sont pas prédéfinis dans le formulaire
x.values <- [something]
ni globalement ni dans l'appelant.
Au lieu de cela, ce sont des variables dans une trame de données qui est définie plus tôt et transmise à la fonction JitteredResponsesByContrast()
.
Pourquoi ggplot2 rend difficile la vérification de R CMD
ggplot2 semble encourager l'utilisation d'un data
argument. L'argument data est probablement la raison pour laquelle ce code s'exécutera
library(ggplot2)
p <- ggplot(aes(x = hwy, y = cty), data = mpg)
p + geom_point()
mais ce code produira une erreur d'objet introuvable:
library(ggplot2)
hwy # a variable in the mpg dataset
Deux solutions de contournement et pourquoi je ne suis satisfait ni de l'un ni de l'autre
La stratégie NULLing out
Matthew Dowle recommande de définir d'abord les variables problématiques sur NULL, ce qui dans mon cas ressemblerait à 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 ne l'aime pas pour trois raisons.
- il ne sert à rien d'autre que l'apaisement
R CMD check
. - cela ne reflète pas l'intention. Cela laisse espérer que l'
aes()
appel verra nos variables maintenant NULL (ce ne sera pas le cas), tout en obscurcissant le but réel (rendant la vérification R CMD consciente des variables qu'il ne saurait apparemment pas autrement être liées) - Les problèmes de 1 et 2 se multiplient car chaque fois que vous écrivez une fonction qui renvoie un élément de tracé, vous devez ajouter une instruction NULL déroutante
La stratégie with ()
Vous pouvez utiliser with()
pour signaler explicitement que les variables en question peuvent être trouvées dans un environnement plus large. Dans mon cas, l'utilisation 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 comme je m'y attendais. Si with()
je résolvais vraiment le problème de pointer l'interpréteur vers où se trouvent les variables, alors je ne devrais même pas avoir besoin de l' data =
argument. Mais with()
cela 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 des défauts similaires à la stratégie NULLing:
- Je dois encore parcourir chaque fonction d'élément de tracé et envelopper la logique dans un
with()
appel - L'
with()
appel est trompeur. J'ai encore besoin de fournir undata =
argument; toutwith()
est apaisantR CMD check
.
Conclusion
D'après moi, il y a trois options que je pourrais prendre:
- Faites pression sur CRAN pour qu'il ignore les notes en faisant valoir qu'elles sont "fausses" (conformément à la politique CRAN ), et faites-le chaque fois que je soumets un colis
- Corrigez mon code avec l'une des deux stratégies indésirables (NULLing ou
with()
blocs) - Hum très fort et j'espère que le problème disparaîtra
Aucun des trois ne me rend heureux, et je me demande ce que les gens suggèrent que je (et les autres développeurs de paquets souhaitant exploiter ggplot2) devrais faire. Merci à tous d'avance. J'apprécie vraiment votre lecture même de ceci :-)
aes_string
transform
et subset
aussi (pas sûr à 100%, mais cela a du sens).