与HDF5或netCDF相比,使用.Rdata文件有什么缺点?

Dav*_*uer 27 file-format r hdf5 netcdf

我被要求更改当前导出.Rdata文件的软件,以便以"平台无关的二进制格式"导出,例如HDF5或netCDF.有两个原因:

  1. Rdata文件只能由R读取
  2. 二进制信息的存储方式取决于操作系统或体系结构

我还发现 "R数据导入导出手册"没有讨论Rdata文件,尽管它确实讨论了HDF5和netCDF.

对R-帮助的讨论表明,.Rdata文件是平台无关的.

问题:

  1. 这些担忧在多大程度上有效?
    • 例如,Matlab可以在不调用R的情况下读取.Rdata吗?
  2. 在这方面,其他格式比.Rdata文件更有用吗?
  3. 是否有可能编写一个脚本来创建所有.Rdata文件的.hdf5类似物,最大限度地减少对程序本身的更改?

Ite*_*tor 28

以下是各种答案:

  1. 丰富的选择首先,关注是有效的,但你的选择列表比它应该更窄.HDF5/netCDF4是一个很好的选择,适用于Python,Matlab和许多其他系统.HDF5在很多方面都优于Python的pickle存储 - 查看PyTables,你很可能会看到很好的加速.Matlab过去曾经(并且可能仍然存在)在HDF5中存储大型单元(或可能是结构)阵列的一些问题.并不是说它不能做到这一点,而是它太可怕了.这是Matlab的问题,而不是HDF5的问题.虽然这些都是很好的选择,但您也可以考虑HDF5是否足够:考虑是否有一些非常大的文件,并且可以从专有编码中受益,无论是访问速度还是压缩速度.使用任何语言进行原始二进制存储并不困难,您可以轻松设计类似文件存储bigmemory(即访问速度)的内容.事实上,您甚至可以使用bigmemory其他语言的文件 - 它实际上是一种非常简单的格式.HDF5当然是一个很好的起点,但是没有一种通用的数据存储和访问解决方案,特别是当人们使用非常大的数据集时.(对于较小的数据集,您还可以查看协议缓冲区或其他序列化格式; Dirk RProtoBuf在R中访问这些格式.)对于压缩,请参阅下一个建议.

  2. 大小正如Dirk所提到的,文件格式可以描述为应用程序中立和应用程序相关.另一个轴是域独立(或域无知)或域依赖(域智能;-))存储.如果您对数据的生成方式有所了解,尤其是可以在压缩中使用的任何信息,那么您可以构建比标准压缩器可能执行的更好的格式.这需要一些工作.替代压缩器比gzip和bzip还允许您分析大量数据并开发适当的压缩"词典",以便您可以使用.Rdat文件获得更好的压缩.对于多种类型的数据集,在表中的不同行之间存储增量是一个更好的选择 - 它可以导致更大的可压缩性(例如可能出现大量的0),但只有您知道这是否适用于您的数据.

  3. 速度和访问权限 .Rdat不支持随机访问.它没有内置的并行I/O支持(如果您愿意,可以序列化为并行I/O存储).在这里可以做很多事情来改善事情,但是一次又一次地将东西粘合到.Rdat上,而不是仅仅切换到不同的存储机制并将速度和访问问题放在一边.(这不仅仅是HDF5的一个优点:我经常使用多核函数来并行化其他I/O方法,例如bigmemory.)

  4. 更新功能 R没有将对象添加到.Rdat文件的非常好的方法.据我所知,它不提供任何"查看器",允许用户直观地检查或搜索.Rdat文件的集合.据我所知,它不提供文件中对象的任何内置版本控制记录.(我通过文件中的单独对象来执行此操作,该对象记录生成对象的脚本的版本,但我将在未来的迭代中将其外包给SQLite.)HDF5具有所有这些.(此外,随机访问会影响数据的更新 - .Rdat文件,您必须保存整个对象.)

  5. 公共支持虽然我提倡您自己的格式,但这是针对极端数据大小的.为许多语言构建库非常有助于减少交换数据的摩擦.对于大多数简单的数据集(在大多数情况下简单仍然意味着"相当复杂")或从中等到相当大的数据集,HDF5是一种很好的格式.当然,有办法在专业系统上击败它.尽管如此,这是一个很好的标准,意味着将花费更少的组织工作来支持专有或特定于应用程序的格式.我已经看到组织在使用生成数据的应用程序之后多年来坚持使用格式,只是因为编写了大量代码以加载并保存在该应用程序的格式中,并且GB或TB数据已经以其格式存储(这可能是你和R有一天,但这是由一个不同的统计套件产生的,一个以字母"S"开头,以字母"S"结尾;-)).这对未来的工作来说是一个非常严重的摩擦.如果您使用广泛的标准格式,则可以更轻松地在它与其他广泛的标准之间移植:很可能其他人也决定解决同样的问题.尝试一下 - 如果你现在做转换器,但实际上并没有将它转换成使用,至少你已经创建了一个其他人可以拿起并使用的工具,如果有必要转移到另一种数据格式的话.

  6. 内存使用.Rdat文件,您必须loadattach它才能访问对象.大多数时候,人们load都是文件.好吧,如果文件非常大,那就会有很多内存.因此,任何一个人都可以更聪明地使用attach或将对象分成多个文件.这对于访问对象的小部分来说是非常麻烦的.为此,我使用内存映射.HDF5允许随机访问文件的某些部分,因此您无需加载所有数据即可访问一小部分内容.这只是事情运作方式的一部分.因此,即使在R中,也有比.Rdat文件更好的选择.

  7. 用于转换的脚本关于编写脚本的问题 - 是的,您可以编写一个加载对象并将其保存到HDF5的脚本.但是,除非您对将要创建的内容有充分的了解,否则在大量异构文件上执行此操作并不一定明智.我无法开始为我自己的数据集设计这个:在那里有太多的一次性对象,并且创建一个巨大的HDF5文件库将是荒谬的.最好把它想象成启动一个数据库:你想要存储什么,你将如何存储它,以及如何表示和访问它?

