在列条目确定的两行之间插入增量时间

时间:2013-05-31 15:57:05

标签: r time row data.table

再次对不起我。我将继续努力,但我想要帮助,以防我在下一个小时内无法弄清楚。

我的数据如下:

B<-data.frame(ID=c(1,1,1,1,1,1,1,1,2,2,2,2,2,2,2),EVID=c(1,1,1,0,1,2,2,1,1,1,2,2,1,1,1),VALUE=seq(15))
B$TIME<-c(Sys.time()+6*3600*(seq_len(nrow(B))-1))

实际上时间变化多了,每个ID可能有多个EVID为2。

我想在EVID = 2的时间之间增加一小时的增量,因为它们相隔很多小时,即,对于每对EVID = 2,我添加一小时,直到时间在一小时内到第二小时EVID = 2对,所以我可以得到这样的东西: (值和ID只是重复的前一行)

   ID EVID VALUE                TIME
1   1    1     1 2013-05-31 07:51:09
2   1    1     2 2013-05-31 13:51:09
3   1    1     3 2013-05-31 19:51:09
4   1    0     4 2013-06-01 01:51:09
5   1    1     5 2013-06-01 07:51:09
6   1    2     6 2013-06-01 13:51:09
6   1    2     6 2013-06-01 14:51:09
6   1    2     6 2013-06-01 15:51:09
6   1    2     6 2013-06-01 16:51:09
6   1    2     6 2013-06-01 17:51:09
6   1    2     6 2013-06-01 18:51:09
7   1    2     7 2013-06-01 19:51:09
8   1    1     8 2013-06-02 01:51:09
9   2    1     9 2013-06-02 07:51:09
10  2    1    10 2013-06-02 13:51:09
11  2    2    11 2013-06-02 19:51:09
11  2    2    11 2013-06-02 20:51:09
11  2    2    11 2013-06-02 21:51:09
11  2    2    11 2013-06-02 22:51:09
11  2    2    11 2013-06-02 23:51:09
11  2    2    11 2013-06-02 0:51:09
12  2    2    12 2013-06-03 01:51:09
13  2    1    13 2013-06-03 07:51:09
14  2    1    14 2013-06-03 13:51:09
15  2    1    15 2013-06-03 19:51:09

以下是我的头脑风暴/尝试:

library(data.table)
BDT <- data.table(row=1:nrow(B), B, key="ID")
BDT[,list(row,EVID,c(EVID)==2)]

attach(B)

newB<-BDT[c(EVID)==2,list(row=row+1,ID=ID,EVID=EVID,VALUE=VALUE,TIME=head(TIME+3600,-1))]
finalB<-rbind(BDT,newB)[order(EVID,decreasing=TRUE)][order(row)][,-1,with=FALSE]

但是,这会为每个EVID = 2增加一行时间+ 1小时,这不是我想要的。

我试过的下一件事就是在第一行之后复制每一行,这不是我想要的,但是有一个好处就是可以省去我输入列的所有名字(我有大约32个)

newB<-B[c(1,rep(2:nrow(B),each=2)),] 
## My wild guess -- as.numeric(head(TIME))-as.numeric(tail(TIME)))/3600 doesn't work. I know it says that from row 2 to last row, repeat each row twice
newB[c(FALSE,TRUE),"EVID"]<-2
newB[c(FALSE,TRUE),"TIME"]<-newB[c(FALSE,TRUE),"TIME"]+3600

感谢您的任何反馈。

=============================================== ==================

eddie的代码适用于我的例子,我认为这是一个很好的代表,但我的实际数据不断增加

  seq.int中的

错误(...)'by'参数错误签到

(...)根据我的尝试而有所不同

我有一个相对较大的数据,我用作示例中的ID的列位于数据表的中间;我甚至从我的小样本数据中看到,如果我将ID与列表中的其他名称一起放置,R将识别项目2比rbind中的项目1具有n + 1列。但是如果我没有将它包含在列表中以便我可以使用by = ID,则R会抱怨名称的顺序不同。如果a没有列出数据开头的一个不重要的列,R表示第2项与第1项相比有n-1列!

我认为也许我的错误来自于我的时间并不完全相隔几小时,但通过测试运行,我发现可以容忍小的差异,无论是小时还是整数,都没有帮助。

我尝试使用length.out,忽略警告

  

警告消息:在.rbind.data.table(...)中:参数2中包含名称   不同的顺序。列将按名称绑定以与其一致   基础。或者,您可以删除名称(使用未命名的列表)和   然后列将按位置连接。或者,设置use.names = FALSE。

但是代码不会添加到2之间,除了最后,它增加了太多了!

我做错了什么?为此,我一直在努力:(

好的,当我重新排列原始数据时,我可以摆脱警告。但是,插入仍然只发生在数据的末尾,而且它们太多了。

1 个答案:

答案 0 :(得分:2)

这应该有效:

library(data.table)
dt = data.table(B)
dt[, TIME := as.POSIXct(TIME)]

rbind(dt, dt[EVID == 2,
             list(EVID=EVID[1],
                  VALUE=VALUE[1],
                  TIME=seq.POSIXt(TIME[1], TIME[2], "hour")),
             by = ID])[!duplicated(paste(ID,EVID,TIME))][order(ID, TIME)]