首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R:根据索引列查找两个日期中最近的日期。

R:根据索引列查找两个日期中最近的日期。
EN

Stack Overflow用户
提问于 2019-10-16 20:00:09
回答 1查看 132关注 0票数 2

这个项目的目的是测量医学实验室检查和最近的药物剂量之间的时间间隔。每个病人都有不同数量的后续剂量的这种药物,和数量的后续实验室检查也是不同的每一个对象。

第一个数据框架包含study_id和相应的剂量日期:

代码语言:javascript
复制
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,这一次具有实验室检查日期和相关的实验室值以及异常的指示符(是/否)。

代码语言:javascript
复制
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来计算时间间隔,所以需要将其添加到解释中。

期望产出:

代码语言:javascript
复制
  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万名受试者,所以用手做是不可行的。任何帮助都很感激。

EN

回答 1

Stack Overflow用户

发布于 2019-10-16 21:13:37

有一个使用data.table的一行解决方案,使用non-equi联接:

代码语言:javascript
复制
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_idjoin_time of labs_df上合并,以尊重dose_df < joint_time和labs_df中的条件join_time

我创建一个join_time列,因为join只保留了两个time列中的一个,并且更改了名称,所以我总是感到困惑:如果您直接这样做

代码语言:javascript
复制
doses_df[labs_df,on=.(study_id,dose_dt < lab_dt),mult = "last"]

它给了你

代码语言:javascript
复制
   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列一样)。

实际上,我想在开始时使用滚动连接:

代码语言:javascript
复制
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的最后一行)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58420883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档