程序包的
inst/extdata
目录中的逐列存储,suggested by Jan,现在已在dfunbind
package中实现。
我使用data-raw
idiom从原始数据到结果可重复进行整个分析。为此,数据集首先包装在R包中,然后可以使用library()
加载。
我使用的其中一个数据集很大,大约有800万个观测值,大约有80个属性。对于我目前的分析,我只需要一小部分属性,但我还是要打包整个数据集。
现在,如果将其简单地打包为数据帧(例如,使用devtools::use_data()
),则在首次访问时将完整地加载它。打包这种数据的最佳方法是什么,以便我可以在列级别进行延迟加载? (只有我实际访问的那些列才会被加载,其他列很高兴留在磁盘上并且不会占用RAM。)ff
package会有帮助吗?有人能指出我一个有效的例子吗?
答案 0 :(得分:4)
我想,我会将数据存储在inst/extdata
中。然后在包中创建一些可以读取和返回部分数据的函数。在您的功能中,您可以使用system.file("extdata", "yourfile", package = "yourpackage")
获取数据路径。 (与您链接的页面一样)。
问题在于您存储数据的格式,以及如何在不读取内存中的数据的情况下从中获取选择。为此,有很多选择。为某些人命名:
sqlite
数据库中。然后,您可以使用rsqlite
包对此数据执行查询。 ff
个对象中(例如,使用save.ffdf
中的ffbase
函数进行保存;再次使用load.ffdf
加载) 。 ff
没有很好地处理字符字段(它们总是转换为因子)。从理论上讲,这些文件并不是跨平台的,尽管只要你留在英特尔平台上就应该没问题。 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)
在构建和安装软件包之后(您需要修复文档,例如删除它),您可以执行以下操作:
library(lazyload)
data <- load_data("iris", "Sepal.Width")
加载虹膜数据集的Sepal.Width
列。
当然这是load_data
的一个非常简单的实现:没有错误处理,它假定所有列都存在,它不知道哪些列存在,它不知道存在哪些数据集。