EDIT: Hadley Wickham указывает, что я оговорился. R CMD check выдает NOTES, а не Warnings. Я ужасно извиняюсь за путаницу. Это был мой недосмотр.
R CMD check
выбрасывает это замечание каждый раз, когда я использую разумный синтаксис создания графиков в ggplot2:
no visible binding for global variable [variable name]
Я понимаю, почему R CMD check делает это, но, похоже, это криминализирует целый ряд других разумных синтаксисов. Я не уверен, какие шаги нужно предпринять, чтобы мой пакет прошел R CMD check
и был допущен в CRAN.
Саша Эпскамп ранее писал о по сути той же проблеме. Разница, я думаю, в том, что на manpage subset()
сказано, что он предназначен для интерактивного использования.
В моем случае проблема не в subset()
, а в основной возможности ggplot2
: аргументе data =
.
Вот подфункция в моем пакете, которая добавляет точки на график:
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
, разобрав этот код, скажет
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'x.values'
granovagg.contr : JitteredResponsesByContrast: no visible binding for
global variable 'y.values'
Проверка технически верна. x.values
и y.values
JitteredResponsesByContrast()
x.values ни глобально, ни в вызывающей функции.
Вместо этого они являются переменными внутри фрейма данных, который определяется ранее и передается в функцию JitteredResponsesByContrast()
.
ggplot2, похоже, поощряет использование аргумента data
. Аргумент data, предположительно, является причиной того, что этот код выполнится
library(ggplot2)
p <- ggplot(aes(x = hwy, y = cty), data = mpg)
p + geom_point()
но этот код выдаст ошибку object-not-found:
library(ggplot2)
hwy # a variable in the mpg dataset
Мэтью Доул рекомендует сначала установить проблемные переменные в NULL, что в моем случае будет выглядеть так:
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))
)
)
}
Я ценю это решение, но оно мне не нравится по трем причинам.
R CMD check
. aes()
увидит наши теперь уже NULL-переменные (это не так), скрывая при этом истинную цель (заставить R CMD check узнать о переменных, о которых он, очевидно, иначе не знал бы, что они связаны)Вы можете использовать with()
, чтобы явно сигнализировать, что переменные, о которых идет речь, могут быть найдены внутри некоторого большего окружения. В моем случае использование with()
выглядит так:
JitteredResponsesByContrast <- function (data) {
with(data, {
geom_point(
aes(
x = x.values,
y = y.values
),
data = data,
position = position_jitter(height = 0, width = GetDegreeOfJitter(jj))
)
}
)
}
Это решение работает. Но мне не нравится это решение, потому что оно работает не так, как я ожидал. Если бы with()
действительно решала проблему указания интерпретатору на то, где находятся переменные, то мне даже не нужен аргумент data =
. Но with()
так не работает:
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
Поэтому, опять же, я думаю, что это решение имеет те же недостатки, что и стратегия NULLing:
with()
with()
вводит в заблуждение. Мне все еще нужно предоставить аргумент data =
; все, что делает with()
- это успокаивает R CMD check
. Как я это вижу, есть три варианта, которые я могу предпринять:
with()
блоки)Ни один из этих трех вариантов не делает меня счастливым, и мне интересно, что люди предлагают мне (и другим разработчикам пакетов, желающим использовать ggplot2) делать. Заранее спасибо всем. Я очень ценю, что вы даже читаете это :-)