我在data.table(1.8.8,R 3.0.1)中使用fread试图读取非常大的文件。
问题中的文件有313行和~660万列数字数据行,文件大约为12gb。这是一款带有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
我尝试使用--max-ppsize 500000启动R,这是最大值,但是相同的错误。
我还尝试通过
将堆栈大小设置为无限制ulimit -s unlimited
虚拟内存已设置为无限制。
我对这么大的档案不切实际吗?我错过了一些相当明显的东西吗?
答案 0 :(得分:6)
现在已在R-Forge的v1.8.9中修复。
fread
已删除意外的50,000列限制。感谢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 section 5.9.1,不需要循环内的PROTECT:
在某些情况下,有必要更好地跟踪是否真的需要保护。是 特别注意生成大量对象的情况。指针 保护堆栈具有固定大小(默认为10,000)并且可以变满。这不是一个好主意 然后只是保护视线中的一切,并在最后完成数百件物品的保护。它 几乎总是可以将对象分配为另一个对象的一部分(哪个 自动保护它们)或在使用后立即取消保护。
所以现在删除了PROTECT,一切都很顺利。 (似乎指针保护堆栈限制已经减少到50,000,因为该文本被写入; Defn.h包含#define R_PPSSIZE 50000L
。)我已经检查了data.table C源代码中的所有其他PROTECT,用于任何类似的,找到的和修复了一个在assign.c中(当通过引用添加超过50,000列时),没有其他列。
感谢报道!