匹配两个非常大的向量与容差(快速!但工作空间保留)

考虑我有两个向量.一个是参考向量/列表,其包括所有感兴趣的值和一个可包含任何可能值的样本向量.现在我想在参考列表中找到我的样本的匹配,并且具有一定的容差,该容差不是固定的,并且依赖于向量内的比较值:

matches: abs(((referencelist - sample[i])/sample[i])*10^6)) < 0.5

舍入两个向量是没有选择!

例如考虑:

referencelist <- read.table(header=TRUE,text="value  name
154.00312  A
154.07685  B
154.21452  C
154.49545  D
156.77310  E
156.83991  F
159.02992  G
159.65553  H
159.93843  I")

sample <- c(154.00315,159.02991,154.07688,156.77312)

所以我得到了结果:

name value      reference
1    A   154.00315  154.00312
2    G   159.02991  159.02992
3    B   154.07688  154.07685
4    E   156.77312  156.77310

我能做的就是使用例如外在的功能就像

mydist <- outer(referencelist,sample,FUN=function(x,y) abs(((x - y)/y)*10^6))
matches <- which(mydist < 0.5,arr.ind=TRUE)
data.frame(name = referencelist$name[matches[,1]],value=sample[matches[,2]])

或者我可以使用for()循环.

但我的特殊问题是,参考向量有大约1 * 10 ^ 12个条目,我的样本向量大约是1 * 10 ^ 7.所以通过使用outer()我很容易破坏所有工作空间限制,并通过使用for()或chained for()循环,这将需要数天/周才能完成.

有没有人知道如何在R中快速做到这一点,仍然是精确的,但在最大的计算机上工作. 64 GB内存?

谢谢你的帮助!

最好的祝福

解决方法

你的比赛条件

abs(((referencelist - sample[i])/sample[i])*10^6)) < 0.5

可以重写为

sample[i] * (1 - eps) < referencelist < sample[i] * (1 + eps)

eps = 0.5E-6.

使用这个,我们可以使用非等连接来查找每个样本的参考列表中的所有匹配项(不仅是最近的!):

library(data.table)
options(digits = 10)
eps <- 0.5E-6 # tol * 1E6
setDT(referencelist)[.(value = sample,lower = sample * (1 - eps),upper = sample * (1 + eps)),on = .(ref > lower,ref < upper),.(name,value,reference = x.ref)]

它再现了预期的结果:

06003

作为对OP’s comment的回应,假设我们有一个修改后的referencelist2,其中F = 154.00320,那么这也将被捕获:

setDT(referencelist2)[.(value = sample,reference = x.ref)]

06005

相关文章

Java中的String是不可变对象 在面向对象及函数编程语言中,不...
String, StringBuffer 和 StringBuilder 可变性 String不可变...
序列化:把对象转换为字节序列的过程称为对象的序列化. 反序...
先说结论,是对象!可以继续往下看 数组是不是对象 什么是对...
为什么浮点数 float 或 double 运算的时候会有精度丢失的风险...
面试题引入 这里引申出一个经典问题,看下面代码 Integer a ...