РЕДАКТИРОВАТЬ: Хэдли Уикхэм указывает, что я оговорился. R CMD проверяет выбрасывание NOTES, а не предупреждений. Мне ужасно жаль за путаницу. Это был мой недосмотр.
Короткая версия
R CMD check
выдает эту заметку каждый раз, когда я использую разумный синтаксис создания графика в ggplot2:
no visible binding for global variable [variable name]
Я понимаю, почему проверка R CMD делает это, но, похоже, криминализирует всю вину разумного синтаксиса. Я не уверен, какие шаги предпринять, чтобы мой пакет прошел R CMD check
и был принят в CRAN.
Фон
Саша Эпскамп ранее публиковал по сути ту же проблему . Разница, я думаю, в том, что 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'
Почему R CMD проверка верна
Проверка технически верна. x.values
иy.values
- Не определены локально в функции
JitteredResponsesByContrast()
- Не определены заранее в форме
x.values <- [something]
ни глобально, ни в вызывающей стороне.
Вместо этого они являются переменными внутри фрейма данных, который определяется ранее и передается в функцию JitteredResponsesByContrast()
.
Почему ggplot2 мешает успокоить проверку CMD
ggplot2, кажется, поощряет использование data
аргумента. Предположительно, именно поэтому аргумент data будет выполнять этот код
library(ggplot2)
p <- ggplot(aes(x = hwy, y = cty), data = mpg)
p + geom_point()
но этот код выдаст ошибку «объект не найден»:
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()
вызов увидит наши переменные now-NULL (это не будет), в то же время скрывая реальную цель (делая проверку CMD R осведомленной о переменных, которые, по-видимому, иначе бы не знали, были связаны) - Проблемы 1 и 2 умножаются, потому что каждый раз, когда вы пишете функцию, которая возвращает элемент сюжета, вы должны добавить непонятный оператор NULLing
Стратегия с ()
Вы можете 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:
- Мне все еще нужно пройти через каждую функцию элемента plot и обернуть логику в
with()
вызов with()
Вызов в заблуждение. Мне все еще нужно предоставитьdata =
аргумент; всеwith()
это делает это умиротворениеR CMD check
.
Вывод
На мой взгляд, есть три варианта:
- Побуждайте CRAN игнорировать заметки, утверждая, что они «ложные» (согласно политике CRAN ), и делайте это каждый раз, когда я отправляю пакет
- Исправьте мой код с помощью одной из двух нежелательных стратегий (NULLing или
with()
блоков) - Гул очень громко и надеюсь, что проблема уходит
Ни один из трех не делает меня счастливым, и мне интересно, что люди предлагают мне (и другим разработчикам пакетов, желающим подключиться к ggplot2). Спасибо всем заранее. Я очень ценю, что вы даже читаете это :-)
aes_string
transform
иsubset
тоже (не уверен на 100%, но это имеет смысл).Ответы:
Вы пробовали с
aes_string
вместоaes
? Это должно работать, хотя я не пробовал:источник
aes
делает, покаaes_string
не определяет позиционные параметрыx
иy
.aes_string
гласит: «Все эти функции мягко осуждаются. Вместо этого, пожалуйста, используйте аккуратные идиомы оценки (см. Раздел квазиквотации в документации по aes ())». (ggplot2 версия 3.2.1). Это, вероятно, делаетrlang::.data
лучшим кандидатом, чтобы заставить замолчать эти заметки.