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

yts*_*aig 65 r reference dataframe data.table

我有一个大型数据框(大约几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()
Run Code Online (Sandbox Code Playgroud)

随着输出:

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
Run Code Online (Sandbox Code Playgroud)

Aru*_*run 76

这可以从v1.9.0 +获得.来自新闻:

o在此SO帖子之后,setDT现在实现了一个函数,它接受list(命名和/或未命名),data.frame(或data.table)作为输入,并返回相同的对象作为data.table 引用(没有任何副本).请参阅?setDT示例了解更多信

这符合data.table命名约定 - 所有set*函数都通过引用进行修改.:=是唯一也通过引用修改的其他人.

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

查看较早(现已过时)答案的历史记录.

  • @eddi在R2.14.0之前,R的向量头的`truelength`成员没有被R初始化.在C中,如果你没有初始化一个变量,它有未定义的内容(无论发生在以前的那块RAM中).`data.table()`和类似的创建者在调用`alloc.col`之前将`truelength`初始化为0,以便与pre R 2.14.0兼容.`alloc.col`将`truelength`视为输入(0表示truelength == length).有一次我认为data.table需要依赖于R> = 2.14.0,因为这样,但设法保持R> = 2.12.0.我在每次发布到CRAN之前都使用R2.12.0进行测试. (3认同)
  • 也许来自Matthew的[this post](http://stackoverflow.com/questions/8077761/strange-difference-between-x-and-getx)将有助于更多地了解`truelength`. (2认同)