加速data.table的向量查找

时间:2015-01-12 18:47:12

标签: r data.table

data.table中的每一行,我需要从向量中找到最接近的较低数字。以下最小工作示例完成了这项工作,但速度太慢,特别是对于较长的pre.numbers向量(实际数据中约有100万个元素)。

library(data.table)
set.seed(2)
pre.numbers <- sort(floor(runif(50000, 1, 1000000)))
the.table <- data.table(cbind(rowid=1:10000, current.number=floor(runif(1000, 1, 100000)), closest.lower.number=NA_integer_))
setkey(the.table, rowid)
the.table[, closest.lower.number:=max(pre.numbers[pre.numbers<current.number]), by=rowid]

必须有一种更聪明的方法来做到这一点。 vector-number与data.table中的数字之间没有关系。

1 个答案:

答案 0 :(得分:4)

这个怎么样?使用data.table的滚动连接:

DT = data.table(pre = pre.numbers, 
       current.number = pre.numbers+0.5, key="current.number")
setkey(the.table, current.number)
ans = DT[the.table, roll=Inf, rollends=FALSE]

由于你正在处理整数,我刚刚添加了0.5(0到1之间的任何数字应该没问题)从DT创建pre.numbers

最后一步执行 LOCF滚动连接(最后一次观察结果)。对于current.number(键列)的每个值,在DT的{​​{1}}(键列)中查找匹配的行。如果没有匹配,则向前滚动最后一个观察。如果匹配发生在开头/结尾,则会产生current.numberNA)。

为了更好地说明发生的情况,请考虑以下情况:

rollends = FALSE

我们首先将pre.numbers转换为# pre.numbers: # c(10, 11) # the.table: # current.numbers # 9 # 10 # 11 ,这将产生列

DT

对于# DT: # pre current.numbers (key col) # 10 10.5 # 11 11.5 中的每个值:

the.table

HTH


以下是我用来生成数据的代码:

#  9 -> falls before 10.5, LOCF and rollends = FALSE => result is NA
# 10 -> falls before 10.5 => same as above
# 11 -> falls between 10.5 and 11.5, LOCF matches with previous row = 10.5 
#       corresponding pre = 10.