每次加载包时从互联网下载新数据
Downloading new data from internet when package is loaded every time
我有一个包可以从互联网上抓取数据并根据函数调用显示其内容。但最近我从 CRAN 收到一条消息,当安装二进制构建时数据变得陈旧(因为在 utils.R
中提到了该功能并且它已经在构建时下载)。
在过去的几天里,我尝试了以下但没有成功:
- 全局变量使用
<<-
但它生成了一个 CRAN 注释,我也经历了一些建议反对该方法的答案
注:no visible binding for global variable
- 创建一个新环境,然后在其中添加这个下载的对象,但它从来没有成功,因为我无法在其他函数中访问该对象。参考:
这是当前的包文件: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()
内部创建新环境。
我有一个包可以从互联网上抓取数据并根据函数调用显示其内容。但最近我从 CRAN 收到一条消息,当安装二进制构建时数据变得陈旧(因为在 utils.R
中提到了该功能并且它已经在构建时下载)。
在过去的几天里,我尝试了以下但没有成功:
- 全局变量使用
<<-
但它生成了一个 CRAN 注释,我也经历了一些建议反对该方法的答案 注:no visible binding for global variable
- 创建一个新环境,然后在其中添加这个下载的对象,但它从来没有成功,因为我无法在其他函数中访问该对象。参考:
这是当前的包文件: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。这样,就可以在不滥用网站的情况下获得最新数据。您也可以使用文件整理而不是排序名称黑客攻击。
请注意,您也可以导出活动绑定,然后您的用户可以像变量一样使用它,而不是像函数一样调用它。
实际上,我采用了与上述 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()
内部创建新环境。