日期和重叠日期功能

问题描述 投票:0回答:1

我正在尝试创建一个函数,在按 id、start_ins、rxdate 排序的数据中考虑重叠周期:

dt <- data.table(
  id = c(1, 2, 2, 3,3,3),
  start_ins = as.Date(c('2000-10-12', '2000-03-31', '2000-03-31', '2000-01-11', '2000-01-11', '2000-01-11')),
  rxdate = as.Date(c('2010-01-04', '2010-03-30', '2010-04-08', '2003-12-29', '2004-01-12' , '2004-03-10')),
  amount = c(30, 28, 100, 60, 1, 10),
rx_end = as.Date(c('2010-02-03', '2010-04-27', '2010-07-17', '2004-02-27', '2004-01-13', '2004-03-20'
)

在此集合中,观测值按 id 和 start_ins 分组。人们还会根据日期和药片数量(数量)购买处方药。 rx_end 是

[, rx_end := rxdate + amount]

但是,如果仔细观察,您会发现第 2 行的 rx_end 位于第 3 行的 rxdate 之后。在这种情况下,第 3 行的 rxdate 和上一个处方的末尾之间存在重叠。我想假设一个人在开始新的治疗之前完成了一次治疗。在这种情况下,第 3 行的 rxdate 应在第 2 行的 rx_end 之后的一天开始,并且第 3 行的 rx_end 应更新,以考虑第 3 行中的新 rxdate。相同的逻辑适用于第 4 行和第 5 行。在这种情况下,新的 rxdate数据集看起来像这样:

dt1 <- data.table(
  id = c(1, 2, 2, 3, 3, 3),
  start_ins = as.Date(c('2000-10-12', '2000-03-31', '2000-03-31', '2000-01-11', '2000-01-11', '2000-01-11')),
  rxdate = as.Date(c('2010-01-04', '2010-03-30', '2010-04-28', '2003-12-29', '2004-02-28', '2004-03-10')),
  amount = c(30, 28, 100, 60, 1, 10),
rx_end = as.Date(c('2010-02-03', '2010-04-27', '2010-08-06', '2004-02-27', '2004-02-29', '2004-03-20'
).

我尝试使用 data.table 编写这个函数:

overlapper <- function (dt){
dt[,{
prev_end_date <- shift(rx_end, 1, type = "lag")

for (i in 2:.N){
if(!is.na(prev_end_date[i-1]) & prev_end_date >= dt[i, rxdate]){
dt[i, rxdate := prev_end_date[i-1] +1]
dt[i, rx_end := rxdate + amount]
}
prev_end_date[i] <- dt[i, rx_end]
}
return(dt)}, by = .(id, start_ins)]}

请记住,有些人只有一个观察结果,因此不应考虑这些,这就是为什么我要按 id 和 start_ins 进行分组操作。 我总是想查看第 n 行并将其与 n-1 进行比较,以仅在存在重叠时更新第 n 行。如果没有重叠,我会保持这条线不变,然后继续下一条线。

r dplyr data.table
1个回答
0
投票

您可以使用

data.table::shift()
来完成此操作:

dt[, rx_days := rx_end - rxdate][
    , rxdate := fifelse(
        rxdate < shift(rx_end, 1, fill = rxdate[1]),
        shift(rx_end, 1) + 1,
        rxdate
    ),
    id
][, rx_end := rxdate + rx_days][,
    rx_days := NULL
]

dt
#       id  start_ins     rxdate amount     rx_end
#    <num>     <Date>     <Date>  <num>     <Date>
# 1:     1 2000-10-12 2010-01-04     30 2010-02-03
# 2:     2 2000-03-31 2010-03-30     28 2010-04-27
# 3:     2 2000-03-31 2010-04-28    100 2010-08-06
# 4:     3 2000-01-11 2003-12-29     60 2004-02-27
# 5:     3 2000-01-11 2004-02-28      1 2004-02-29
# 6:     3 2000-01-11 2004-03-10     10 2004-03-20

identical(dt, dt1)
# [1] TRUE
© www.soinside.com 2019 - 2024. All rights reserved.