为什么R对象比Stata / SPSS中的相同数据大得多?

时间:2015-04-23 11:10:00

标签: r memory survey

我的SPSSStata的调查数据大小为~730 MB。如果我正在处理这些数据,那么这些程序中的每一个程序也会占用内存中的大约空间(~800MB)。

我一直试图选择R,因此尝试将此数据加载到R。无论我尝试采用何种方法(read.dta文件中的statafread文件中的csvread.spss文件中的spssR对象(使用object.size()衡量)的大小介于2.6 to 3.1 GB之间。如果我将对象保存在R文件中,该文件小于100 MB,但在加载时,它与之前的大小相同。

使用调查包分析数据的任何尝试,特别是如果我尝试subset数据,都会比stata中的等效命令花费更长的时间。

例如,我的数据'hhpers'中有一个家庭大小变量'hh',按变量'hhwt'加权,子集加'htype'

R代码:

require(survey)
sv.design <- svydesign(ids =  ~0,data = hh, weights = hh$hhwt)
rm(hh)
system.time(svymean(~hhpers,sv.design[which
(sv.design$variables$htype=="rural"),]))

将R使用的内存推高到6 GB,需要很长时间 -  用户系统已过    3.70 1.75 144.11

stata中的等效操作

svy: mean hhpers if htype == 1

几乎瞬间完成,给我相同的结果。

为什么内存使用(按对象和函数)以及RStata之间的时间之间存在如此巨大的差异? 我可以做些什么来优化数据以及R如何使用它?

ETA:我的机器运行的是64位Windows 8.1,我在没有加载其他程序的情况下运行R.至少,R的环境与Stata的环境没有区别。

经过一番挖掘后,我预计造成这种情况的原因是R数据类型有限。我的所有数据都存储为int,每个元素需要4个字节。在调查数据中,每个响应都是分类编码的,通常只需要一个字节来存储,这些stata存储使用&#39;字节&#39;数据类型和R使用&#39; int&#39;数据类型,导致大型调查显着低效。

2 个答案:

答案 0 :(得分:1)

关于内存使用的差异 - 由于对象类型的原因,你在正确的轨道上(大部分)都是如此。实际上,整数节省会占用大量内存。因此,适当设置变量类型可以提高R的内存使用率。as.factor()会有所帮助。有关在读取数据后更新此的详细信息,请参阅?as.factor。要在从文件中读取数据期间修复此,请参阅colClasses的{​​{1}}参数(以及特定于stata和SPSS格式的类似函数)。这将有助于R更有效地存储数据(它对类型的即时猜测不是一流的)。

关于第二部分 - 计算速度 - 大数据集解析在基数R中并不完美,其中read.table()包很方便 - 它快速且与原始data.table行为非常相似。总结计算非常快。您可以通过data.frame使用它,您可以使用

计算与您的示例类似的内容
hh <- as.data.table(read.table(...))

抱歉,我不熟悉调查数据研究,所以我不能更具体。

按功能划分内存使用的另一个细节 - 很可能是R制作了整个数据集的副本来计算您要查找的摘要。同样,在这种情况下,hh <- as.data.table(hh) hh[htype == "rural",mean(hhpers*hhwt)] ## or hh[,mean(hhpers*hhwt),by=hhtype] # note 'empty' first argument 将有助于防止R制作过多的副本并提高内存使用率。

答案 1 :(得分:0)

感兴趣也可能是libbacktrace包,对我来说,导致比memisc更小的最终文件(但我的工作规模比你小)

来自read.spss小插曲

  

...因此,这个包提供了加载这些变量子集的工具,而无需加载完整的数据集。此外,从SPSS文件加载数据的方式使得保留有关变量标签,值标签和用户定义的缺失值的所有信息。这可以通过定义导入器对象来实现,其中存在子集方法。导入器对象仅包含有关外部数据集中的变量的信息,但不包含数据。当使用函数子集或as.data.set时,数据本身被加载到内存中。