Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 从不同的起点应用cumsum()_R_Data.table_Vectorization - Fatal编程技术网

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