将数据帧转换为data.table而不复制


81

我有一个很大的数据帧(大约数GB),我想将其转换为data.table。使用as.data.table创建数据帧的副本,这意味着我需要可用内存至少为数据大小的两倍。有没有复制的方法吗?

这是一个简单的示例来演示:

library(data.table)
N <- 1e6
K <- 1e2
data <- as.data.frame(rep(data.frame(rnorm(N)), K))

gc(reset=TRUE)
tracemem(data)
data <- as.data.table(data)
gc()

输出:

library(data.table)
# data.table 1.8.10  For help type: help("data.table")
N <- 1e6
K <- 1e2
data <- as.data.frame(rep(data.frame(rnorm(N)), K))

gc(reset=TRUE)
# used  (Mb) gc trigger   (Mb)  max used  (Mb)
# Ncells    303759  16.3     597831   32.0    303759  16.3
# Vcells 100442572 766.4  402928632 3074.2 100442572 766.4
tracemem(data)
# [1] "<0x363fda0>"
data <- as.data.table(data)
# tracemem[0x363fda0 -> 0x31e4260]: copy as.data.table.data.frame as.data.table 
gc()
# used  (Mb) gc trigger   (Mb)  max used   (Mb)
# Ncells    304519  16.3     597831   32.0    306162   16.4
# Vcells 100444242 766.4  322342905 2459.3 200933219 1533.0

Answers:


92

v1.9.0 +开始可用。来自新闻

o在此SO帖子之后setDT现在实现了一个函数,该函数以list(命名和/或未命名)data.frame(或data.table)作为输入,并返回与data.table by引用相同的对象(无任何副本)。有关?setDT更多信息,请参见示例。

这符合data.table命名约定-所有set*功能均按引用进行修改。:=是唯一也可以通过引用进行修改的其他内容。

require(data.table) # v1.9.0+
setDT(data) # converts data which is a data.frame to data.table *by reference*

查看历史记录以获取较旧(现已过时)的答案。


@Arun:感谢您的详细回答。我实际上是在问如何将数据帧转换为data.table,但是在创建玩具示例时草率地行事,我将更新问题以使其成为数据帧。相同的想法然后适用于数据帧吗,例如,由于数据帧已经具有前两个setattr而保留其余两个,则摆脱掉前两个setattr?
ytsaig 2013年

@YT,如果您的意思是将“ data.frame”添加到“ data.table”,那么您说的当然是正确的。如果要表示data.frame的列表,则必须在设置类和分配之前将它们绑定(列或行)。
阿伦(Arun)2013年

@Arun,我的意思是前者是data.table的单个数据帧,我编辑了问题以希望更好地反映它。再次感谢您提供一个聪明的解决方案,我可以按原样接受答案,或者如果您想对其进行修改以匹配修订后的问题,请稍候。
ytsaig 2013年

2
也许马修(Matthew)的这篇文章将有助于阐明更多truelength
阿伦(Arun)2013年

3
@eddi在R2.14.0之前,truelengthR的向量标头的成员未由R初始化。在C中,如果不初始化变量,则该变量具有未定义的内容(无论之前是否在该RAM块中)。data.table()和类似的创建者truelength在要求alloc.col与R 2.14.0之前的兼容性之前初始化为0 。alloc.col长相在truelength作为输入(0被认为是指truelength ==长度)。有一次,我认为data.table因此需要依赖R> = 2.14.0,但是设法使其保持R> = 2.12.0。在每次发布到CRAN之前,我都使用R2.12.0进行测试。
Matt Dowle 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.