R中的Bootstrap采样大数据(太大而无法容纳在RAM中)

Ben*_*ert 0 r bigdata sampling

是否可以从.Rdata对象或存储在磁盘上的任何其他大型数据对象中绘制引导样本?我目前从非常大的数据中采样的方法是构建一个本地MySQL数据库,然后使用SQL将随机样本绘制到R中.不幸的是,MySQL中的采样和排序根本没有效率.我想知道是否有人为此用例设计了更好的解决方案.

要了解我当前的解决方案,请参阅MySQL中的采样问题: 来自Sql数据库的简单随机样本

Gab*_*rdi 5

一般评论

您不必将所有数据加载到样本,只需加载行的ID,并从ids中加样.然后仅加载采样行的数据.更详细:

  1. 例如,如果您ID在数据库中调用了一列,则只加载此列.这应该很快,特别是如果ID是一个整数.即使你有(比方说)20亿条记录,你只需要8GB内存来存储20亿个整数,所以这应该是可能的.

  2. 然后从这些ID中取样.

  3. 然后仅加载带有采样ID的记录.

考虑一下.如果你想从在线书店Siren购买三本随机书籍,你会怎么做?Siren有数百万本书,你不能订购它们,然后在它们之间随机选择,然后发回其余的,对吧?所以你要做的是,你向Siren索取书籍ID列表(ISBN会这样做),这个大小适合于适度的计算机.您可以从列表中随机选择三个,并从Siren中订购这三个.

Rdata文件

这显然不适用于.Rdata文件,但.Rdata文件无论如何都是无望的,因为你无法加载一段.Rdata文件.所以你需要一些索引的格式.

源码

但是你可以使用sqlite和RSQLite包.RSQLite支持与数据帧绑定,因此加载采样数据只需将采样的id放入一个名为samp_ids(单列命名id)的数据框中,然后说出类似的东西.

...
my_samp <- dbGetQuery(con, "SELECT * FROM mytable WHERE id = :id", 
                      bind.data = samp_ids)
...
Run Code Online (Sandbox Code Playgroud)

这将读取带有采样ID的记录.

MySQL的

我上次检查RMySQL时不支持绑定,所以这可能不是要走的路.如果你坚持使用MySQL,那么我要尝试的第一件事是创建一个临时表,其中只包含采样的行ID,然后将这个表与数据表一起加入.这是支持的RMySQL,它的工作原理如下:

dbSendQuery(con, "CREATE TEMPORARY TABLE tmp (id INTEGER);")

## Stupid, but this seems to be necessary to really create the
## temporary table, it is an RMySQL bug that I reported long time
## ago: https://github.com/jeffreyhorner/RMySQL/issues/10
try(dbSendQuery(con, "CREATE TEMPORARY TABLE tmp (id INTEGER);"))

dbWriteTable(con, "tmp", samp_ids, row.names=FALSE, append=TRUE)
Run Code Online (Sandbox Code Playgroud)

然后,您可以编写SELECT以加入临时表tmp和原始数据表.

  • 您是否想要扩展如何使用行ID来从未存储在内存中的对象中进行采样? (2认同)