您如何管理在 R 中生成大数据表? (不在大桌子上阅读)

Posted

技术标签:

【中文标题】您如何管理在 R 中生成大数据表? (不在大桌子上阅读)【英文标题】:How can you manage generating big data.tables in R? (not reading in big tables) 【发布时间】:2012-11-21 17:01:20 【问题描述】:

我一直在寻找解决此问题的方法,但似乎找不到任何东西。

基本上,我有一段代码希望扩展到大数据,代码的示例摘录如下:

num_train <- 100
num_test <- 100

train <- data.table(k = rep(1,num_train), ID_train = 1:num_train, b_train = rnorm(num_train), c_train = rnorm(num_train), cat = sample(c("A", "B", "C", "D"), num_train, replace = TRUE))
test <- data.table(k = rep(1,num_test), ID_test = 1:num_test, b_test = rnorm(num_test), c_test = rnorm(num_test))

df <- merge(test,train, by="k")

当我在更大的数据上使用它时,它完全按照我想要的方式运行并且速度非常快。 (可能和 num_train * num_test = 2,000,000,000 一样大...)

但是问题是生成的数据表增长了 num_train*num_test 行,所以很快就太大了,R 无法处理。

num_train <- 1000
num_test <- 10000

train <- data.table(k = rep(1,num_train), ID_train = 1:num_train, b_train = rnorm(num_train), c_train = rnorm(num_train), cat = sample(c("A", "B", "C", "D"), num_train, replace = TRUE))
test <- data.table(k = rep(1,num_test), ID_test = 1:num_test, b_test = rnorm(num_test), c_test = rnorm(num_test))

df <- merge(test,train, by="k")

>Error: cannot allocate vector of size 76.3 Mb

我知道 R 和包的所有内存限制,例如 filehash、ff 和 bigmemory(不太熟悉,已经使用了一些)。这些似乎允许您将大文件设置为数据库并有效地从中读取数据。

但基本上我想知道的是,有没有办法从已经在内存中的表中管理 创建一个大表,比如在创建时将它的一部分写入硬盘?这些软件包中的任何一个都适用于此吗?还有其他解决方案吗?

还是说这份工作不适合 R?

干杯!

【问题讨论】:

计算出在不使计算机内存超载的情况下可以存储多少“块”,然后一次创建一个块——将其附加到 ff、大内存或数据库支持 (sql)不占用内存中任何空间的表。然后删除内存中的当前块,然后继续下一个。 谢谢,这是我现在正在研究的一种方法。出于我正在做的事情的目的,我可以分块处理它,但只能处理测试数据集。它需要应用于整个训练数据集。因此,当训练数据集大于 10,000 时,我需要将训练数据集分块为 500 行以下的块并循环遍历,直到所有内容都被处理……这否定了使用 data.tables 包实现的速度。 好问题。同意安东尼。我做了一个快速计算:2e9 * 9 columns * 8 bytes / 1024^3 = 134 GB,所以是的,你正在调查你提到的包。除非你能找到一台有这么多内存的机器,或者一个可以在集群或其他东西上分配给你的虚拟机。这是 Revolution 提供(闭源)工具的领域。 代替merge(x,y) 或许可以尝试x[y,&lt;process chunk&gt;] 语法。这就是 by-without-by(参见?data.table)可能会给你一个分块的机会。 【参考方案1】:

您可以为此使用包 ff 和 ffbase。它不需要像 data.table 那样将您的数据存储在 RAM 中。 以下脚本将生成您的 10Mio 行 x 10 列 data.frame。

num_train <- 1000
num_test <- 10000
train <- data.table(k = rep(1,num_train), ID_train = 1:num_train, b_train =     rnorm(num_train), c_train = rnorm(num_train), cat = sample(c("A", "B", "C", "D"), num_train,     replace = TRUE))
test <- data.table(k = rep(1,num_test), ID_test = 1:num_test, b_test = rnorm(num_test),     c_test = rnorm(num_test))


train <- data.frame(unclass(train), stringsAsFactors=TRUE)
test <- data.frame(unclass(test), stringsAsFactors=TRUE)
require(ffbase)
train$id <- seq_len(nrow(train))
test$id <- seq_len(nrow(test))
train <- as.ffdf(data.frame(train, stringsAsFactors=TRUE))
test <- as.ffdf(data.frame(test, stringsAsFactors=TRUE))
x <- expand.ffgrid(train$id, test$id)
dim(x)
names(x) <- c("train.id", "test.id")
x <- merge(x, train, by.x="train.id", by.y="id", all.x=TRUE, all.y=FALSE)
x <- merge(x, test, by.x="test.id", by.y="id", all.x=TRUE, all.y=FALSE)
dim(x)
x[1:5, ]

【讨论】:

谢谢,我喜欢这个解决方案,我不完全确定发生了什么,但它似乎在您设置的示例中有效。我想知道的唯一想法是这将如何在速度方面进行扩展(特别是对于 10,000*10,000,expand.ffgrid() 步骤似乎相当慢)。这可以与任何地方的 data.tables 的速度相结合吗?看来我可以有一个好的速度/糟糕的内存解决方案或糟糕的速度/良好的内存...... 使用包 ff 和 ffbase 用于内存不足的解决方案。这意味着您的数据在磁盘上,将在 R 中按块加载并再次放入磁盘。当然,RAM 总是更快。如果您可以在 RAM 中获取所有数据,则不需要 ff/ffbase。所以速度也取决于你的硬盘。因此,与 SQL 或 SAS 进行比较更合适。但是为了争论,您可以执行以下操作。 system.time(x

以上是关于您如何管理在 R 中生成大数据表? (不在大桌子上阅读)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Dart 中生成大随机数?

如何使用操作按钮在 R Shiny 中显示和隐藏表格输出?

如何在不在 grails 中生成视图的情况下调用动作 [关闭]

如何在 R 中生成许多最独特的颜色?

大数据互联网机器人成大热门

如何不在 Python、Django 中生成两次相同的动态图像?