当我的ggplot2语法合理时,如何处理R CMD检查“全局variables没有可见的绑定”注释?
编辑:哈德利·韦翰指出,我错过了。 R CMD检查是抛出NOTES,而不是警告。 我非常抱歉的混淆。 这是我的疏忽。
简短的版本
R CMD check
每次在ggplot2中使用合理的绘图创build语法时都会抛出此注释:
no visible binding for global variable [variable name]
我明白为什么R CMD检查是这样做的,但是它似乎正在将整个语言的句法进行定罪。 我不确定要采取什么措施让我的包裹通过R CMD check
并获得CRAN的录取。
的背景
Sascha Epskamp以前发布了基本上相同的问题 。 我认为,区别在于subset()
的manpage 表示它是为交互使用而devise的 。
在我的情况下,这个问题不在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]
的forms预定义的。
相反,它们是先前定义的dataframe中的variables,并传递给函数JitteredResponsesByContrast()
。
为什么ggplot2难以安抚R CMD检查
ggplot2似乎鼓励使用data
参数。 数据参数,大概是这个代码执行的原因
library(ggplot2) p <- ggplot(aes(x = hwy, y = cty), data = mpg) p + geom_point()
但是这段代码会产生一个对象未find的错误:
library(ggplot2) hwy # a variable in the mpg dataset
两个解决方法,为什么我都不满意
空出策略
Matthew Dowlebuild议首先将有问题的variables设置为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)) ) ) }
我很欣赏这个解决scheme,但我不喜欢它有三个原因。
- 除了安排
R CMD check
之外,它没有其他用途。 - 它并不反映意图。 它提出了
aes()
调用将会看到我们现在为NULL的variables(它不会)的期望,同时掩盖了真正的目的(使得R CMD检查意识到它显然不会知道的variables被绑定) - 1和2的问题相乘,因为每次你写一个返回一个plot元素的函数时,你都必须添加一个混淆的NULLing语句
with()策略
你可以with()
一起使用来明确地表示有问题的variables可以在更大的环境中find。 在我的情况下,使用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)) ) } ) }
此解决scheme工作。 但是,我不喜欢这个解决scheme,因为它甚至不能像我期望的那样工作。 如果with()
真的解决了将解释器指向variables的地方,那么我甚至不需要 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
所以,我认为这个解决scheme与NULLing策略有类似的缺陷:
- 我仍然需要通过每个plot元素函数,并
with()
调用来包装逻辑 -
with()
调用是误导性的。 我仍然需要提供一个data =
参数; 所有with()
做的都是安抚R CMD check
。
结论
我看到的方式有三种select:
- 大厅CRAN通过争辩他们是“虚假的”(根据CRAN政策 )忽略笔记,并且每次我提交一个包裹
- 用两个不希望有的策略之一修正我的代码(NULL或
with()
块) - 呃,真的很大声,希望问题消失
三者中没有一个让我开心,我想知道人们build议我(和其他软件包开发人员想要使用ggplot2)应该做什么。 感谢所有提前。 我真的很感激你通过这个阅读:-)
你用aes_string
而不是aes
来aes_string
吗? 这应该工作,虽然我还没有尝试过:
aes_string(x = 'x.values', y = 'y.values')
你有两个解决scheme:
-
重写你的代码,以避免非标准的评估。 对于ggplot2,这意味着使用
aes_string()
而不是aes()
(如Harlan所述) -
添加一个调用
globalVariables(c("x.values", "y.values"))
在你的包的顶层。
提交给CRAN时,您应该在包装中争取0注释,即使您必须做一些有点冒险的事情。 这使得CRAN的生活更轻松,而且更容易。
(2014-12-31更新,以反映我对此的最新想法)
这个问题刚才已经被问到和回答了,但是从aes_(x=~x.values,y=~y.values).
还有另一种解决方法: aes_(x=~x.values,y=~y.values).
如果
getRversion() >= "3.1.0"
您可以在软件包的顶层添加一个呼叫:
utils::suppressForeignCheck(c("x.values", "y.values"))
从:
help("suppressForeignCheck")