R 连接时段以同时获得不同起点的时间序列

R 连接时段以同时获得不同起点的时间序列,r,data.table,sequence,purrr,R,Data.table,Sequence,Purrr,我有以下示例数据: library(data.table) set.seed(42) t <- data.table(time=1:1000, period=round(runif(100,1,5))) p <- data.table(id=1:10, cut=sample(1:100,5)) > t[62:71] time period 1: 62 5 2: 63 4 3: 64 3 4: 65 4

我有以下示例数据:

library(data.table)
set.seed(42)
t <- data.table(time=1:1000, period=round(runif(100,1,5)))
p <- data.table(id=1:10, cut=sample(1:100,5))


> t[62:71]
    time period
 1:   62      5
 2:   63      4
 3:   64      3
 4:   65      4
 5:   66      2
 6:   67      2
 7:   68      4
 8:   69      4
 9:   70      2
10:   71      1

> head(p)
   id cut
1:  1  63
2:  2  22
3:  3  99
4:  4  38
5:  5  91
6:  6  63
我以前学习过如何使用
accumulate::purr
()创建序列。但是,我想知道是否可以使用
data.table
或其他包同时为不同的人执行类似的操作,但避免使用for循环,因为数据集相当大


编辑:时间值与行标记不一致的版本

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

其中,
t$time[i]
不等于
i
,这禁止了Jaap的第一个解决方案。

对于循环,不一定是坏的或低效的。如果使用得当,它们可以有效地解决您的问题

对于您当前的问题,我将使用-package的For循环,这是有效的,因为
数据。表
通过引用更新:

res <- p[, .(id, t1 = cut)]

for(i in 2:4) {
  res[, paste0("t",i) := t[res[[i]], time + period] ]
}

或者,您可以选择更新
p
,如下所示:

for(i in 2:4) {
  p[, paste0("t",i) := t[p[[i]], time + period]]
}
setnames(p, "cut", "t1")
这给出了相同的结果


对于更新的示例数据,应将上述方法更改为:

for(i in 2:4) {
  p[, paste0("t",i) := t[match(p[[i]], t$time), time + period]]
}
setnames(p, "cut", "t1")
我将使用
while()
循环

while (ncol(p) - 1 < 4) {
  p <- cbind(p, p[[ncol(p)]] + t$period[p[[ncol(p)]]])
} 

> head(p)
   id cut  V2  V2  V2
1:  1  63  67  69  73
2:  2  22  24  29  32
3:  3  99 103 105 109
4:  4  38  40  43  44
5:  5  91  95 100 103
6:  6  63  67  69  73
while(ncol(p)-1<4){
p头(p)
id切割V2
1:  1  63  67  69  73
2:  2  22  24  29  32
3:  3  99 103 105 109
4:  4  38  40  43  44
5:  5  91  95 100 103
6:  6  63  67  69  73

您的
t
p
的实际尺寸是多少?感谢您的输入和这个想法!我尝试了在
time
cut
都是POSIXct并且
period
是difftime时实现这个解决方案,但是我一直得到一个错误,
我没有计算为逻辑、整数或双精度
。是吗我纠正了这一点,这意味着POSIXct对象不能用于为
t
表设置键?问题解决了,这是一个简单的连接问题。我重新命名了
setnames(p,“cut”,“time”)
,并添加了将循环更改为
t[p[[I]],time+period,on=(time)]]
获取
t
p
在关节
time
变量上连接。我是否正确地假设,与直接索引
t
表相比,这需要花费时间?在我的解决方案中,我可以只使用值来筛选
t
,因为它们是数字并且引用行。如果不是这样,您将必须使用其他方法,如您在第2条评论中显示的加入。我错了-我的调整不起作用(
逻辑错误。我不是数据表,但提供了“on”参数。
)并使用
p
代替
p[[I]]
t2
t3
t4
生成相同的值。不知何故,我需要使
on=(time=…)
部分交互,并在
的位置获取(更改)列名。
我尝试了
p[,paste0(“t”,I):=t[p,time+period,on=(time=as.name(names)(p)[I])]
但这不起作用。有什么办法吗?@bumblebee你能在你的问题中添加一些例子数据,模仿你在上面的评论中描述的情况吗?我明天早上再看
for(i in 2:4) {
  p[, paste0("t",i) := t[p[[i]], time + period]]
}
setnames(p, "cut", "t1")
for(i in 2:4) {
  p[, paste0("t",i) := t[match(p[[i]], t$time), time + period]]
}
setnames(p, "cut", "t1")
while (ncol(p) - 1 < 4) {
  p <- cbind(p, p[[ncol(p)]] + t$period[p[[ncol(p)]]])
} 

> head(p)
   id cut  V2  V2  V2
1:  1  63  67  69  73
2:  2  22  24  29  32
3:  3  99 103 105 109
4:  4  38  40  43  44
5:  5  91  95 100 103
6:  6  63  67  69  73