Как я могу обрабатывать R CMD для проверки заметок «нет видимой привязки для глобальной переменной», когда разумный синтаксис ggplot2?

EDIT: Хэдли Уикхэм указывает, что я оговорился. R CMD проверка бросает ПРИМЕЧАНИЯ, а не предупреждения. Мне ужасно жаль путаницы. Это был мой надзор.

Краткая версия

R CMD check эту заметку каждый раз, когда я использую разумный синтаксис создания сюжета в ggplot2:

 no visible binding for global variable [variable name] 

Я понимаю, почему R CMD проверяет это, но, похоже, это криминализирует всю жилу в противном случае разумного синтаксиса. Я не уверен, какие шаги нужно предпринять, чтобы мой пакет прошел R CMD check и попал в CRAN.

Фон

Sascha Epskamp ранее размещал по существу ту же самую проблему . Разница, я думаю, в том, что man-страница 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 при parsingе этого кода скажет

 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 затрудняет утилизацию проверки 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 

Два обхода, и почему я не доволен ни тем, ни другим

Страtagsя 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)) ) ) } 

Я ценю это решение, но мне это не нравится по трем причинам.

  1. он не служит дополнительной целью, кроме умиротворяющей R CMD check .
  2. он не отражает намерения. Это вызывает ожидание того, что вызов aes() увидит наши переменные now-NULL (это будет не так), в то время как затенение реальной цели (проверка R CMD, известная о переменных, которые, по-видимому, не знали бы, была связана)
  3. Проблемы 1 и 2 умножаются, потому что каждый раз, когда вы пишете функцию, возвращающую элемент графика, вам нужно добавить запутанный оператор NULLing

Страtagsя with ()

Вы можете использовать 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 

Итак, опять же, я думаю, что это решение имеет схожие недостатки страtagsи NULLing:

  1. Мне все равно нужно пройти через каждую функцию элемента plot и обернуть логику в вызове with()
  2. Вызов with() вводит в заблуждение. Мне все еще нужно предоставить аргумент data = ; все with() делает, это успокаивающая R CMD check .

Вывод

То, как я это вижу, есть три варианта, которые я мог бы предпринять:

  1. Лобби CRAN игнорирует заметки, утверждая, что они «ложные» (в соответствии с политикой CRAN ) и делают это каждый раз, когда я отправляю пакет
  2. Исправьте мой код одной из двух нежелательных страtagsй (NULLing или with() блоками)
  3. Хум действительно громко и надеюсь, что проблема исчезнет

Ни один из трех не делает меня счастливым, и мне интересно, что люди предлагают мне (и другим разработчикам пакетов, которые хотят использовать ggplot2). Спасибо всем заблаговременно. Я очень благодарен за то, что вы даже читаете это 🙂

Вы пытались использовать aes_string вместо aes ? Это должно работать, хотя я не пробовал:

 aes_string(x = 'x.values', y = 'y.values') 

У вас есть два решения:

  • Перепишите код, чтобы избежать нестандартной оценки. Для ggplot2 это означает использование aes_string() вместо aes() (как описано Harlan)

  • Добавьте вызов globalVariables(c("x.values", "y.values")) где-то на верхнем уровне вашего пакета.

Вы должны стремиться к 0 ПРИМЕЧАНИЯ в вашем пакете при отправке в CRAN, даже если вам нужно сделать что-то немного взломанное. Это облегчает жизнь CRAN, и вам легче.

(Обновлено 2014-12-31, чтобы отразить мои последние мысли об этом)

Этот вопрос был задан и ответил некоторое время назад, но только FYI, начиная с версии 2.1.0 есть еще один способ обойти заметки: aes_(x=~x.values,y=~y.values).

Если

 getRversion() >= "3.1.0" 

Вы можете добавить вызов на верхний уровень пакета:

 utils::suppressForeignCheck(c("x.values", "y.values")) 

из:

 help("suppressForeignCheck") 
  • Страtagsи для чтения в CSV-файлах?
  • Создание бункеров из фрейма данных
  • Subset dataframe несколькими логическими условиями строк для удаления
  • Можно ли использовать dcast без агрегатной функции?
  • Создание нескольких графических элементов из R-функции
  • Как назначить функцию, возвращающую более одного значения?
  • передавая несколько аргументов FUN of lapply (и другие * применяются)
  • Заменить NA в столбце со значением в соседнем столбце
  • Сценарий расписания R с использованием cron
  • Как выполнить естественную сортировку?
  • Перестановка множества наборов измерительных столбцов (широкий формат) в отдельные столбцы (длинный формат)
  • Interesting Posts

    Преимущество подключения ноутбука для мониторинга через HDMI к VGA

    Ноутбук Samsung NP530 не может войти в настройку BIOS

    Как выбрать всех дочерних элементов элемента, кроме последнего дочернего элемента?

    Выделите пользовательский элемент списка, когда он длительный

    возможно равномерно распределять кнопки по ширине андроида linearlayout

    Как обрабатывать redirect Spring Boot в / error?

    Как использовать OAuth2RestTemplate?

    Лучшее регулярное выражение для проверки электронной почты в C #

    Как получить срез в виде массива в Rust?

    Awesome Window Manager – Правило, назначающее программы тегам

    Определение алгоритма сжатия изображения, используемого на изображениях TIFF

    Размер файла для файла ftp-сервера vs фактический размер файла

    Какая версия моей дебианской системы?

    Доступ к firebase.storage () с помощью AngularFire2 (Angular2 rc.5)

    Ошибка ASP.Net: «Тип« foo »существует как в« temp1.dll », так и в« temp2.dll »,

    Давайте будем гением компьютера.