这个项目的目的是测量医学实验室检查和最近的药物剂量之间的时间间隔。每个病人都有不同数量的后续剂量的这种药物,和数量的后续实验室检查也是不同的每一个对象。
第一个数据框架包含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在第一次用药前有一次实验室检查,第二组的剂量比实验室检查的要多,第三组的剂量比实验室检查的要少。
我希望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 我尝试过一些合并方案,但没有一个保存所有数据。有4万名受试者,所以用手做是不可行的。任何帮助都很感激。
发布于 2019-10-16 21:13:37
有一个使用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这里的想法是将doses_df在study_id和join_time of labs_df上合并,以尊重dose_df < joint_time和labs_df中的条件join_time。
我创建一个join_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列(合并就像在lab_dt值上子设置doses_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但问题是,它使日期保持在等于或低于。
我使用这个问题来找到equi-joins解决方案,并且我推荐滚动联接的本教程。data.table是快速的,并且允许您在一行中完成实际需要的操作(在合并中,使用符合dose_dt < lab_dt的最后一行)。
https://stackoverflow.com/questions/58420883
复制相似问题