每次加载包时从互联网下载新数据

Downloading new data from internet when package is loaded every time

我有一个包可以从互联网上抓取数据并根据函数调用显示其内容。但最近我从 CRAN 收到一条消息,当安装二进制构建时数据变得陈旧(因为在 utils.R 中提到了该功能并且它已经在构建时下载)。

在过去的几天里,我尝试了以下但没有成功:

这是当前的包文件:https://github.com/amrrs/tiobeindexr/tree/master/R

尝试过的解决方案:

zzz.r 文件:

.onLoad <- function (libname, pkgname)
{

  assign("newEnv", new.env(hash = TRUE, parent = parent.frame()))

  newEnv$.all_tablesx789  <- rvest::html_table(xml2::read_html('https://www.tiobe.com/tiobe-index/'))


}

核心代码中的函数之一。

hall_of_fame <- function() {

  #check_data()

  #.GlobalEnv$.all_tablesx789 <- check_data()

  newEnv$.all_tablesx789[[4]]

}

包构建良好,但找不到对象。错误如下:

Error in hall_of_fame() : object 'newEnv' not found

我只有几天时间将我的包裹保存在 CRAN 上,我希望我已经提供了足够的数据来保存正在下载的这个问题。

谢谢!

考虑添加 memoise 作为依赖项,这样您就可以使用最小的依赖链免费获得会话中缓存,然后使用包环境和(只是为了好玩)活动绑定。

创建新的环境(你可以把它贴在里面,比如说,aaa.R):

.pkgenv <- new.env(parent=emptyenv())

现在,(比如,在 zzz.R 中)设置一个执行 table 抓取的函数:

.get_tiboe_tables <- function(url) {
  message("Delete this since it's just to show caching works") # delete this
  content <- xml2::read_html(url)
  rvest::html_table(content)
}

和"memoise"它(同样,在zzz.R):

get_tiboe_tables <- memoise::memoise(.get_tiboe_tables)

现在,创建一个活动绑定,让我们像访问变量一样访问 table(即 w/o 和 ())。它比必要的 "fun" 多(同样,在 zzz.R 中):

makeActiveBinding(
  sym = "all_tables",
  fun = function() get_tiboe_tables('https://www.tiobe.com/tiobe-index/'),
  env = .pkgenv
)

现在,像这样获取值(注意我们获取 "loading" 消息,因为它 "primes" 缓存:

str(.pkgenv$all_tables, 1)
## Delete this since it's just to show caching works ** the loading msg
## List of 4
##  $ :'data.frame':    20 obs. of  6 variables:
##  $ :'data.frame':    30 obs. of  3 variables:
##  $ :'data.frame':    15 obs. of  8 variables:
##  $ :'data.frame':    15 obs. of  2 variables:

在后续调用中没有加载消息,因为它正在检索缓存值:

str(.pkgenv$all_tables, 1)
## List of 4
##  $ :'data.frame':    20 obs. of  6 variables:
##  $ :'data.frame':    30 obs. of  3 variables:
##  $ :'data.frame':    15 obs. of  8 variables:
##  $ :'data.frame':    15 obs. of  2 variables:

在下一个 R 会话中,它将刷新 tables。这样,就可以在不滥用网站的情况下获得最新数据。您也可以使用文件整理而不是排序名称黑客攻击。

请注意,您也可以导出活动绑定,然后您的用户可以像变量一样使用它,而不是像函数一样调用它。

实际上,我采用了与上述 . This is in reference with Thomas' 略有不同的方法,原因是我不想添加 memoise 作为依赖项并尝试了替代方法。

正在 aaa.R 中创建新包:

.pkgenv <- new.env(parent=emptyenv())

正在使用 zzz.R

中的 .onAttach() 将数据加载到环境中的表中
.onAttach <- function(libname, pkgname) {

  packageStartupMessage("Downloading TIOBE Index Data using your Internet...")

  tryCatch({
    .pkgenv$.get_tiboe_tables <- rvest::html_table(xml2::read_html("https://www.tiobe.com/tiobe-index/"))
  },
  error = function(e){
    packageStartupMessage("Downloading TIOBE Index data failed!")
    packageStartupMessage("Error Message:")
    packageStartupMessage(e)
    return(NA)
  })

}

我之前的错误似乎是我试图在 .onLoad() 内部创建新环境。