【问题标题】:Object State inside of R packageR包内的对象状态
【发布时间】:2025-12-03 16:15:01
【问题描述】:

我正在构建一个像这样获取数据的 R 包。

getdata <- function(uri ="dummyuri.csv"){
  httr::GET(url = uri)
}

这是一个昂贵的调用,所以我想在第一次调用后缓存数据。因此,除非您明确声明,否则您会在第一次调用后从包环境中获取它的本地副本。

所以我的目标是将这个对象包含在包环境中。我如何以符合 cra 的方式实现这一目标?

我花了很多时间looking up environments in advanced r,但似乎无法理解如何实现这一点。

【问题讨论】:

  • ggmap::geocode 将最后一次调用存储为全局环境中的不可见变量,这显然是合法的,但作为用户,我觉得不太理想。更改包的环境可能是不可能的,尽管您可以使用临时文件,将路径作为环境变量存储在 options 中。
  • 感谢您的示例,我可能会以这种方式解决问题。我认为用不可见的变量污染全局环境是不行的......鉴于取消附加包可能不会删除所述变量。这可能很幼稚,但我认为封装将是包的关键。
  • 查看?ns-hooks;我想你可以指定用.onUnload 删除它。
  • 谢谢,我去看看。我仍然认为这通常是危险的,因为它需要成功卸载包并且作者跟踪全局环境中的所有对象。
  • 哦!这是一个更好的方法:github.com/r-lib/memoise

标签: r r-package


【解决方案1】:

local() 调用中创建您的getdata 函数,并让它将值写入本地环境。例如,

getdata <- local({
  cache <- NULL
  cachedURI <- NULL
  function(uri ="dummyuri.csv") {
    if (is.null(cache) || cachedURI != uri) {
      cache <<- httr::GET(url = uri)
      cachedURI <<- uri
    }
    cache
  }
})

这会将getdata 的环境设置为local 创建的环境,其父级是包环境。您可以修改本地版本,而不必担心任何人的投诉。

【讨论】: