R Dataframe 中治疗事件的顺序计数

tcomlyy6  于 2023-01-10  发布在  其他
关注(0)|答案(1)|浏览(115)

我有一个不同患者ID、诊所访视日期和出勤率的数据集(见以下示例数据,为清楚起见,按患者ID分隔)。
我感兴趣的是按顺序计算治疗次数,定义为在开始月份接受≥ 4次访视,之后每月接受≥ 1次访视。如果患者在开始后接受〈1次访视(即,在开始月份完成初次≥ 4次访视后),则认为该治疗期结束。随后在患者在给定月份中参加≥ 4次就诊时开始新的治疗期,并且只要患者此后每月参加≥ 1次访视,相同的事件就会继续。当患者不符合或打破此模式时,我希望输入0。
示例数据(注:我排除了每天的日期,以防止示例过长,并重新生成日期,以便更清楚地了解所需的数据):
| 患者ID|访视日期|出席情况|
| - ------| - ------| - ------|
| 1个|2023年1月1日|是的|
| 1个|2023年1月2日|是的|
| 1个|2023年3月1日|是的|
| 1个|2023年4月1日|是的|
| 1个|2023年2月1日|是的|
| 1个|2023年1月3日|是的|
| 1个|2023年4月1日|没有|
| 1个|2023年5月1日|是的|
| 1个|2023年6月1日|没有|
| 1个|2023年7月1日|是的|
| 1个|2023年2月7日|是的|
| 1个|2023年3月7日|是的|
| 1个|2023年4月7日|是的|
| 1个|2023年1月8日|是的|
| - -----| - -----| - -----|
| 患者ID|访视日期|出席情况|
| - -----| - -----| - -----|
| 第二章|2023年1月1日|是的|
| 第二章|2023年2月1日|是的|
| 第二章|2023年1月3日|是的|
| 第二章|2023年2月3日|是的|
| 第二章|2023年3月3日|是的|
| 第二章|2023年3月4日|是的|
| 第二章|2023年4月1日|是的|
| 第二章|2023年5月1日|是的|
| 第二章|2023年7月1日|是的|
所需数据:
| 患者ID|访视日期|出席情况|Tx发作|
| - ------| - ------| - ------| - ------|
| 1个|2023年1月1日|是的|1个|
| 1个|2023年1月2日|是的|1个|
| 1个|2023年3月1日|是的|1个|
| 1个|2023年4月1日|是的|1个|
| 1个|2023年2月1日|是的|1个|
| 1个|2023年1月3日|是的|1个|
| 1个|2023年4月1日|没有|无|
| 1个|2023年5月1日|是的|无|
| 1个|2023年6月1日|没有|无|
| 1个|2023年7月1日|是的|第二章|
| 1个|2023年2月7日|是的|第二章|
| 1个|2023年3月7日|是的|第二章|
| 1个|2023年4月7日|是的|第二章|
| 1个|2023年1月8日|是的|第二章|
| - -----| - -----| - -----| - -----|
| 患者ID|访视日期|出席情况|Tx发作|
| - -----| - -----| - -----| - -----|
| 第二章|2023年1月1日|是的|无|
| 第二章|2023年2月1日|是的|无|
| 第二章|2023年1月3日|是的|1个|
| 第二章|2023年2月3日|是的|1个|
| 第二章|2023年3月3日|是的|1个|
| 第二章|2023年3月4日|是的|1个|
| 第二章|2023年4月1日|是的|1个|
| 第二章|2023年5月1日|是的|1个|
| 第二章|2023年7月1日|是的|无|
我对用R编程有点陌生,最初尝试过使用ifelse(),但没能写出有效的逻辑,我也尝试过写循环,但没能运行。
任何帮助将不胜感激,我很乐意提供更多的细节,如果以上是不清楚。
提前感谢您的时间/努力!

igetnqfo

igetnqfo1#

