通过重复连接创建序列

时间:2019-07-02 16:25:25

标签: r join data.table sequence

假设我有以下数据:

library(data.table)
set.seed(42)
t <- data.table(time=1001:2000, period=round(runif(1000,1,5)), a=round(rnorm(1000)))
p <- data.table(id=1:10, time=sample(1000:1100,5), a=round(rnorm(10)))


 > t[27:38]
    time period  a
 1: 1027      3 -1
 2: 1028      5 -1
 3: 1029      3  0
 4: 1030      4 -2
 5: 1031      4 -2
 6: 1032      4 -1
 7: 1033      3  0
 8: 1034      4  1
 9: 1035      1  0
10: 1036      4  0
11: 1037      1  0
12: 1038      2 -1

> head(p)
   id time  a
1:  1 1027  1
2:  2 1094  1
3:  3 1044 -1
4:  4 1053  1
5:  5 1015  1
6:  6 1027 -1

类似于我之前以{{3}}发布的数据,但是现在有了从a继承来的附加变量t

与我之前的问题相反,我的目标是通过串联p中的n个周期来在t中创建序列。对于n=4,理想情况下,结果应如下所示:

> head(p)
   id time  a
1:  1 1027  1
2:  1 1030 -1 
3:  1 1034 -2
4:  1 1038  1
5:  1 1040 -1
6:  2 1094  1

由于id为1,从1027开始,序列为10271027+3=10301030+4=10341034+4=10381038+2=1040,其中的增量取来自t。此外,t$a被“带走”以填写p$a

在我之前的问题中,Jaap提供了一种出色的解决方案,以获得每id每行一行的二维输出。我想知道是否可以直接在p中实现。也许可以使用tp的重复连接来完成,或者有一个更有效的解决方案(因为效率在这里很关键)。

1 个答案:

答案 0 :(得分:0)

我不确定100%想用a做什么以“随身携带”, 但也许这种递归可以满足您的需求, 尽管我不知道它是否足够有效:

create_sequences <- function(p, n, acc = p) {
  if (n == 0L) return(setkey(acc, id, time))

  next_p <- t[p, .(id, time = time + period, a = x.a), on = "time"]

  create_sequences(next_p, n - 1L, rbindlist(list(acc, next_p)))
}

ans <- create_sequences(p, 4L)