编辑:哈德利威克姆指出我错过了 . R CMD检查是投掷NOTES,而不是警告 . 我非常抱歉这种混乱 . 这是我的疏忽 .
简短版
每次我在ggplot2中使用sensible plot-creation syntax时, R CMD check
会抛出此注释:
no visible binding for global variable [variable name]
我理解为什么R CMD检查会这样做,但它似乎将整个其他合理语法的一部分定为犯罪 . 我不知道采取什么措施让我的包裹通过 R CMD check
并获准进入CRAN .
背景
Sascha Epskamp之前发布在essentially the same issue上 . 我认为,差异在于 subset()
的手册页says it's designed for interactive use .
在我的情况下,问题不是 subset()
,而是 ggplot2
的核心功能: data =
参数 .
我编写的代码示例生成这些注释
这是my package中的a sub-function,它为一个图添加了点:
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难以安抚R CMD检查
ggplot2似乎鼓励使用 data
参数 . 据推测,数据参数是此代码执行的原因
library(ggplot2)
p <- ggplot(aes(x = hwy, y = cty), data = mpg)
p + geom_point()
但是 this 代码会产生一个对象未找到的错误:
library(ggplot2)
hwy # a variable in the mpg dataset
两个解决方法,以及为什么我对两者都不满意
NULLing out策略
Matthew Dowle recommends首先将有问题的变量设置为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()
调用将看到我们现在为空的变量的期望(它赢得't), while obscuring the real purpose (making R CMD check aware of variables it apparently wouldn'否则知道已经绑定) -
1和2的问题相乘因为每次编写一个返回plot元素的函数时,都必须添加一个令人困惑的NULLing语句
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
所以,再次,我认为这个解决方案与NULLing策略有类似的缺陷:
-
我仍然需要遍历每个绘图元素函数并在
with()
调用中包装逻辑 -
with()
电话具有误导性 . 我仍然需要提供data =
参数;所有with()
正在做的是安抚R CMD check
.
结论
我看到它的方式,我可以采取三种选择:
-
大堂CRAN忽略这些说明,认为它们是"spurious"(依据CRAN policy),每次提交包裹时都这样做
-
使用两种不合需要的策略之一修复我的代码(NULLing或
with()
块) -
哼声非常响亮,希望问题消失
这三个人都没有让我高兴,我想知道人们建议我(以及其他想要利用ggplot2的软件包开发者)应该做些什么 . 感谢所有提前 . 我非常感谢你甚至通过这个阅读:-)
4 回答
你有两个解决方案:
重写代码以避免非标准评估 . 对于ggplot2,这意味着使用
aes_string()
而不是aes()
(如Harlan所述)在包的顶层某处添加对
globalVariables(c("x.values", "y.values"))
的调用 .在提交给CRAN时,你应该在你的包裹中争取0注意,即使你必须做一些有点hacky的事情 . 这使CRAN的生活更轻松,也更容易 .
(2014-12-31更新以反映我对此的最新想法)
你试过
aes_string
而不是aes
吗?这应该工作,虽然我没有尝试过:这个问题前一段时间已被提出并得到解答,但仅供参考,因为version 2.1.0还有另一种方法可以解决这些问题:
aes_(x=~x.values,y=~y.values).
如果
您可以在包的顶层添加呼叫:
从: