小编典典

当我的 ggplot2 语法合理时,如何处理 R CMD 检查“全局变量没有可见绑定”注释?

all

编辑:Hadley Wickham 指出我说错了。 R CMD 检查是抛出注释,而不是警告。我对混乱感到非常抱歉。这是我的疏忽。

短版

R CMD check每次我在 ggplot2
中使用合理的绘图创建语法时都会抛出这个注释:

no visible binding for global variable [variable name]

我理解为什么 R CMD 检查会这样做,但它似乎将一整套原本合理的语法定为犯罪。我不确定要采取什么步骤才能让我的包裹通过R CMD check并被
CRAN 录取。

背景

Sascha Epskamp 此前曾发表过基本相同的问题。我认为不同之处在于subset()手册页上说它是为交互式使用而设计的。

subset是非交互式使用的潜在“意外后果”之一。正如它在警告部分所说?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'

为什么 R CMD 检查是正确的

检查在技术上是正确的。x.valuesy.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

两种解决方法,以及为什么我都不满意

归零策略

Matthew Dowle 建议首先将有问题的变量设置为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. 它不反映意图。它提高了调用将看到我们现在为 NULL 的变量的期望aes()(它不会),同时掩盖了真正的目的(使 R CMD 检查意识到它显然不会知道的变量是绑定的)
  3. 1 和 2 的问题成倍增加,因为每次编写返回绘图元素的函数时,都必须添加令人困惑的 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 策略有类似的缺陷:

  1. 我仍然需要遍历每个绘图元素函数并将逻辑包装在with()调用中
  2. with()电话具有误导性。我仍然需要提供一个data =论据;所做的一切with()都是安抚R CMD check

结论

在我看来,我可以采取三种选择:

  1. 游说 CRAN 通过辩称它们是“虚假的”(根据CRAN 政策)来忽略这些注释,并且每次我提交一个包时都这样做
  2. 使用两种不受欢迎的策略之一(NULLing 或with()blocks)修复我的代码
  3. 大声哼唱,希望问题消失

这三个都没有让我高兴,我想知道人们建议我(以及其他想要利用 ggplot2 的包开发人员)应该做什么。


阅读 67

收藏
2022-06-28

共1个答案

小编典典

你试过用aes_string代替aes吗?这应该可行,虽然我还没有尝试过:

aes_string(x = 'x.values', y = 'y.values')
2022-06-28