这看起来相当复杂,并且不确定整个逻辑,但是我认为这可能会有帮助。这使用lubridate库,但是其他的基本R函数。一个帮助函数elapsed_months是从here借用的。
首先创建一个空列表enc_list,它将存储最终data. frame的结果。
我们构建了两个循环--第一个循环分析每个Patient_ID的数据,第二个循环评估给定患者的遭遇。
请注意,我基于Attendance为“是”的子集-如果没有参加,将不希望在评估中包括该数据。
Visit_Date创建一个月的table,这样我们就知道哪些月有〉= 4次相遇。
enc_active是一个简单的标志,指示我们是否逐行处理活动的遭遇。enc_num是处理遭遇的数量,当发现新的处理遭遇时,该数量递增。
逐行查看就诊数据,首先检查是否处于活动就诊中,如果是,则检查经过的月数是0(当月)还是1(连续月),如果是,则记录该次就诊,如果不是,则本次就诊结束。
如果不是主动治疗,检查是否有一个月有4次以上的主动治疗,如果有,则设置为新的主动治疗。注意,如果不为真,则将Tx_Encounter记录为0,然后重置标记。
最终结果存储回列表中,列表最后将与rbind(行绑定)绑定在一起。
merge将结果与原始 Dataframe 合并,由于带有Attendance或“No”的行在早期被删除,因此需要原始 Dataframe 。由于merge将使Tx_Encounter在这些“No“中缺失,因此我们将用0替换NA
一些示例数据是从你的评论改编的。请让我知道问题-很高兴做一个StackOverflow聊天来复习。我确实对这种形式的数据有兴趣,来自我自己的经验。

library(lubridate)

elapsed_months <- function(end_date, start_date) {
  ed <- as.POSIXlt(end_date)
  sd <- as.POSIXlt(start_date)
  12 * (ed$year - sd$year) + (ed$mon - sd$mon)
}

enc_list <- list()

for (id in unique(df$Patient_ID)) {
  enc_data <- df[df$Patient_ID == id & df$Attendance == "Yes", ]
  enc_month <- table(cut(enc_data$Visit_Date, 'month'))
  enc_active <- F
  enc_num <- 0
  for (i in 1:nrow(enc_data)) {
    if (enc_active) {
      if(elapsed_months(enc_data$Visit_Date[i], enc_data$Visit_Date[i - 1]) <= 1) {
        enc_data[i, "Tx_Episode"] <- enc_num
      } else {
        enc_active = F
        enc_data[i, "Tx_Episode"] <- 0
      }
    } else {
      if(enc_month[as.character(floor_date(enc_data$Visit_Date[i], unit = "month"))] >= 4) {
        enc_active = T
        enc_num <- enc_num + 1
        enc_data[i, "Tx_Episode"] <- enc_num
      } else {
        enc_data[i, "Tx_Episode"] <- 0
      }
    }
  }
  enc_list[[id]] <- enc_data
}

df_final <- merge(
  do.call('rbind', enc_list),
  df,
  all.y = T
)

df_final$Tx_Episode[is.na(df_final$Tx_Episode)] <- 0

产出

Patient_ID Visit_Date Attendance Tx_Episode
1           1 2023-01-01        Yes          1
2           1 2023-01-02        Yes          1
3           1 2023-01-03        Yes          1
4           1 2023-01-04        Yes          1
5           1 2023-02-01        Yes          1
6           1 2023-03-01        Yes          1
7           1 2023-04-01         No          0
8           1 2023-05-01        Yes          0
9           1 2023-06-01         No          0
10          1 2023-07-01        Yes          2
11          1 2023-07-02        Yes          2
12          1 2023-07-03        Yes          2
13          1 2023-07-04        Yes          2
14          1 2023-08-01        Yes          2
15          2 2023-01-01        Yes          0
16          2 2023-02-01        Yes          0
17          2 2023-03-01        Yes          1
18          2 2023-03-02        Yes          1
19          2 2023-03-03        Yes          1
20          2 2023-03-04        Yes          1
21          2 2023-04-01        Yes          1
22          2 2023-04-02        Yes          1
23          2 2023-04-03        Yes          1
24          2 2023-04-04        Yes          1
25          2 2023-06-12        Yes          0

相关问题