R data.table 更新错误

R data.table update errors

与此相关的旧 data.table 代码还有一些问题: R: number rows that match >= other row within group

数据是这样的,每个人都有不同的ID,IDSEQ是这个人每次入院的顺序,TAG是糖尿病药物(TAG=1降糖药,TAG=2胰岛素)。

   ID IDSEQ TAG
1   1     1   0
2   1     2   0
3   1     3   0
4   1     4   0
5   1     5   0
6   1     6   0
7   1     7   0
8   1     8   1
9   1     9   0
10  1    10   0
11  2     1   0
12  2     2   0
13  2     3   0
14  2     4   1
15  2     5   0
16  2     6   0
17  2     7   0
18  2     8   2
19  2     9   0
20  2    10   0

# recreate this data with
df <- data.frame(ID=c(rep(1,10),rep(2,10)),
                 IDSEQ=c(1:10,1:10),
                 TAG=c(rep(0,7),1,0,0,0,0,0,1,0,0,0,2,0,0))

练习:新建两个索引序列变量,COND1使用TAG=1作为索引记录,COND2使用TAG=2作为索引记录。编写您的语法,以便仅在索引记录之前的块中记录索引记录之前的块中的记录编号为“0”。

a) TAG=1(似乎仍然有效)

DT <- data.table(df)
setkey(DT, ID)

# counter for condition 1
tmp <- df[which(df$TAG == 1),1:2]
DT1 <- data.table(tmp)
DT1 <- DT1[, list(IDSEQ=min(IDSEQ)), by=ID]

DT[, COND1:=0L]
DT[DT[DT1,.I[IDSEQ >= i.IDSEQ]],COND1:=1:.N,by=ID]
# previously 
# DT[DT[DT1,.I[IDSEQ >= i.IDSEQ]]$V1,COND1:=1:.N,by=ID]

a) TAG=2 不再导致正确的结果,它没有链接到 ID 和 IDSEQ。

tmp <- df[which(df$TAG == 2),1:2]
DT1 <- data.table(tmp)
DT1 <- DT1[, list(IDSEQ=min(IDSEQ)), by=ID]

DT[, COND2:=0L]
DT[DT[DT1,.I[IDSEQ >= i.IDSEQ]],COND2:=1:.N,by=ID]

# previously worked with
# DT[DT[DT1,.I[IDSEQ >= i.IDSEQ]]$V1,COND2:=1:.N,by=ID]

整体结果应该是这样的

   ID IDSEQ TAG COND1 COND2
1   1     1   0     0     0
2   1     2   0     0     0
3   1     3   0     0     0
4   1     4   0     0     0
5   1     5   0     0     0
6   1     6   0     0     0
7   1     7   0     0     0
8   1     8   1     1     0
9   1     9   0     2     0
10  1    10   0     3     0
11  2     1   0     0     0
12  2     2   0     0     0
13  2     3   0     0     0
14  2     4   1     1     0
15  2     5   0     2     0
16  2     6   0     3     0
17  2     7   0     4     0
18  2     8   2     5     1
19  2     9   0     6     2
20  2    10   0     7     3

# recreate this data with
  data.frame(ID=c(rep(1,10),rep(2,10)),
             IDSEQ=c(1:10,1:10),
             TAG=c(rep(0,7),1,0,0,0,0,0,1,0,0,0,2,0,0),
             COND1=c(rep(0,7),1,2,3,0,0,0,1,2,3,4,5,6,7),
             COND2=c(rep(0,17),1,2,3))

data.table版本1.9.4,R版本3.1.1

您的示例的更正最后一行:

DT[DT[DT1, .I[IDSEQ >= i.IDSEQ], by=.EACHI]$V1, COND2:=1:.N, by=ID]

或者,您也可以更改默认行为,但由于兼容性问题我不推荐这样做。

options(datatable.old.bywithoutby=TRUE)

一些背景信息:

TAG==2 的选择标准导致

DT[DT1,.I[IDSEQ >= i.IDSEQ]]
[1]  8  9 10

这是 subset/join 之后 ID==2 的正确索引(行号)。

如果有,你也会有同样的经历 problem/result没有任何 TAG==1.

ID==0
df <- data.frame(ID=c(0, rep(1,10),rep(2,10)),
             IDSEQ=c(1, 1:10,1:10),
             TAG=c(0, rep(0,7),1,0,0,0,0,0,1,0,0,0,2,0,0))

DT <- data.table(df)
setkey(DT, ID)

# counter for condition 1
tmp <- df[which(df$TAG == 1),1:2]
DT1 <- data.table(tmp)
DT1 <- DT1[, list(IDSEQ=min(IDSEQ)), by=ID]

DT[, COND1:=0L]
DT[DT[DT1, .I[IDSEQ >= i.IDSEQ]], COND1:=1:.N, by=ID]

DT[c(1,2, 7:10),]
   ID IDSEQ TAG COND1
1:  0     1   0     0
2:  1     1   0     0
3:  1     6   0     0
4:  1     7   0     1
5:  1     8   1     2
6:  1     9   0     3

data.table 处理这种情况 (by-without-by) 的方式与版本 1.9.4 不同。加载 data.table 时显示

> library(data.table)
data.table 1.9.4  For help type: ?data.table
*** NB: by=.EACHI is now explicit. See README to restore previous behaviour.

因此你需要明确地告诉你想要得到你的结果j(语句的第二部分)不仅针对当前子集(在第一部分中定义),而且按每个键分组变量。

更多信息可以在第 5 页和第 6 页的 data.table 常见问题解答 1.13 和 1.14 中找到。

这是使用 data.table 的一种方法:

dt[, `:=`(count1 = cumsum(cumsum(TAG == 1L)), 
          count2 = cumsum(cumsum(TAG == 2L))
         ), by=ID]
#     ID IDSEQ TAG count1 count2
#  1:  1     1   0      0      0
#  2:  1     2   0      0      0
#  3:  1     3   0      0      0
#  4:  1     4   0      0      0
#  5:  1     5   0      0      0
#  6:  1     6   0      0      0
#  7:  1     7   0      0      0
#  8:  1     8   1      1      0
#  9:  1     9   0      2      0
# 10:  1    10   0      3      0
# 11:  2     1   0      0      0
# 12:  2     2   0      0      0
# 13:  2     3   0      0      0
# 14:  2     4   1      1      0
# 15:  2     5   0      2      0
# 16:  2     6   0      3      0
# 17:  2     7   0      4      0
# 18:  2     8   2      5      1
# 19:  2     9   0      6      2
# 20:  2    10   0      7      3