EDIT: Хедлі Вікхем вказує, що я помиляюсь. R CMD перевірка кидає ПРИМІТКИ, а не попередження. Мені страшенно шкода плутанини. Це був мій нагляд.
Коротка версія
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'
Чому перевірка CM CMD правильна
Чек технічно правильний. x.values
іy.values
- Не визначено локально у функції
JitteredResponsesByContrast()
- Не заздалегідь визначено у формі
x.values <- [something]
ні в глобальному масштабі, ні в абонента.
Натомість вони є змінними всередині фрейму даних, який визначається раніше та передається у функцію JitteredResponsesByContrast()
.
Чому ggplot2 утруднює прихильність перевірки R CMD
ggplot2, здається, заохочує використання data
аргументу. Аргумент даних, імовірно, саме тому цей код буде виконуватися
library(ggplot2)
p <- ggplot(aes(x = hwy, y = cty), data = mpg)
p + geom_point()
але цей код призведе до помилки, що не знайдена:
library(ggplot2)
hwy # a variable in the mpg dataset
Дві роботи, і чому я задоволений жодним із них
Стратегія NULLing out
Меттью Даул рекомендує спочатку встановити проблемні змінні значення 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 перевіряти змінні, які, мабуть, інакше не знали б, що вони пов'язані) - Проблеми 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:
- Мені все-таки належить пройти кожну функцію елемента сюжету та обернути логіку під час
with()
виклику with()
Виклик в оману. Мені ще потрібно навестиdata =
аргумент; всеwith()
робиться приємноR CMD check
.
Висновок
Як я це бачу, я можу прийняти три варіанти:
- Лобіюйте CRAN ігнорувати нотатки, стверджуючи, що вони "фальшиві" (відповідно до політики CRAN ), і робити це щоразу, коли я надсилаю пакет
- Виправити код за допомогою однієї з двох небажаних стратегій (NULLing або
with()
блоки) - Хум справді голосно і сподіваюся, що проблема відходить
Жоден із трьох не робить мене щасливим, і мені цікаво, що люди пропонують мені (та іншим розробникам пакетів, які хочуть скористатися ggplot2). Дякуємо всім заздалегідь. Я дуже вдячний, що ви навіть прочитали це :-)
aes_string
transform
і subset
занадто (не на 100% впевнений, але це має сенс).