首页 > 解决方案 > 如何查找值是否与上一行不同并在下一行重复该信息(如循环)?

问题描述

问题

标题具有误导性,因为它比这更复杂。我需要从 2 个不同的变量中找到 2 行之间的值差异,并且我还需要将该信息重复到下面的所有行。

我有一份病人名单,他们进出我工作的医院。有时,在住院期间,他们会从一个病房转移到另一个病房(例如急诊转重症监护)。

我想知道他们实际上离开了多少时间然后又回到了医院。

要找到它,我只需要搜索进入日和前一个退出日之间的时间差。如果两者相等,那么这是相同的停留。如果他们不同,那么这是另一个住宿。

用我的英语水平很难解释,所以我在下面给你一个例子。

例子

我与 合作data.table,但您可以根据需要使用dplyr。我应该能够轻松地转换它。*

# ==== Library ====
require(data.table)

# ==== Data set ====
## The patient id, the unit id, and the entry and exit date from individuals unit
patient_id <- c(rep(x = "0034280", 4), rep(x = "0002050", 2))
unit_id    <- c(c("azr", "grt", "chd", "grt"), c("tgo", "grt"))
date_entry <- c(c("2021-07-10", "2021-07-13", "2021-07-14", "2021-07-30"),c("2021-07-29", "2021-07-30"))
date_exit  <- c(c("2021-07-10", "2021-07-14", "2021-07-25", "2021-07-30"),c("2021-07-30", "2021-07-30"))

## The variable I want to get
expected_result <- c(c(1,2,2,3), c(1,1))

## Final result expected
data_set <- data.table(patient_id, unit_id, date_entry, date_exit, expected_result)

如您所见,由于第 2 行的“2021-07-13”与第 1 行的“2021-07-10”不同,因此表明该患者住院人数的预期结果增加了。

我的尝试

首先,我开始为新变量创建一个基值

data_set <- data_set[
  j = stay_number := 1
]

然后,使用移位功能,我可以检查两个连续行之间的差异。

data_set <- data_set[
  j = stay_number := data.table::fifelse(test = date_entry != data.table::shift(date_exit, type = "lag"),
                                        yes  = stay_number+1,
                                        no   = stay_number),
  by = patient_id
][
  j = stay_number := data.table::fifelse(test = base::is.na(stay_number),
                                        yes  = 1,
                                        no   = stay_number)
]

但是我不知道如何将数字“2”重复到第三排,这与第二排相同的住院时间。因此,我不知道如何在第四排找到“3”,因为它是第三排该患者的住院治疗。

解决方案

谢罗纳克沙阿

data_set[, result := cumsum(date_entry != shift(date_exit, fill = FALSE)), patient_id]

标签: rdifference

解决方案


首先,您必须准备数据集 - 您基本上只想比较 NEXT 条目和 PREVIOUS 出口。第一个入口不会有之前的出口,所以可以删除第一个入口,最后一个出口不会有入口。


# ==== Library ====
require(data.table)

# ==== Data set ====
## The patient id, the unit id, and the entry and exit date from individuals unit
patient_id <- c(rep(x = "0034280", 4), rep(x = "0002050", 2))
unit_id    <- c(c("azr", "grt", "chd", "grt"), c("tgo", "grt"))
date_entry <- c(c("2021-07-10", "2021-07-13", "2021-07-14", "2021-07-30"),c("2021-07-29", "2021-07-30"))
date_exit  <- c(c("2021-07-10", "2021-07-14", "2021-07-25", "2021-07-30"),c("2021-07-30", "2021-07-30"))

date_exitT <- date_exit[1:(length(date_entry)-1)] #remove last exit
date_entryT <- date_entry[2:length(date_exit)] #remove first entry

接下来,只需计算退出和离开之间的时间差(删除后我们要减去的值位于彼此下方),并将其与零进行比较以获得真值表:

output<-difftime(date_exitT, date_entryT, units="days")
values<-!(output==0) #negation because we actually want zeros to be falses and all others trues
values <- c(TRUE, values) #because we want to add 1 to the result(we always starting from 1 as I see from the result)

最后,由于false被视为0,true被视为1,我们可以计算累积和。

vals <- cumsum(values)

基本上就是这样,您只需要拆分数据,因此它将为每一列(每个患者)运行它。这可以通过过滤具有特定 ID 的列并为每个患者制作一个临时表来完成(根据 Patient_ID 获取集合的一个子集)

我不确定我是否理解你 - 我希望它能解决你的问题:)


推荐阅读