9

非常に大きなファイルを読み取ろうとして、data.table (1.8.8、R 3.0.1) で fread を使用しています。

問題のファイルには、313 行と最大 660 万列の数値データ行があり、ファイルは約 12 GB です。これは512GBのRAMを搭載したCentos 6.4です。

ファイルを読み込もうとすると:

g=fread('final.results',header=T,sep=' ')
'header' changed by user from 'auto' to TRUE
Error: protect(): protection stack overflow

R を --max-ppsize 500000 で起動しようとしましたが、これは最大ですが、同じエラーです。

また、スタックサイズを無制限に設定しようとしました

ulimit -s unlimited

仮想メモリは既に無制限に設定されています。

このサイズのファイルは非現実的ですか? かなり明白な何かを見逃しましたか?

4

1 に答える 1

7

R-Forge の v1.8.9 で修正されました。

  • では意図しない 50,000 列の制限が削除されましたfread。報告してくれた mpmorley に感謝します。テストが追加されました。

その理由は、fread.cソースでこの部分を間違えたからです。

// *********************************************************************
// Allocate columns for known nrow
// *********************************************************************
ans=PROTECT(allocVector(VECSXP,ncol));
protecti++;
setAttrib(ans,R_NamesSymbol,names);
for (i=0; i<ncol; i++) {
    thistype  = TypeSxp[ type[i] ];
    thiscol = PROTECT(allocVector(thistype,nrow));   // ** HERE **
    protecti++;
    if (type[i]==SXP_INT64)
        setAttrib(thiscol, R_ClassSymbol, ScalarString(mkChar("integer64")));
    SET_TRUELENGTH(thiscol, nrow);
    SET_VECTOR_ELT(ans,i,thiscol);
}

R-exts セクション 5.9.1によると、ループ内の PROTECT は必要ありません:

場合によっては、保護が本当に必要かどうかをより正確に追跡する必要があります。大量のオブジェクトが生成される状況には特に注意してください。ポインター保護スタックのサイズは固定されており (デフォルトは 10,000)、いっぱいになる可能性があります。その場合、目に見えるすべてのものを保護し、最後に数千のオブジェクトを保護解除することはお勧めできません。ほとんどの場合、オブジェクトを別のオブジェクトの一部として割り当てる (自動的に保護する) か、使用後すぐに保護を解除することができます。

これで PROTECT が削除され、すべてが正常になりました。(そのテキストが書かれて以来、ポインター保護スタック制限は 50,000 に減らされたようです。Defn.h には が含まれています#define R_PPSSIZE 50000L。) data.table C ソース内の他のすべての PROTECT をチェックして、同様のものを見つけ、代入で 1 つを修正しました。 cも(参照によって50,000を超える列を追加する場合)、他にはありません。

ご報告ありがとうございます!

于 2013-08-26T20:28:25.473 に答える