如何查找值是否与上一行不同并在下一行重复该信息(如循环)?
How to find if a value differs from the previous line and repeat that information in next line (like a loop)?
问题
标题具有误导性,因为它比那更复杂。我需要从 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
]
然后,使用 shift 函数,我可以检查两个连续行之间的差异。
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”怎么找,因为这是该患者的第三次住院。
解决方案
感谢 Ronak Shah !
data_set[, result := cumsum(date_entry != shift(date_exit, fill = FALSE)), patient_id]
首先,您必须准备数据集 - 您基本上只想比较下一个入口和上一个出口。第一次进入不会有之前的出口,所以可以删除第一次进入,最后一次出口不会有进入。
# ==== 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
接下来,计算exit和left之间的时间差(删除后我们要相减的值在彼此下方),并将其与零进行比较以获得真相table:
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 的列并为每个患者创建一个临时 table(根据 patient_ID 获取您的集合的子集)
来完成
我不确定我是否理解你 - 我希望它能解决你的问题:)
如果前一行的 date_exit
与每个 patient_id
的当前 date_entry
不同,您可以增加计数。
library(data.table)
data_set[, result := cumsum(date_entry != shift(date_exit, fill = FALSE)), patient_id]
# patient_id unit_id date_entry date_exit expected_result result
#1: 0034280 azr 2021-07-10 2021-07-10 1 1
#2: 0034280 grt 2021-07-13 2021-07-14 2 2
#3: 0034280 chd 2021-07-14 2021-07-25 2 2
#4: 0034280 grt 2021-07-30 2021-07-30 3 3
#5: 0002050 tgo 2021-07-29 2021-07-30 1 1
#6: 0002050 grt 2021-07-30 2021-07-30 1 1
问题
标题具有误导性,因为它比那更复杂。我需要从 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
]
然后,使用 shift 函数,我可以检查两个连续行之间的差异。
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”怎么找,因为这是该患者的第三次住院。
解决方案
感谢 Ronak Shah !
data_set[, result := cumsum(date_entry != shift(date_exit, fill = FALSE)), patient_id]
首先,您必须准备数据集 - 您基本上只想比较下一个入口和上一个出口。第一次进入不会有之前的出口,所以可以删除第一次进入,最后一次出口不会有进入。
# ==== 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
接下来,计算exit和left之间的时间差(删除后我们要相减的值在彼此下方),并将其与零进行比较以获得真相table:
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 的列并为每个患者创建一个临时 table(根据 patient_ID 获取您的集合的子集)
来完成我不确定我是否理解你 - 我希望它能解决你的问题:)
如果前一行的 date_exit
与每个 patient_id
的当前 date_entry
不同,您可以增加计数。
library(data.table)
data_set[, result := cumsum(date_entry != shift(date_exit, fill = FALSE)), patient_id]
# patient_id unit_id date_entry date_exit expected_result result
#1: 0034280 azr 2021-07-10 2021-07-10 1 1
#2: 0034280 grt 2021-07-13 2021-07-14 2 2
#3: 0034280 chd 2021-07-14 2021-07-25 2 2
#4: 0034280 grt 2021-07-30 2021-07-30 3 3
#5: 0002050 tgo 2021-07-29 2021-07-30 1 1
#6: 0002050 grt 2021-07-30 2021-07-30 1 1