コピーせずにデータフレームをdata.tableに変換します


81

に変換したい大きなデータフレーム(数GBのオーダー)がありdata.tableます。を使用as.data.tableすると、データフレームのコピーが作成されます。つまり、データの少なくとも2倍のサイズの使用可能なメモリが必要です。コピーなしで変換を行う方法はありますか?

簡単な例を次に示します。

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

回答:


93

これはv1.9.0 +から利用できます。ニュースから:

oこのSO投稿に続いsetDTlist(名前付きおよび/または名前なし)、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*

古い(現在は古くなっている)回答については、履歴を参照してください。


@アルン:詳細な回答をありがとう。実際にデータフレームをdata.tableに変換する方法を尋ねていましたが、おもちゃの例を作成するのが面倒だったので、質問を更新してデータフレームにします。同じアイデアがデータフレームでも機能しますか?たとえば、データフレームにはすでにこれらが含まれているため、最初の2つのsetattrを削除し、残りを保持しますか?
ytsaig 2013

@YT、「data.frame」を「data.table」に取得することを意味する場合は、もちろんあなたの言うことは正しいです。data.framesのリストを意味する場合は、クラスを設定して割り当てる前に、それらを(列または行ごとに)バインドする必要があります。
アルン

@Arun、私は前者、data.tableへの単一のデータフレームを意味しました。うまくいけばそれをよりよく反映するように質問を編集しました。賢い解決策を再度ありがとう、私は答えをそのまま受け入れるか、改訂された質問に一致するようにそれを編集したい場合は待つことができます。
ytsaig 2013

2
たぶん、マシューからのこの投稿は、にもっと光を当てるのに役立つでしょうtruelength
アルン

3
@eddi R2.14.0より前truelengthは、RのベクターヘッダーのメンバーはRによって初期化されていませんでした。Cでは、変数を初期化しないと、内容が未定義になります(以前にRAMのチャンクにあったものは何でも)。data.table()および同様のクリエーターは、R2.14.0より前の互換性をtruelength要求alloc.colする前に0に初期化します。alloc.coltruelength入力(0平均truelength ==長さに取られる)として。ある時点で、data.tableはこのためR> = 2.14.0に依存する必要があると思いましたが、R> = 2.12.0を維持することができました。CRANにリリースする前に、R2.12.0でテストします。
Matt Dowle
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.