EDYCJA: Hadley Wickham zwraca uwagę, że popełniłem błąd. R Kontrola CMD rzuca UWAGI, a nie Ostrzeżenia. Bardzo mi przykro z powodu zamieszania. To był mój niedopatrzenie.
Krótka wersja
R CMD check
rzuca tę notatkę za każdym razem, gdy używam rozsądnej składni tworzenia fabuły w ggplot2:
no visible binding for global variable [variable name]
Rozumiem, dlaczego R CMD to robi, ale wydaje się, że kryminalizacja całej żyły skądinąd sensownej składni. Nie jestem pewien, jakie kroki podjąć, aby moja paczka została przekazana R CMD check
i przyjęta do CRAN.
Tło
Sascha Epskamp poprzednio pisał na zasadniczo ten sam problem . Myślę, że różnica polega na tym, że subset()
strona ta mówi, że została zaprojektowana do użytku interaktywnego .
W moim przypadku kwestia ta nie jest zakończona, subset()
ale dotyczy podstawowej cechy ggplot2
: data =
argumentu.
Przykład kodu, który piszę, który generuje te notatki
Oto podfunkcja w moim pakiecie, która dodaje punkty do wykresu:
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
, podczas analizowania tego kodu, powie
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'x.values'
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'y.values'
Dlaczego sprawdzenie R CMD jest prawidłowe
Sprawdzenie jest technicznie prawidłowe. x.values
iy.values
- Nie są zdefiniowane lokalnie w funkcji
JitteredResponsesByContrast()
- Nie są wstępnie zdefiniowane
x.values <- [something]
ani w formie globalnej, ani w dzwoniącym.
Zamiast tego są zmiennymi w ramce danych, która została wcześniej zdefiniowana i przekazana do funkcji JitteredResponsesByContrast()
.
Dlaczego ggplot2 utrudnia złagodzenie kontroli R CMD
ggplot2 wydaje się zachęcać do użycia data
argumentu. Argument data prawdopodobnie przypuszczalnie powoduje wykonanie tego kodu
library(ggplot2)
p <- ggplot(aes(x = hwy, y = cty), data = mpg)
p + geom_point()
ale ten kod wygeneruje błąd „nie znaleziono obiektu”:
library(ggplot2)
hwy # a variable in the mpg dataset
Dwa obejścia i dlaczego nie jestem zadowolony z żadnego
Strategia NULLing out
Matthew Dowle zaleca najpierw ustawienie problematycznych zmiennych na NULL, co w moim przypadku wyglądałoby tak:
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))
)
)
}
Doceniam to rozwiązanie, ale nie podoba mi się to z trzech powodów.
- nie służy żadnemu dodatkowemu celowi poza uspokajaniem
R CMD check
. - nie odzwierciedla intencji. Rodzi to oczekiwanie, że
aes()
wywołanie zobaczy nasze zmienne NULL (nie zrobi tego), jednocześnie zaciemniając prawdziwy cel (uświadomienie R CMD zmiennych, o których inaczej nie wiedziałby, że byłyby związane) - Problemy 1 i 2 mnożą się, ponieważ za każdym razem, gdy piszesz funkcję zwracającą element wydruku, musisz dodawać mylącą instrukcję NULLing
Strategia with ()
Możesz użyć with()
do jawnego zasygnalizowania, że zmienne, o których mowa, można znaleźć w większym środowisku. W moim przypadku użycie with()
wygląda następująco:
JitteredResponsesByContrast <- function (data) {
with(data, {
geom_point(
aes(
x = x.values,
y = y.values
),
data = data,
position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
)
}
)
}
To rozwiązanie działa. Ale nie podoba mi się to rozwiązanie, ponieważ nie działa tak, jakbym tego oczekiwał. Jeśli with()
naprawdę rozwiązywania problemu wskazując tłumacza do miejsca, gdzie są zmienne, to nie powinien nawet trzeba ten data =
argument. Ale with()
to nie działa w ten sposób:
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
I znów myślę, że to rozwiązanie ma podobne wady do strategii NULLing:
- Nadal muszę przejść przez każdą funkcję elementu wykresu i zawrzeć logikę w
with()
wywołaniu with()
Rozmowa jest mylące. Nadal muszę przedstawićdata =
argument; wszystko cowith()
robi jest uspokajająceR CMD check
.
Wniosek
Z mojego punktu widzenia mogę wziąć trzy opcje:
- Zachęcaj CRAN do zignorowania notatek, argumentując, że są „fałszywe” (zgodnie z zasadami CRAN ) i rób to za każdym razem, gdy przesyłam paczkę
- Napraw mój kod za pomocą jednej z dwóch niepożądanych strategii (NULLing lub
with()
bloki) - Bucz się naprawdę głośno i mam nadzieję, że problem zniknie
Żadna z tych trzech rzeczy mnie nie uszczęśliwia i zastanawiam się, co ludzie sugerują, że ja (i inni programiści pakietów chcący skorzystać z ggplot2) powinienem zrobić. Dzięki wszystkim z góry. Naprawdę doceniam twoje nawet przeczytanie tego :-)
aes_string
transform
i subset
zbyt (nie 100% pewien, ale to ma sens).