1

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

起始数据集是这样的:

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,以评估是否有元素<=值(mztol)。我是通过外部功能做到的。

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 工作站。但无论如何它都失败了。

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

4

1 回答 1

0

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

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

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


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

于 2017-12-06T20:25:30.330 回答