使用 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")
)
我是 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")
)