5

R は、小さなものであっても、整数ごとに 4 バイトのストレージを必要とするようです:

> object.size(rep(1L, 10000))
40040 bytes

さらに、要因についても:

> object.size(factor(rep(1L, 10000)))
40456 bytes

特に後者の場合、これははるかにうまく処理できると思います。この場合のストレージ要件を 1 行あたり 8 ビットまたは 2 ビットに減らすのに役立つソリューションはありますか? おそらく、rawストレージのために型を内部的に使用するソリューションですが、それ以外は通常の要素のように動作します。パッケージはビット単位でこれbitを提供しますが、同様の要因は見つかりませんでした。

数百万行しかない私のデータ フレームはギガバイトを消費しており、これはメモリと実行時間 (!) の膨大な浪費です。圧縮により、必要なディスク容量が削減されますが、やはり実行時間が犠牲になります。

関連している:

4

3 に答える 3

6

あなたが言及したのでraw(そして256未満の因子レベルがあると仮定して)-メモリがボトルネックであり、CPU時間がボトルネックでない場合は、前提条件の変換操作を実行できます。例えば:

f = factor(rep(1L, 1e5))
object.size(f)
# 400456 bytes

f.raw = as.raw(f)
object.size(f.raw)
#100040 bytes

# to go back:
identical(as.factor(as.integer(f.raw)), f)
#[1] TRUE

ファクターレベルを個別に保存して、興味がある場合はそれらを復元することもできますが、グループ化とすべてのことに関しては、すべてを行うことができraw、ファクターに戻ることはありません(プレゼンテーションを除く).

この方法で問題が発生する特定のユースケースがある場合は、投稿してください。そうでない場合は、これで問題なく機能すると思います。


byte.factorクラスの開始点は次のとおりです。

byte.factor = function(f) {
  res = as.raw(f)
  attr(res, "levels") <- levels(f)
  attr(res, "class") <- "byte.factor"
  res
}

as.factor.byte.factor = function(b) {
  factor(attributes(b)$levels[as.integer(b)], attributes(b)$levels)
}

したがって、次のようなことができます。

f = factor(c('a','b'), letters)
f
#[1] a b
#Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z

b = byte.factor(f)
b
#[1] 01 02
#attr(,"levels")
# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
#[20] "t" "u" "v" "w" "x" "y" "z"
#attr(,"class")
#[1] "byte.factor"

as.factor.byte.factor(b)
#[1] a b
#Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z

ジェネリックを作成し、追加したい関数を追加する場合は、data.tableオーバーライドの方法を確認してください。すべてが非常に簡単である必要があります。rbind.data.frameas.factor

于 2013-11-14T21:50:37.827 に答える
2

箱から少し外れていますが、ランレングス エンコーディングは、要素がある程度順序付けられている場合、数レベルの長い要素に適している可能性があります。これは、 BioconductorのIRangesパッケージでサポートできます。

rle = Rle(factor("A"), 1000000)
df = DataFrame(rle=rle)

> object.size(rle)
1528 bytes

DataFrameRleRle のサブセット化、追加など、すべての標準操作をサポートします。もちろん、サイズの節約は、ソートされた順序を維持することに大きく依存します。

于 2013-07-18T12:06:08.897 に答える