这个问题是我问的上一个问题的延伸(计算类别经过午夜的行之间的时间差)。虽然 maupagas 对该帖子的回复解决了可重现示例的问题,但当我在更复杂的数据集上尝试时,出现了一些问题。
我有一个数据集正在比较疼痛评分,并试图确定该人处于特定疼痛范围的持续时间。这个想法是将每个疼痛评分视为恒定,直到下次评估疼痛为止。我想要的是每个观察日 (
time_diff_hours
) 特定疼痛范围 (pain_score
) 的持续时间 (day
)。
我遇到的问题是:
pain_score
延续到新的一天。这适用于之前解决的代码,直到出现多个 Patient_id 为止。代码按时间排列变量,但应该先按 patient_id
,然后按 time
。我无法通过代码解决这个问题。time_diff_hours
) 的新行,并且 pain_score
为 NA。我已经包含了一个与我正在使用的类似的虚拟数据集。
library(tidyverse)
df <-
tibble(
patient_id = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2),
time = lubridate::as_datetime(c("2022-01-04 02:00:00", "2022-01-04 07:00:00", "2022-01-04 15:00:00", "2022-01-04 20:00:00", "2022-01-06 02:00:00", "2022-01-06 08:00:00",
"2022-01-04 04:00:00", "2022-01-04 14:00:00", "2022-01-04 22:00:00", "2022-01-05 02:00:00", "2022-01-05 20:00:00", "2022-01-06 12:00:00", "2022-01-06 18:00:00")),
day = c(1, 1, 1, 1, 3,3, 1, 1, 1, 2, 2, 3, 3),
pain_score = c("None", "Mild", "Mild", "Moderate", "None", "Mild", "Moderate", "Severe", "Moderate", "Mild", "Moderate", "Severe", "Moderate")
)
这是上一篇文章中的代码解决方案:
df |> complete(time = seq.POSIXt(min(ceiling_date(time , 'day')),
max(floor_date(time , 'day')), by = 'day')) |>
arrange(time) |>
fill(c(patient_id, pain_score)) |>
fill(day, .direction = "up") |>
mutate(time_diff_hours = as.numeric(lead(time ) - time, units = 'hours'))
如您所见,当添加第二个
patient_id
时,time_diff_hours
变为负值(最好设为 NA)。此外,当未执行 pain_score
时(即丢失数据),不存在 NA。
这是我想要的输出:
任何帮助将不胜感激。
干杯,
本
bind_rows(df,
df |>
reframe(time = seq.POSIXt(
ceiling_date(min(time), "day"), floor_date(max(time), "day"), "1 day"),
.by = patient_id)) |>
arrange(patient_id, time) |>
mutate(day = as.numeric(as_date(time) - as_date(min(time)) + 1),
time_diff_hours = (lead(time) - time)/dhours(1),
.by = patient_id)
结果
# A tibble: 17 × 5
patient_id time day pain_score time_diff_hours
<dbl> <dttm> <dbl> <chr> <dbl>
1 1 2022-01-04 02:00:00 1 None 5
2 1 2022-01-04 07:00:00 1 Mild 8
3 1 2022-01-04 15:00:00 1 Mild 5
4 1 2022-01-04 20:00:00 1 Moderate 4
5 1 2022-01-05 00:00:00 2 NA 24
6 1 2022-01-06 00:00:00 3 NA 2
7 1 2022-01-06 02:00:00 3 None 6
8 1 2022-01-06 08:00:00 3 Mild NA
9 2 2022-01-04 04:00:00 1 Moderate 10
10 2 2022-01-04 14:00:00 1 Severe 8
11 2 2022-01-04 22:00:00 1 Moderate 2
12 2 2022-01-05 00:00:00 2 NA 2
13 2 2022-01-05 02:00:00 2 Mild 18
14 2 2022-01-05 20:00:00 2 Moderate 4
15 2 2022-01-06 00:00:00 3 NA 12
16 2 2022-01-06 12:00:00 3 Severe 6
17 2 2022-01-06 18:00:00 3 Moderate NA