EDIT: Hadley Wickham points out that I misspoke. R CMD check is throwing NOTES, not Warnings. I'm terribly sorry for the confusion. It was my oversight.
简本
每次我在ggplot2中使用sensible plot-creation syntax时,R CMD check
都会抛出这个注释:
no visible binding for global variable [variable name]
我理解为什么R CMD check会这样做,但它似乎将所有其他合理的语法都定为犯罪.我不确定该采取什么措施才能让我的包裹通过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
两个变通办法,为什么我对两个都不满意
抵消策略
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()
调用将看到我们现在的空变量的期望(它不会),同时模糊了真正的目的(使R CMD check知道它显然不知道的变量是绑定的) - 1和2的问题会成倍增加,因为每次编写返回plot元素的函数时,都必须添加一个令人困惑的null语句
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()
真的解决了将解释器指向变量所在位置的问题,那么我甚至不应该need 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
因此,我再次认为,这种解决方案与零位策略有类似的缺陷:
- 我仍然需要遍历每个plot元素函数,并将逻辑封装在一个
with()
调用中 - 这
with()
个电话有误导性.我仍然需要提供data =
个论点;with()
人所做的只是安抚R CMD check
人.
结论
在我看来,我有三个 Select :
- 游说克兰忽略这些笔记,辩称它们是"虚假的"(根据CRAN policy),并在每次我提交包裹时都这样做
- 用两种不受欢迎的策略之一(置零或
with()
块)修复我的代码 - 大声哼唱,希望问题消失
这三个都不能让我高兴,我想知道人们建议我(以及其他想要进入ggplot2的包开发人员)应该做什么.