0

再次对不起我。我会继续尝试,但我需要帮助,以防我在接下来的一个小时内无法弄清楚。

我的数据如下所示:

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 添加一行 Time+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 之间,除了最后,它添加了太多!

我究竟做错了什么?我一直在为此熬夜:(

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

4

1 回答 1

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)]
于 2013-05-31T21:49:57.820 回答