【问题标题】:Convert a data frame to a data.table without copy将数据框转换为 data.table 而无需复制
【发布时间】:2013-12-19 03:33:40
【问题描述】:

我有一个大数据框(大约几 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

【问题讨论】:

    标签: r dataframe reference data.table


    【解决方案1】:

    这可从v1.9.0+ 获得。来自NEWS

    o 在this S.O. post 之后,现在实现了一个函数setDT,它将list(命名和/或未命名)、data.frame(或data.table)作为输入并返回与@ 相同的对象987654329@ 参考(无任何副本)。有关更多信息,请参阅 ?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,因为数据框已经拥有这些并保留其余部分?
    • @YT,如果您的意思是将“data.frame”添加到“data.table”,那么您所说的当然是正确的。如果您的意思是 data.frames 列表,那么您必须在设置类和分配之前绑定它们(按列或按行)。
    • @Arun,我的意思是前者,一个 data.table 的单个数据框,我编辑了这个问题,希望能更好地反映它。再次感谢您的聪明解决方案,我可以按原样接受答案,或者如果您想编辑它以匹配修改后的问题,我可以等待。
    • 也许来自 Matthew 的 this post 将有助于更多地了解 truelength
    • @eddi 在 R2.14.0 之前,R 的向量头的 truelength 成员没有被 R 初始化。在 C 中,如果你不初始化一个变量,它有未定义的内容(无论发生什么在之前的那块 RAM 中)。 data.table() 和类似的创建者在调用 alloc.col 之前将 truelength 初始化为 0,以兼容 pre R 2.14.0。 alloc.coltruelength 视为输入(0 表示真实长度==长度)。有一次我认为data.table因此需要依赖R>=2.14.0,但设法保持它R>=2.12.0。在每次发布到 CRAN 之前,我都会使用 R2.12.0 进行测试。
    猜你喜欢
    • 2014-09-21
    • 2020-08-07
    • 2018-09-22
    • 2017-05-09
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 2013-06-27
    • 2021-10-21
    相关资源
    最近更新 更多