R 从不同的起点应用cumsum()
我有数据R 从不同的起点应用cumsum(),r,data.table,vectorization,R,Data.table,Vectorization,我有数据 library(data.table) set.seed(42) t <- data.table(time=1:1000, value=runif(100,0,1)) p <- data.table(id=1:10, cut=sample(1:100,5)) vals <- 1:5 > head(t) time value 1: 1 0.9148060 2: 2 0.9370754 3: 3 0.2861395 4: 4
library(data.table)
set.seed(42)
t <- data.table(time=1:1000, value=runif(100,0,1))
p <- data.table(id=1:10, cut=sample(1:100,5))
vals <- 1:5
> head(t)
time value
1: 1 0.9148060
2: 2 0.9370754
3: 3 0.2861395
4: 4 0.8304476
5: 5 0.6417455
6: 6 0.5190959
> head(p)
id cut
1: 1 63
2: 2 22
3: 3 99
4: 4 38
5: 5 91
6: 6 63
> vals
[1] 1 2 3 4 5
哪个应该让步
1 2 3 4 5
[1,] 1 4 5 9 12
[2,] 1 2 5 6 7
[3,] 1 2 4 5 7
[4,] 1 3 5 7 8
[5,] 2 3 5 7 8
[6,] 1 4 5 9 12
[7,] 1 2 5 6 7
[8,] 1 2 4 5 7
[9,] 1 3 5 7 8
[10,] 2 3 5 7 8
这当然是非常低效的,而且不公平地对待R的权力。有没有办法加快这一进程?我会这么做
# precompute cumsum on full table
t[, cs := cumsum(value)]
# compute one time per unique cut value, not per id
cuts = unique(p[, .(t_cut = cut)])
# look up value at cut time
cuts[t, on=.(t_cut = time), v_cut := i.cs]
# look up time at every cut value combo
cutres = cuts[, .(pt = vals + v_cut), by=t_cut][, .(
t_cut,
v = vals,
t_plus = t[.SD, on=.(cs = pt), roll=TRUE, x.time] - t_cut
)]
给
t_cut v t_plus
1: 63 1 1
2: 63 2 4
3: 63 3 5
4: 63 4 9
5: 63 5 12
6: 22 1 1
7: 22 2 2
8: 22 3 5
9: 22 4 6
10: 22 5 7
11: 99 1 1
12: 99 2 2
13: 99 3 4
14: 99 4 5
15: 99 5 7
16: 38 1 1
17: 38 2 3
18: 38 3 5
19: 38 4 7
20: 38 5 8
21: 91 1 2
22: 91 2 3
23: 91 3 5
24: 91 4 7
25: 91 5 8
t_cut v t_plus
如果要将其映射回id
并将其放入id x vals表中
cutres[p, on=.(t_cut = cut), allow.cartesian=TRUE,
dcast(.SD, id ~ v, value.var = "t_plus")]
id 1 2 3 4 5
1: 1 1 4 5 9 12
2: 2 1 2 5 6 7
3: 3 1 2 4 5 7
4: 4 1 3 5 7 8
5: 5 2 3 5 7 8
6: 6 1 4 5 9 12
7: 7 1 2 5 6 7
8: 8 1 2 4 5 7
9: 9 1 3 5 7 8
10: 10 2 3 5 7 8
(或者,关键部分可以像
t\u plus=t[.SD,on=(cs=pt),roll=TRUE,which=TRUE]-t\u cut
,因为t$time
是行号。)您能再看看示例数据吗?例如,条件t$value>p$cut[i]
总是FALSE
;因此没有什么可总结的。让我检查一下,对不起!抱歉,我混淆了两个变量,不明智地选择了vals
在这里打印它。现在应该修好了!谢谢,很好用!但是,在某些情况下,cutres=…
步骤会生成数据。表的末尾有一个额外的行,它重复第一行的t_cut
,并且具有t_plus
等于某个疯狂的高数字。在您的示例中,这将是26:63 5 1000
。我怀疑这是由于roll=TRUE
造成的,但还没有弄清楚是什么导致了这种行为。有什么想法吗?@bumblebee是t_plus
的值。你可以在问题的末尾尝试另一种方法来计算它,或者t_plus=findInterval(pt,t$cs)-t_cut
这两种方法都可以达到相同的结果。或者,您可以将mult=“first”
添加到t\u plus=t[…]
,如果由于t$value
为零而重复出现t$cs
的值,则需要添加。对于额外的一行,我被难住了,但您可以查看中间表,如cuts[,(pt=vals+v_-cut),by=t_-cut]
,以进行调查。
cutres[p, on=.(t_cut = cut), allow.cartesian=TRUE,
dcast(.SD, id ~ v, value.var = "t_plus")]
id 1 2 3 4 5
1: 1 1 4 5 9 12
2: 2 1 2 5 6 7
3: 3 1 2 4 5 7
4: 4 1 3 5 7 8
5: 5 2 3 5 7 8
6: 6 1 4 5 9 12
7: 7 1 2 5 6 7
8: 8 1 2 4 5 7
9: 9 1 3 5 7 8
10: 10 2 3 5 7 8