inst/extdata正如Jan所建议的那样,现在在dfunbindpackage中实现了按列存储在package目录中。
我正在使用这种data-raw惯用法来使从原始数据到结果的整个分析都可重现。为此,数据集首先包装在R包中,然后可以使用加载library()。
我使用的数据集之一比较庞大,大约有800万个观测值,其中包含约80个属性。对于当前的分析,我只需要一小部分属性,但是无论如何我都希望打包整个数据集。
现在,如果将其简单地打包为数据帧(例如,使用devtools::use_data()),则在首次访问它时将全部加载。打包此类数据以使我可以在列级别进行延迟加载的最佳方法是什么?(只有我实际访问的那些列被加载,其他列愉快地保留在磁盘上并且不占用RAM。)ff程序包对您有帮助吗?谁能指出我的工作范例?
我认为,我会将数据存储在中inst/extdata。然后在包中创建几个函数,这些函数可以读取和返回部分数据。在您的函数中,您可以使用来获取数据的路径system.file("extdata", "yourfile", package = "yourpackage")。(与您链接到的页面一样)。
然后的问题是,您以何种格式存储数据,以及如何在不读取内存中数据的情况下从中获取选择。为此,有很多选择。列举一些:
sqlite数据库中。然后,您可以使用rsqlite包对该数据执行查询。ff对象中(例如,使用save.ffdffrom中的函数进行保存ffbase;用于load.ffdf再次加载)。ff不能很好地处理字符字段(它们总是转换为因子)。从理论上讲,文件不是跨平台的,尽管只要您停留在intel平台上就可以。LaF软件包从该文件中进行选择。性能可能会比不上,ff但可能会足够好。saveRDS),并使用加载它们,readRDS其优点是您不依赖任何R包。很快 缺点是您不能进行行选择(但事实并非如此)。如果只想选择列,我将使用RDS。
以下代码创建一个包含虹膜数据集的示例程序包:
load_data <- function(dataset, columns) {
result <- vector("list", length(columns));
for (i in seq_along(columns)) {
col <- columns[i]
fn <- system.file("extdata", dataset, paste0(col, ".RDS"), package = "lazydata")
result[[i]] <- readRDS(fn)
}
names(result) <- columns
as.data.frame(result)
}
store_data <- function(package, name, data) {
dir <- file.path(package, "inst", "exdata", name)
dir.create(dir, recursive = TRUE)
for (col in names(data)) {
saveRDS(data[[col]], file.path(dir, paste0(col, ".RDS")))
}
}
packagename <- "lazyload"
package.skeleton(packagename, "load_data")
store_data(packagename, "iris", iris)
Run Code Online (Sandbox Code Playgroud)
构建和安装软件包后(您需要修复文档,例如删除它),您可以执行以下操作:
library(lazyload)
data <- load_data("iris", "Sepal.Width")
Run Code Online (Sandbox Code Playgroud)
加载Sepal.Width虹膜数据集的列。
当然,这是一个非常简单的实现load_data:没有错误处理,它假定所有列都存在,它不知道哪些列存在,它不知道哪些数据集存在。