一旦您获得了数据转换计划,您就可以使用Hadoop等工具甚至基本的多核功能来释放转换程序并尽快完成.

简而言之,即使您留在R中,也建议您查看其他可能的存储格式,尤其是对于大型,不断增长的数据集.如果您必须与他人共享数据,或者至少提供读取或写入访问权限,则建议使用其他格式.没有理由花时间维护其他语言的读者/作者 - 这只是数据而不是代码.:)将代码集中在如何以合理的方式处理数据,而不是花时间处理存储 - 其他人已经做了很好的工作.


Dir*_*tel 9

(二进制)文件格式有两种基本风格:

  • 应用程序中立,由公共库和API支持(netCDF和HDF5都属于这个阵营),这有助于不同程序和应用程序之间的数据交换,前提是它们使用API​​通过附加软件包进行扩展

  • 特定应用程序的应用程序专门用于处理一个程序,尽管效率更高:这就是.RData所做的

因为R是开源的,所以你可以从你的Matlab文件中重新创建RData的格式:没有什么能阻止你编写一个合适的mex文件.也许有人甚至已经做过了.没有技术理由不尝试---但如果两个应用程序意图共享数据同样支持格式,那么另一条路径可能会更容易.

对于它的价值,回到20世纪90年代早期/中期,我确实编写了自己的C代码来编写Octave使用的二进制格式的模拟文件(我用它然后切片数据).能够使用开源软件实现这一目标是一大优点.


Tom*_*mmy 5

我想我可以回答一些,但不是所有这些问题.

  1. 好吧,任何把它放在心上的人都可以.Rdata直接读取文件,但这很难,也没有多大好处.所以我怀疑Matlab已经做到了.您可能还记得,R可以精确地阅读各种其他系统格式,因为有人付出了很多努力.

  2. 对于文本格式,csv看起来很"标准",但对于二进制格式我不知道 - 而且csv不是一个很好的标准 - 它变化很大(特别是)日期和引用的处理方式(当然它只适用于数据表).

  3. 当然!

例:

for(f in list.files(".", pattern="\\.Rdata$") {
    e <- new.env()
    load(f, e)       # load all values into environment e
    x <- as.list(e)

    #saveInOtherFormat(x, file=sub("\\.Rdata$", ".Other", f))
}
Run Code Online (Sandbox Code Playgroud)

  • 在这里你可能想要检查加载的对象是否可以用新格式成功保存的类型,否则排除/警告... (2认同)