使用 data.table 按组顺序更新行

Sequentially update rows by group using data.table

我是 R 的新手。我有一个假设的数据集,其中包含来自各种不同患者和药物类型的处方。我想做的是创造药物使用的情节,即我想看看病人使用药物的时间。 post 中提到的循环对我有用,但我不确定如何确保在遇到新的患者标识符或药物类型时循环重新开始。

这些是数据集“AllDrugs”中的一些行:

DrugType    ID  Duration StartPrescr    EndPrescr   n
1           1   90       5-3-2020       3-6-2020    1
1           2   30       7-1-2020       6-2-2020    1
1           2   30       14-1-2020      12-6-2020   2
1           2   30       21-01-2020     19-6-2020   3

注意:n 是一个数字,根据 ID 和 DrugType 表示处方

这是当前循环:

 for (i in 2:nrow(AllDrugs)) {
   if (AllDrugs[i,StartPrescr] >= AllDrugs[i-1,EndPrescr]) {
     AllDrugs[i, EndPrescr:= StartPrescr+ Duration]
   } else {
     AllDrugs[i, EndPrescr:= AllDrugs[i-1,EndPrescr] + Duration]
   }
 }

这是我得到的:

DrugType    ID  Duration    StartPrescr EndPrescr   n
1           1   90          5-3-2020    3-6-2020    1
1           2   30          7-1-2020    3-7-2020    1
1           2   30          14-1-2020   2-8-2020    2
1           2   30          21-01-2020  1-9-2020    3

这就是我想要的:

DrugType    ID  Duration    StartPrescr EndPrescr   n
1           1   90          5-3-2020    3-6-2020    1
1           2   30          7-1-2020    6-2-2020    1
1           2   30          14-1-2020   7-3-2020    2
1           2   30          21-01-2020  6-4-2020    3

如何根据 ID 和 DrugType 根据处方的持续时间转移处方?注意:这是一种药物类型的示例,但 DrugType 也可以是 2 或 3 等

这对你有用吗?

shift_end <- function(en,dur) {
  if(length(en)>1) for(i in 2:length(en)) en[i] = en[i-1] + dur[i]
  return(en)
}

df[order(ID, DrugType,StartPrescr), EndPrescr:=shift_end(EndPrescr,Duration), by=.(ID,DrugType)]

结果:

   DrugType ID Duration StartPrescr  EndPrescr n
1:        1  1       90  2020-03-05 2020-06-03 1
2:        1  2       30  2020-01-07 2020-02-06 1
3:        1  2       30  2020-01-14 2020-03-07 2
4:        1  2       30  2020-01-21 2020-04-06 3

数据来源:

df <- structure(list(
  DrugType = c(1, 1, 1, 1),
  ID = c(1, 2, 2, 2),
  Duration = c(90, 30, 30, 30),
  StartPrescr = structure(c(18326,18268, 18275, 18282), class = "Date"),
  EndPrescr = structure(c(18416, 18298, 18425, 18432), class = "Date"),
  n = c(1, 1, 2, 3)), row.names = c(NA,-4L),
  class = c("data.table", "data.frame")
)