EDIT: Hadley Wickham weist darauf hin, dass ich falsch geschrieben habe. R CMD-Prüfung löst NOTES aus, keine Warnungen. Die Verwirrung tut mir schrecklich leid. Es war mein Versehen.
Die Kurzversion
R CMD check
Wirft diese Notiz jedes Mal, wenn ich in ggplot2 eine sinnvolle Syntax zur Erstellung von Plots verwende:
no visible binding for global variable [variable name]
Ich verstehe, warum R CMD Check das tut, aber es scheint eine ganze Ader ansonsten vernünftiger Syntax zu kriminalisieren. Ich bin mir nicht sicher, welche Schritte ich unternehmen muss, um mein Paket zu bestehen R CMD check
und zu CRAN zugelassen zu werden.
Der Hintergrund
Sascha Epskamp hat zuvor im Wesentlichen das gleiche Thema gepostet . Ich denke, der Unterschied besteht darin, dass subset()
die Manpage besagt, dass sie für den interaktiven Gebrauch konzipiert ist .
In meinem Fall ist das Problem nicht vorbei, subset()
sondern über ein Kernmerkmal von ggplot2
: dem data =
Argument.
Ein Beispiel für Code, den ich schreibe und der diese Notizen generiert
Hier ist eine Unterfunktion in meinem Paket , die einem Plot Punkte hinzufügt:
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
wird beim Parsen dieses Codes sagen
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'x.values'
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'y.values'
Warum R CMD-Prüfung richtig ist
Die Prüfung ist technisch korrekt. x.values
undy.values
- Sind in der Funktion nicht lokal definiert
JitteredResponsesByContrast()
- Sind
x.values <- [something]
weder global noch im Aufrufer im Formular vordefiniert .
Stattdessen handelt es sich um Variablen innerhalb eines Datenrahmens, die früher definiert und an die Funktion übergeben werden JitteredResponsesByContrast()
.
Warum ggplot2 es schwierig macht, die R CMD-Prüfung zu beschwichtigen
ggplot2 scheint die Verwendung eines data
Arguments zu fördern . Das Datenargument ist vermutlich der Grund, warum dieser Code ausgeführt wird
library(ggplot2)
p <- ggplot(aes(x = hwy, y = cty), data = mpg)
p + geom_point()
aber dieser Code wird ein Objekt nicht gefunden - Fehler erzeugen:
library(ggplot2)
hwy # a variable in the mpg dataset
Zwei Workarounds, und warum ich mit keinem zufrieden bin
Die NULLing-Out-Strategie
Matthew Dowle empfiehlt , die problematischen Variablen zuerst auf NULL zu setzen, was in meinem Fall folgendermaßen aussehen würde:
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))
)
)
}
Ich schätze diese Lösung, aber ich mag sie aus drei Gründen nicht.
- es dient keinem zusätzlichen Zweck als dem Beschwichtigen
R CMD check
. - es spiegelt nicht die Absicht wider. Es erhöht die Erwartung, dass der
aes()
Aufruf unsere now-NULL-Variablen sieht (dies wird nicht der Fall sein), während der eigentliche Zweck verdeckt wird (wodurch die R CMD-Prüfung auf Variablen aufmerksam wird, von denen sie anscheinend sonst nicht wissen würde, dass sie gebunden sind). - Die Probleme von 1 und 2 multiplizieren sich, da Sie jedes Mal, wenn Sie eine Funktion schreiben, die ein Plotelement zurückgibt, eine verwirrende NULL-Anweisung hinzufügen müssen
Die with () Strategie
Sie können with()
damit explizit signalisieren, dass sich die betreffenden Variablen in einer größeren Umgebung befinden. In meinem Fall with()
sieht die Verwendung folgendermaßen aus:
JitteredResponsesByContrast <- function (data) {
with(data, {
geom_point(
aes(
x = x.values,
y = y.values
),
data = data,
position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
)
}
)
}
Diese Lösung funktioniert. Aber ich mag diese Lösung nicht, weil sie nicht einmal so funktioniert, wie ich es erwarten würde. Wenn with()
ich das Problem wirklich lösen würde, den Interpreter darauf zu richten, wo sich die Variablen befinden, sollte ich das Argument nicht einmal brauchendata =
. Funktioniert aber with()
nicht so:
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
Ich denke also, diese Lösung weist ähnliche Mängel auf wie die NULL-Strategie:
- Ich muss immer noch jede Plotelementfunktion durchgehen und die Logik in einen
with()
Aufruf einschließen - Der
with()
Anruf ist irreführend. Ich muss noch eindata =
Argument liefern ; alleswith()
was tut ist zu beschwichtigenR CMD check
.
Fazit
So wie ich das sehe, gibt es drei Möglichkeiten, die ich wählen könnte:
- Setzen Sie sich für CRAN ein, um die Notizen zu ignorieren, indem Sie argumentieren, dass sie "falsch" sind (gemäß der CRAN-Richtlinie ), und tun Sie dies jedes Mal, wenn ich ein Paket einreiche
- Korrigiere meinen Code mit einer von zwei unerwünschten Strategien (NULL oder
with()
Blöcke) - Summen Sie sehr laut und hoffen Sie, dass das Problem verschwindet
Keiner der drei macht mich glücklich und ich frage mich, was die Leute (und andere Paketentwickler, die auf ggplot2 zugreifen möchten) vorschlagen sollten. Vielen Dank an alle im Voraus. Ich freue mich sehr, dass Sie dies überhaupt durchgelesen haben :-)
aes_string
transform
und subset
zu (nicht 100% sicher, aber es macht Sinn).