根据命名向量的 last(name) 创建新的 data.table 列

Create new data.table column based on last(name) of named vector

我有一个包含流量数据的庞大数据集(超过 100 行 Mio),我想创建一个额外的列来说明该行的流量所在的分位数。


MWE

library(data.table)
# Demo dataset
test = data.table(a=c(1,2,3,4,5,6,7,8,9))
# Demo numeric vector
tocheck = c("TypeA" = 1, "TypeB" = 5)

预期结果

根据a列中的值,应该return矢量的姓氏:

> last(names(tocheck)[tocheck < 2])
[1] "TypeA"
> last(names(tocheck)[tocheck < 7])
[1] "TypeB"

最终数据集应如下所示:

data.table(a=c(1,2,3,4,5,6,7,8,9), 
       Check=c("TypeA","TypeA","TypeA","TypeA","TypeA",
               "TypeB","TypeB","TypeB","TypeB"))

|  a|Check |
|--:|:-----|
|  1|TypeA |
|  2|TypeA |
|  3|TypeA |
|  4|TypeA |
|  5|TypeA |
|  6|TypeB |
|  7|TypeB |
|  8|TypeB |
|  9|TypeB |

我试过的

> test[, Check := last(names(tocheck)[tocheck < a])]

但这给出了以下警告并且没有结果:

Warning message:
In tocheck < a :
  longer object length is not a multiple of shorter object length

并且 google 我还没有找到我可以适应的解决方案。


问题

如何解决此问题,主要关注 speed/performance(>100 Mio 行,6GB 数据)?

感谢您的宝贵意见和建议。

我们可以使用findInterval

library(data.table)
test[, Check := names(tocheck)[findInterval(a, tocheck, rightmost.closed = TRUE)]]

或使用 data.table,这也可以在将命名的 vector 转换为数据后使用 non-equi 连接来完成。frame/data.table(stack 转换为两列 data.frame)

test[stack(tocheck), Check := ind, on = .(a > values)]