我有一个程序包,该程序包从Internet抓取数据并根据函数调用显示其内容。但是最近我从CRAN收到一条消息,表明安装Binary构建时数据变得过时(因为在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上,我希望我已经提供了足够的数据来保存正在下载的问题。
谢谢!
答案 0 :(得分:3)
考虑将memoise
添加为依赖项,以便您可以使用最少的依赖项链免费获得会话内缓存,然后使用程序包环境和(仅出于娱乐目的)主动绑定。
创建新的环境(您可以将其粘贴在aaa.R
中)
.pkgenv <- new.env(parent=emptyenv())
现在,(例如,在zzz.R
中)设置一个执行表抓取的功能:
.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)
}
并“记住”它(同样在zzz.R
中):
get_tiboe_tables <- memoise::memoise(.get_tiboe_tables)
现在,创建一个活动绑定,该绑定将使我们像访问变量一样访问表(即不使用()
)。它比必要的要有趣得多(再次在zzz.R
中):
makeActiveBinding(
sym = "all_tables",
fun = function() get_tiboe_tables('https://www.tiobe.com/tiobe-index/'),
env = .pkgenv
)
现在,获取如下所示的值(注意,在“启动”缓存时,我们会收到“正在加载”消息:
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会话中,它将刷新表。这样,就可以在不滥用站点的情况下获得新数据。您也可以使用文件排序规则来代替分类名称黑客攻击。
请注意,您也可以导出活动绑定,然后用户可以像使用变量一样使用它,而不必像调用函数一样。
答案 1 :(得分:1)
实际上,我采用的方法与上述answer略有不同。这是与Thomas'comment相关的,原因是我不想添加memoise
作为依赖项并尝试了替代方法。
aaa.R
中创建新程序包: .pkgenv <- new.env(parent=emptyenv())
.onAttach()
中的zzz.R
将数据加载到环境中的表中.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()
自身内部创建新的环境。