【问题标题】:R: selecting subset without copyingR:选择子集而不复制
【发布时间】:2012-03-23 07:16:28
【问题描述】:

有没有办法从对象(数据框、矩阵、向量)选择子集而不复制所选数据

我使用非常大的数据集,但从不更改它们。然而,为了方便起见,我经常选择要操作的数据子集。每次复制一个大子集的内存效率非常低,但是普通索引和subset(以及xapply() 系列函数)都会创建所选数据的副本。所以我正在寻找可以克服这个问题的函数或数据结构。

一些可能适合我的需要并希望在某些 R 包中实现的方法:

  • copy-on-write 机制,即仅在您添加或重写现有元素时复制的数据结构;
  • 不可变数据结构,只需要为数据结构重新创建索引信息,而不是它的内容(例如通过只创建包含长度的小对象和指向同一 char 数组的指针来从字符串中创建子字符串) ;
  • xapply() 不创建子集的类似物。

【问题讨论】:

  • 我认为你应该看看data.table 包(估计很快就会有人出现在这里给你更多细节......)
  • 数据库接口显然是您应该研究的。 r 中几乎所有的东西都是按承诺传递的,在需要对子集做任何事情的那一刻,它实际上变成了按值传递。
  • @BenBolker:谢谢,data.table 似乎是一个不错的包,但不幸的是它在大多数情况下不符合我的需求。特别是,data.table 有另一个索引模型,这使得执行像data[1:50, 1:10] (即同时选择 - 行和列)和许多线性代数运算这样的选择变得更加困难(并且速度更慢)。我正在考虑使用矩阵而不是我的数据框来节省空间和时间,但矩阵也有其局限性,所以我也在寻找替代方案。
  • @DWin:关于“按值传递”。你的意思是 R 使用惰性求值?但它与我看到的不对应:代码DF <- data[1:10000, ] 大约需要 30 秒,这比创建 promise 对象所需的时间要长得多。这也意味着数据结构必须是永久性的才能不破坏语言语义,但事实并非如此。请你解释一下好吗?我肯定想念一些东西。 (让我知道是否值得将其作为单独的问题发布。)
  • 不确定您所说的永久是什么意思。在函数的环境中创建一个对象并让它在退出时自动成为垃圾回收是完全可能的。我的理解是 R 确实使用惰性求值。如果您想对 this.process 进行一些控制,可以使用 delayedAssignforce 函数。我们大多数人都没有考虑太多(直到它在函数评估期间咬我们。)

标签: r immutability subset apply copy-on-write


【解决方案1】:

试用包ref。具体来说,它的refdata 类。

data.table 可能缺少的一点是,在分组(by= 参数)时,不会复制数据子集,因此速度很快。 [从技术上讲,它们只是在一个共享的内存区域中,每个组都可以重复使用,并使用 memcpy 进行复制,这比 C 中 R 的 for 循环快得多。]

data.table 中的:= 是修改data.table 的一种方法。 data.table 与通常的 R 编程风格不同,因为它不是写时复制。用户必须显式调用copy() 来复制(可能非常大的)表,即使在函数内也是如此。

您说得对,data.table 中没有内置像 refdata 这样的机制。我明白你的意思,这将是一个不错的功能。不过,refdata 应该在 data.table 上工作,你可能对 data.frame 没问题(但请务必使用 tracemem(DF) 监视副本)。

plyr中还有idata.frame(不可变data.frame)你可以试试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-21
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    相关资源
    最近更新 更多