【问题标题】:Why is an R object so much larger than the same data in Stata/SPSS?为什么 R 对象比 Stata/SPSS 中的相同数据大得多?
【发布时间】:2015-07-01 12:48:55
【问题描述】:

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

我一直在尝试获取R,因此尝试将此数据加载到R。无论我尝试什么方法(read.dta 来自stata 文件,fread 来自csv 文件,read.spss 来自spss 文件)R 对象(使用object.size() 测量)是大小在2.6 to 3.1 GB 之间。如果我将对象保存在R 文件中,则小于100 MB,但在加载时它的大小与以前相同。

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

例如,我的数据 'hh' 中有一个家庭规模变量 'hhpers',由变量 '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 使用“byte”数据类型存储,而 R 使用“int”数据类型存储,导致大型调查的效率显着低下。

【问题讨论】:

  • 您是否尝试在 Stata 中将 set virtual 开启?之后你能比较一下物体的大小吗?
  • str(hh) 的结果是什么?这可能与因素有关吗?
  • 数据集中有 917 个变量,因此 str(hh) 并没有真正提供任何立即有用的东西。不过,大多数变量似乎都是 int。
  • 设置虚拟在stata中没有任何作用
  • @Frank 是的,我还遇到了 'ff' 包,它实现了一些可以访问较小数据类型的功能,但使用这些包似乎会使分析变得非常复杂,我不确定如果您甚至可以使用它来使用其他包执行分析,而无需在标准 R 数据类型之间来回转换数据。

标签: r memory survey


【解决方案1】:

关于内存使用的差异 - 你在正确的轨道上并且(主要)它是因为对象类型。确实整数保存会占用大量内存。因此,正确设置变量类型将提高 R 的内存使用率。as.factor() 会有所帮助。请参阅?as.factor 了解更多详细信息以更新此读取数据后。要解决此问题从文件中读取数据时,请参阅 read.table()colClasses 参数(以及特定于 stata 和 SPSS 格式的类似函数)。这将有助于 R 更有效地存储数据(它对类型的动态猜测并不是一流的)。

关于第二部分 - 计算速度 - 大型数据集解析在基础 R 中并不完美,这就是 data.table 包派上用场的地方 - 它快速且与原始 data.frame 行为非常相似。汇总计算非常快。你可以通过hh &lt;- as.data.table(read.table(...)) 使用它,你可以计算出类似于你的例子的东西

hh <- as.data.table(hh)
hh[htype == "rural",mean(hhpers*hhwt)]
## or
hh[,mean(hhpers*hhwt),by=hhtype] # note 'empty' first argument

抱歉,我不熟悉调查数据研究,因此无法更具体。

另一个函数使用内存的细节 - 很可能 R 制作了整个数据集的副本来计算您正在寻找的摘要。同样,在这种情况下,data.table 将帮助并防止 R 制作过多的副本并提高内存使用率。

【讨论】:

    【解决方案2】:

    我感兴趣的还有memisc 包,对我来说,它最终生成的文件比read.spss 小得多(不过我的工作规模比你小)

    来自memisc 小插图

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-26
      • 1970-01-01
      • 2019-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多