该项目的目的是测量医学实验室检查和最近用药之间的时间间隔。每个患者的后续服药剂量不同,每个受试者的随访实验室检查次数也不同。
第一个数据框包含study_id和相应的给药日期:
library(dplyr)
library(lubridate)
study_id<- c(1, 1, 1, 2, 2, 3)
dose_dt <- c('1/1/00', '2/1/00', '3/1/00', '1/1/01', '2/1/01', '1/1/02')
doses_df <- data.frame(study_id, dose_dt)
doses_df$dose_dt <- mdy(doses_df$dose_dt)
print(doses_df)
study_id dose_dt
1 1 2000-01-01
2 1 2000-02-01
3 1 2000-03-01
4 2 2001-01-01
5 2 2001-02-01
6 3 2002-01-01
第二个数据帧具有匹配的study_id,这次具有实验室检查日期和相关的实验室值以及异常指示(是/否)。
study_id <- c(1, 1, 1, 2, 3, 3, 3)
lab_dt <- c('1/1/99', '3/1/00', '4/1/00', '2/1/01', '2/1/02', '3/1/02', '4/1/02')
lab_result <- c(100, 200, 50, 25, 75, 100, 75)
lab_abn_yn <- c(0, 0, 1, 1, 1, 0, 1)
labs_df <- data.frame(study_id, lab_dt, lab_result, lab_abn_yn)
labs_df$lab_dt <- mdy(labs_df$lab_dt)
print(labs_df)
study_id lab_dt lab_result lab_abn_yn
1 1 1999-01-01 100 0
2 1 2000-03-01 200 0
3 1 2000-04-01 50 1
4 2 2001-02-01 25 1
5 3 2002-02-01 75 1
6 3 2002-03-01 100 0
7 3 2002-04-01 75 1
请注意,受试者1在第一次给药之前已经进行了一次实验室检查,受试者2的剂量比实验室检查的剂量大,受试者3的剂量少于实验室检查的剂量。
我希望R在实验室检查之前确定药物的最新剂量日期,以便我可以计算出剂量与实验室检查之间的间隔。输出将保留实验室值和指标。优选地,在第一剂之前的实验室检查(从剂量到实验室检查的负时间间隔)将被报告为NA,但我可以轻松过滤出负时间间隔。我也知道如何使用lubridate计算时间间隔,因此需要在解释中添加它。
所需的输出:
study_id lab_dt most_recent_dose_dt lab_result lab_abn_yn interval_months
<dbl> <chr> <chr> <chr> <dbl> <dbl>
1 1 1999-01-01 NA NA NA NA
2 1 2000-03-01 2000-02-02 200 0 0.966
3 1 2000-04-01 2000-03-01 50 1 1
4 2 2001-02-01 2001-01-01 25 1 1
5 3 2002-02-01 2002-01-01 75 1 1
6 3 2002-03-01 2002-01-01 100 0 2
7 3 2002-04-01 2002-01-01 75 1 3
我尝试了多种合并方案,但没有一个保留所有数据。大约有40,000个科目,因此手动进行是不可行的。任何帮助,不胜感激。
答案 0 :(得分:2)
使用data.table
连接,non-equi
有一个单行解决方案:
library(data.table)
# create data.tables
labs_df <- setDT(labs_df)
doses_df <- setDT(doses_df)
# create join variable
doses_df[,join_time := dose_dt]
labs_df[,join_time := lab_dt]
# do nonequi join with a condition
doses_df[labs_df,on=.(study_id,join_time < join_time),mult = "last"]
study_id dose_dt join_time lab_dt lab_result lab_abn_yn
1: 1 <NA> 1999-01-01 1999-01-01 100 0
2: 1 2000-02-01 2000-03-01 2000-03-01 200 0
3: 1 2000-03-01 2000-04-01 2000-04-01 50 1
4: 2 2001-01-01 2001-02-01 2001-02-01 25 1
5: 3 2002-01-01 2002-02-01 2002-02-01 75 1
6: 3 2002-01-01 2002-03-01 2002-03-01 100 0
7: 3 2002-01-01 2002-04-01 2002-04-01 75 1
这里的想法是,您正在将{_1}的study_id
和join_time
的{{1}}和labs_df
上的doses_df合并为labs_df。
我创建一个join_time
列,因为联接只保留两个时间列之一,否则会更改名称,所以我总是会感到困惑:如果您直接这样做
joint_time
它给您
join_time
这对doses_df[labs_df,on=.(study_id,dose_dt < lab_dt),mult = "last"]
和其他列来说是正确的,但对 study_id dose_dt lab_result lab_abn_yn
1: 1 1999-01-01 100 0
2: 1 2000-03-01 200 0
3: 1 2000-04-01 50 1
4: 2 2001-02-01 25 1
5: 3 2002-02-01 75 1
6: 3 2002-03-01 100 0
7: 3 2002-04-01 75 1
列却造成了混乱,因为它变成了您进行合并的lab_result
列(合并就像是子设置dose_dt
值上的lab_dt
列。
我实际上想在一开始使用滚动连接:
doses_dt
,但是问题在于它使日期等于或小于日期。
我使用this question查找了等联接解决方案,对于滚动联接,我建议使用this tutorial。
lab_dt
速度很快,可让您在一行中实际完成所需的操作(合并中符合doses_df[labs_df,on=.(study_id,join_time),roll = T]
study_id dose_dt join_time lab_dt lab_result lab_abn_yn
1: 1 <NA> 1999-01-01 1999-01-01 100 0
2: 1 2000-03-01 2000-03-01 2000-03-01 200 0
3: 1 2000-03-01 2000-04-01 2000-04-01 50 1
4: 2 2001-02-01 2001-02-01 2001-02-01 25 1
5: 3 2002-01-01 2002-02-01 2002-02-01 75 1
6: 3 2002-01-01 2002-03-01 2002-03-01 100 0
7: 3 2002-01-01 2002-04-01 2002-04-01 75 1
的最后一行)。
答案 1 :(得分:1)
我们可以分三个步骤进行操作:
请注意,您的样本数据并不完全符合所需的打印结果,因为2月1日成为2月2日进行第二次观察。
library(tidyverse)
library(lubridate)
doses_df <- tibble(
study_id = c(1, 1, 1, 2, 2, 3),
dose_dt = mdy(c("1/1/00", "2/1/00", "3/1/00", "1/1/01", "2/1/01", "1/1/02"))
)
labs_df <- tibble(
study_id = c(1, 1, 1, 2, 3, 3, 3),
lab_dt = mdy(c("1/1/99", "3/1/00", "4/1/00", "2/1/01", "2/1/02", "3/1/02", "4/1/02")),
lab_result = c(100, 200, 50, 25, 75, 100, 75),
lab_abn_yn = c(0, 0, 1, 1, 1, 0, 1)
)
most_recent_doses <- labs_df %>%
left_join(doses_df, by = "study_id") %>%
group_by(study_id, lab_dt) %>%
filter(dose_dt < lab_dt) %>%
filter(dose_dt == max(dose_dt)) %>%
select(study_id, lab_dt, dose_dt)
labs_df %>%
left_join(most_recent_doses, by = c("study_id", "lab_dt")) %>%
mutate(interval_months = interval(dose_dt, lab_dt) / months(1))
#> # A tibble: 7 x 6
#> study_id lab_dt lab_result lab_abn_yn dose_dt interval_months
#> <dbl> <date> <dbl> <dbl> <date> <dbl>
#> 1 1 1999-01-01 100 0 NA NA
#> 2 1 2000-03-01 200 0 2000-02-01 1
#> 3 1 2000-04-01 50 1 2000-03-01 1
#> 4 2 2001-02-01 25 1 2001-01-01 1
#> 5 3 2002-02-01 75 1 2002-01-01 1
#> 6 3 2002-03-01 100 0 2002-01-01 2
#> 7 3 2002-04-01 75 1 2002-01-01 3
由reprex package(v0.3.0)于2019-10-16创建