400GBのRAMを搭載した64ビットUbuntu環境で64ビットR3.1を実行していますが、大きなマトリックスを処理するときに奇妙な制限が発生します。
Aという数値行列があります。これは4000行950,000列です。その中の要素にアクセスしようとすると、次のエラーが発生します。
Error: long vectors not supported yet: subset.c:733
私のマトリックスはscan
を介して読み込まれましたが、次のコードで複製できます
test <- matrix(1,4000,900000) #no error
test[1,1] #error
私のグーグルは、これがR 3.0より前の一般的なエラーメッセージであり、サイズ2 ^ 31-1のベクトルが限界であったことを明らかにしています。しかし、私の環境を考えると、これは当てはまりません。
この種の行列にネイティブ行列タイプを使用するべきではありませんか?
行列は、Rが行列としてアクセスできるようにする次元属性を持つ単なる原子ベクトルです。行列は、長さ4000*9000000
のベクトルです。これは3.6e+10
要素です(最大の整数値は約2.147e+9
です)。長いベクトルのサブセット化isアトミックベクトルでサポートされています(つまり、2.147e+9
制限を超えて要素にアクセスします)。行列を長いベクトルとして扱うだけです。
デフォルトでRが行列を列単位で埋めることを覚えている場合、たとえばtest[ 2701 , 850000 ]
の値を取得したい場合は、次の方法でアクセスできます。
i <- ( 2701 - 1 ) * 850000 + 2701
test[i]
#[1] 1
これは実際には長いベクトルサブセットであることに注意してください。理由は次のとおりです。
2701L * 850000L
#[1] NA
#Warning message:
#In 2701L * 850000L : NAs produced by integer overflow
別の簡単な解決策は、最初に行を取得し、次に行列の列(結果のベクトルのi番目の要素)を取得することです。例えば ...
test <- matrix(1,4000,900000) #no error
test[1,1] #error
test[1, ][1] # no error
もちろん、行全体が最初にコピー/アクセスされるため、これによってある程度のオーバーヘッドが発生しますが、読みやすくなります。また、最初に列を抽出し、次に行を抽出する場合にも機能します。