根据列条目插入行,并确定插入行的条目位置。

5

我有这个数据,我把它命名为A:

A <- read.table(text = "ID  TIME    EVID    AMT DOSE
1   10      1       100 20
1   12      1       100 20
1   14      1       100 20
1   16      1       100 20
1   17      0       100 20
1   18      1       100 20
1   20      1       100 20
1   22      1       100 20
2   5       1       100 40
2   10      1       100 40
2   15      1       100 40
2   17      0       100 40
2   20      1       100 40
3   4       1       100 25
3   7       1       100 25
3   10      1       100 25
3   11      0       100 25
3   13      1       100 25
3   16      1       100 25
3   19      1       100 25", header = TRUE)

我的目标是插入新的行,EVID=2,ID与前一行ID相同,TIME = 前一行的时间加上AMT / DOSE,并且我希望新的行在0s之后的第一个EVID=1之后,如下所示:
ID  TIME    EVID    AMT DOSE
1   10      1       100 20
1   12      1       100 20
1   14      1       100 20
1   16      1       100 20
1   17      0       100 20
1   18      1       100 20
1   23      2       100 20
1   20      1       100 20
1   22      1       100 20
2   5       1       100 40
2   10      1       100 40
2   15      1       100 40
2   17      0       100 40
2   20      1       100 40
2   22.5    2       100 40
3   4       1       100 25
3   7       1       100 25
3   10      1       100 25
3   11      0       100 25
3   13      1       100 25
3   17      2       100 25
3   16      1       100 25
3   19      1       100 25

我已经把我的EVID索引了

rle(as.character(EVID))$lengths
A$Index<-unlist(sapply(rle(as.character(EVID))$lengths, seq_len), use.names = FALSE)

在这种情况下,与 ave(EVID, EVID, FUN=seq_along) 相比,这段代码的工作效果更好,后者会索引所有连续的1和0,而不管它们是否连续。我想在Index = 1和Index = 2行之间插入新行(我将手动删除第一行新行)。
   ID TIME EVID AMT DOSE Index
1   1   10    1 100   20     1
2   1   12    1 100   20     2
3   1   14    1 100   20     3
4   1   16    1 100   20     4
5   1   17    0 100   20     1
6   1   18    1 100   20     1
7   1   20    1 100   20     2
8   1   22    1 100   20     3
9   2    5    1 100   40     4
10  2   10    1 100   40     5
11  2   15    1 100   40     6
12  2   17    0 100   40     1
13  2   20    1 100   40     1
14  3    4    1 100   25     2
15  3    7    1 100   25     3
16  3   10    1 100   25     4
17  3   11    0 100   25     1
18  3   13    1 100   25     1
19  3   16    1 100   25     2
20  3   19    1 100   25     3

结果A有一个新的索引列;我希望新的行在索引1和2之间,即在此示例中第1、6、13和19行之后。
我发现solutions可以制作列向量,然后通过定义的行号将该列插入到数据中。如何根据列条目添加行并动态确定某些条目?
感谢您的帮助!

1
你能详细说明如何确定要在哪里插入新行吗? - Ricardo Saporta
@RicardoSaporta 我已经添加了澄清说明,谢谢! - shirleywu
没问题,请看下面。 - Ricardo Saporta
1个回答

4

这里有一个使用 data.table 的解决方案。 实际上只需要两行代码(加上一些注释)。

library(data.table)
ADT <- data.table(row=1:nrow(A), A, key="ID")

# just to give an idea of how we can Find the first 0 after the first 1, look at the output from this
ADT[, list(row, EVID,c(NA,diff(EVID)), c(NA,diff(EVID))==1)]

# identify afer which row to insert
# the values you want to change, assign using the `=`
# the values to keep, just call the variable name, no `=` sign
newRows <- ADT[c(NA,diff(EVID))==1, list(row=row+1, ID, TIME=TIME+AMT/DOSE, EVID=2, AMT, DOSE)]

# rbind the new rows with the original DT
# then reverse order by EVID, and order by row.  
# After ordering, remove the first column (`row`) since it is not needed
newA <- rbind(ADT, newRows)[order(EVID, decreasing=TRUE)][order(row)][, -1, with=FALSE]


### Results: 

 > newA
    ID TIME EVID AMT DOSE
 1:  1   10    1 100   20
 2:  1   12    1 100   20
 3:  1   14    1 100   20
 4:  1   16    1 100   20
 5:  1   17    0 100   20
 6:  1   18    1 100   20
 7:  1   23    2 100   20
 8:  1   20    1 100   20
 9:  1   22    1 100   20
10:  2    5    1 100   40
11:  2   10    1 100   40
12:  2   15    1 100   40
13:  2   17    0 100   40
14:  2   20    1 100   40
15:  2   22    2 100   40
16:  3    4    1 100   25
17:  3    7    1 100   25
18:  3   10    1 100   25
19:  3   11    0 100   25
20:  3   13    1 100   25
21:  3   17    2 100   25
22:  3   16    1 100   25
23:  3   19    1 100   25
    ID TIME EVID AMT DOSE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接