首页 文章

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

提问于
浏览
154

编辑:哈德利威克姆指出我错过了 . 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.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()

但是 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 回答

  • 40

    你有两个解决方案:

    • 重写代码以避免非标准评估 . 对于ggplot2,这意味着使用 aes_string() 而不是 aes() (如Harlan所述)

    • 在包的顶层某处添加对 globalVariables(c("x.values", "y.values")) 的调用 .

    在提交给CRAN时,你应该在你的包裹中争取0注意,即使你必须做一些有点hacky的事情 . 这使CRAN的生活更轻松,也更容易 .

    (2014-12-31更新以反映我对此的最新想法)

  • 10

    你试过 aes_string 而不是 aes 吗?这应该工作,虽然我没有尝试过:

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

    这个问题前一段时间已被提出并得到解答,但仅供参考,因为version 2.1.0还有另一种方法可以解决这些问题: aes_(x=~x.values,y=~y.values).

  • 76

    如果

    getRversion() >= "3.1.0"
    

    您可以在包的顶层添加呼叫:

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

    从:

    help("suppressForeignCheck")
    

相关问题