【问题标题】:Error: memory exhausted (limit reached?) due to outer function错误:由于外部功能,内存耗尽(达到限制?)
【发布时间】:2017-12-06 13:02:06
【问题描述】:

我开发了一个脚本,在其中处理了两个大型数组(均为数千行),“父”和“产品”

起始数据集是这样的:

parent<-sample(1:10000,3500)
product<-sample(1:7500,2500)
mztol<-0.0015
mzdiff<-sample(1:1000,31)
names(mzdiff)<-c("d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9",
             "d10", "d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18", 
             "d19", "d20", "d21", "d22", "d23", "d24", "d25", 
             "d26","d27,"d28", "d29", "d30",
             "d31")

首先,我应用了外部函数,以便逐个元素地获取两个数组之间差异的矩阵。

tabdiff<-outer(product,parent,'-')

然后我尝试用向量 (mzdiff) 逐个元素地减去矩阵 tabdiff,以评估是否有元素

subfun<-function(x,y) abs(x-y)<=mztol
vsubfun<-Vectorize(subfun)
vlogres<-outer(tabdiff,mzdiff,vsubfun)

这里我得到了一个向量,它的每个元素都是一个逻辑矩阵。然后我把它转换成一个列表:

listres<-alply(vlogres,3,.dims=T)

并仅将 TRUE 元素作为证据并计算它们:

result<-sapply(listres, function(x) table(x)["TRUE"])

好吧,关键是如果我只详细说明小的父向量和产品向量,脚本就可以正常工作,例如:

parent<-sample(1:1000,150)
product<-sample(1:1500,500)

如果我考虑大型的,我在处理 vlogres 时收到错误消息“错误:内存已用尽(达到限制?)”。 考虑一下我有一个 16 Gb RAM 工作站。但它还是失败了。

那么我该如何优化这个脚本以避免错误消息呢?有什么提示吗?

【问题讨论】:

  • 如果您提供一个可重复的小示例来说明您正在尝试做什么(而不是复制错误),这可能会有所帮助。
  • 你是对的。刚刚编辑过 ;)
  • 嗨。您的输入只是两个数组。它们代表什么?他们是如何被约束的?名字和它有什么关系?什么时候是结果,给定什么输入?您似乎在用您不需要的巨大中间关系来表达解决方案。 PS Re 标签不是指外层产品,不是外连接。
  • 嗨菲利普。我正在处理化学数据(LC-MS/MS 功能)。亲本是关于“亲本化合物”的载体,即可以进行片段化的分子,该片段可以产生一种或多种产物。每个母体和产物分子都有一个称为 m/z 的特征(您可以在母体和产物向量中找到这些值)。因此,我想弄清楚发生了哪种碎片,从而了解父化合物和产物化合物之间是否存在联系。
  • 通过这两个向量的差异(逐个元素),我有一个值矩阵(tabdiff),它向我显示了有关碎片过程的一些信息(碎片意味着 m/z 的丢失,如果父母在产品中进化)。因此,该矩阵的每个元素都必须与给定值 (mzdiff) 进行比较。如果其中一个与 mzdiff 值匹配,则我有一个实际的碎片。所以,我想让 tabdiff 与 mzdiff 的比较更容易和更快。顺便说一句,我想要一个输出,其中我的结果由每个 mzdiff 值报告。

标签: r memory outer-join n-dimensional


【解决方案1】:

我能想到的最简单的解决方案是将tabdiff 作为一维向量进行迭代

tabdiff<-c(outer(product, parent, '-'))
result <- sapply(tabdiff, function(i) sum(abs(i-mzdiff) <= mztol))

sapply 语句应该执行你想要的,但你应该仔细检查它。这消除了保存m * n * p 大小的数据的任务。


另一个想法是倒过来考虑你的问题。您希望 product - parent 值在每个 mzdiff 的容差阈值 (mztol) 内。这意味着您需要在mzdiff +/- mztol 范围内的product - parent 值。您可以为每个 mzdiff 制作上限和下限值向量,并使用dplyr::between 或更快的data.table::inrange 查找哪些值在范围内。

【讨论】:

  • 好吧,老实说,我还需要更多东西。是的,一维向量让一切变得更容易,但同时我会丢失关于谁是谁的所有信息。我的意思是,我需要轻松跟踪每个元素,以了解哪个父级和产品匹配。因此,n 维格式对我很有用,因为它是一种简洁明了的方式来保存我的数据(对于每个 mzdiff,我都有一个父级与产品逻辑矩阵)。顺便说一句,我会测试你建议我的不同方法。谢谢。
猜你喜欢
  • 1970-01-01
  • 2018-12-07
  • 2019-07-10
  • 2018-12-17
  • 2014-06-28
  • 1970-01-01
  • 2017-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多