R CMD 检查注意:`没有全局变量的可见绑定`,在 S3 泛型中定义变量并在方法中使用它时

R CMD check NOTE: `No visible binding for global variable`, when defining a variable in an S3 generic and using it in a method

考虑以下代码:

greet <- function(object) {
        greeting <- "hola"
        UseMethod("greet", object)
}

greet.character <- function(object)
        paste(greeting, object)

greet("Whosebug")
#> [1] "hola Whosebug"

reprex package (v0.3.0)

于 2021-02-03 创建

显然,greet.character 方法的执行环境填充了泛型中创建的变量,在 UseMethod() 之前,因此代码按预期工作。

但是,在包中包含这些定义将导致在 R CMD 检查时出现以下注释:

> checking R code for possible problems ... NOTE
  greet.character: no visible binding for global variable ‘greeting’
  Undefined global functions or variables:
    greeting

您可以在 this repository 找到说明该问题的示例包。

现在,我知道我可以用globalVariables()关闭NOTE,但我仍然对NOTE最初的来源感到困惑。所以我的问题是:

  1. 上面的例子在 R 包中被认为是“不好的做法”有什么内在原因吗?在现实生活中的例子中,我使用这样的构造来避免在多个方法中重复代码。

  2. 如果没有,有没有比使用globalVariables()更好的选择?

回答我自己,我认为这种做法会导致令人困惑的行为,因为 UseMethod() 使用相同的参数生成适当方法的调用;暗示对泛型参数的变量的修改(不像上面示例中的greeting)不会传播到方法。

现在我正在定义要在每个方法开始时调用的额外函数,以执行我最初在泛型中执行的复杂计算。如果这些函数需要很多参数,这也会导致代码繁琐,但这是我目前找到的最佳解决方案。

我会把这个开放一段时间,看看是否有人可以提出其他方法。