【问题标题】:Finding the minimum date for matching record in another data frame在另一个数据框中查找匹配记录的最短日期
【发布时间】:2017-02-08 22:55:03
【问题描述】:

我有一个这样的医院遭遇数据集:

  VISIT_KEY PAT_KEY DICT_ENC_TYPE_KEY     HOSP_DISCHRG_DT MED_ORD_ID HAD_FOLLOWUP
1  82919395 8979499                83 2014-09-07 10:47:00   58826846            1
2  82919395 8979499                83 2014-09-07 10:47:00   58826847            1
3  82919395 8979499                83 2014-09-07 10:47:00   58826848            1
4  82919395 8979499                83 2014-09-07 10:47:00   58826845            1
5  77312433 8979499                83 2015-02-01 09:33:00   98525833            1
6  77312433 8979499                83 2015-02-01 09:33:00   98525834            1
7  77312433 8979499                83 2015-02-01 09:33:00   98525835            1

还有一组这样的后续遭遇:

  VISIT_KEY PAT_KEY DICT_ENC_TYPE_KEY     APPT_CHECKIN_DT
1  84273751 8979499               108 2015-02-07 11:57:46
2  83999897 8979499               108 2014-09-13 16:51:22
3  83881023 8979499               108 2014-11-12 10:37:51
4  83999896 8979499               108 2014-11-20 09:23:25
5  95164335 8979499               108 2016-07-27 15:30:25
6  83922326 8979499               108 2014-11-16 09:08:47

我正在尝试将 APP_CHECKIN_DT 的最小值用于医院遭遇数据集的新字段 FOLLOWUP_DT。这需要是也大于 HOSP_DISCHRG_DT 的最小 APP_CHECKIN_DT。

例如:

  • 对于 VISIT_KEY = 82919395,第二个数据集中大于该患者 2014-09-07 10:47:00 的 HOSP_DISCHRG_DT 的最早 APP_CHECKIN_DT 将是 2014-09-13 16:51:22
  • 对于 VISIT_KEY = 77312433,第二个数据集中大于该患者 2015-02-01 09:33:00 的 HOSP_DISCHRG_DT 的最早 APP_CHECKIN_DT 将是 2015-02-07 11:57:46

最终的医院遭遇数据集如下所示:

  VISIT_KEY PAT_KEY DICT_ENC_TYPE_KEY     HOSP_DISCHRG_DT MED_ORD_ID HAD_FOLLOWUP         FOLLOWUP_DT
1  82919395 8979499                83 2014-09-07 10:47:00   58826846            1 2014-09-13 16:51:22
2  82919395 8979499                83 2014-09-07 10:47:00   58826847            1 2014-09-13 16:51:22
3  82919395 8979499                83 2014-09-07 10:47:00   58826848            1 2014-09-13 16:51:22
4  82919395 8979499                83 2014-09-07 10:47:00   58826845            1 2014-09-13 16:51:22
5  77312433 8979499                83 2015-02-01 09:33:00   98525833            1 2015-02-07 11:57:46
6  77312433 8979499                83 2015-02-01 09:33:00   98525834            1 2015-02-07 11:57:46
7  77312433 8979499                83 2015-02-01 09:33:00   98525835            1 2015-02-07 11:57:46

我用下面的 ifelse 语句尝试了一些 FOR 循环,以查看遇到是否有后续行动,然后获取 APPT_CHECKIN_DT 看看医院遇到的 PAT_KEY 是否与门诊遇到的 PAT_KEY 匹配,并且 APPT_CHECKIN_DT 是否大于 HOSP_DISCHRG_DT,并且然后取最小的 APPT_CHECKIN_DT 得到后续日期:

for (i in 1:nrow(children_dx)) {
  children_dx$FOLLOW_UP_DATE[i] <- 
    ifelse(children_dx$HAD_FOLLOWUP[i] == 1,
           ifelse(outpatient_visits$APPT_CHECKIN_DT[children_dx$PAT_KEY[i] == outpatient_visits$PAT_KEY] > children_dx$HOSP_DISCHRG_DT[i],
                  as.character(min(outpatient_visits$APPT_CHECKIN_DT[children_dx$PAT_KEY[i] == outpatient_visits$PAT_KEY])),
                  NA),NA)
}    

但是,这需要很长时间才能运行完整的数据集,即使完成后,FOLLOWUP_DATE 也是整个数据集的 APPT_CHECKIN_DT 的总体最小值,而不仅仅是 PAT_KEY 匹配的记录。

【问题讨论】:

    标签: r date datetime if-statement for-loop


    【解决方案1】:

    考虑 merge子集 然后 aggregatemin 然后 merge 在原始 df 上:

    数据

    setClass('myDate')
    setAs('character', 'myDate', function(from) as.POSIXct(from, format='%Y-%m-%d %H:%M:%S'))
    
    hospital_encounters <- read.table(text="
                VISIT_KEY PAT_KEY DICT_ENC_TYPE_KEY     HOSP_DISCHRG_DT MED_ORD_ID HAD_FOLLOWUP
                1  82919395 8979499                83 '2014-09-07 10:47:00'   58826846            1
                2  82919395 8979499                83 '2014-09-07 10:47:00'   58826847            1
                3  82919395 8979499                83 '2014-09-07 10:47:00'   58826848            1
                4  82919395 8979499                83 '2014-09-07 10:47:00'   58826845            1
                5  77312433 8979499                83 '2015-02-01 09:33:00'   98525833            1
                6  77312433 8979499                83 '2015-02-01 09:33:00'   98525834            1
                7  77312433 8979499                83 '2015-02-01 09:33:00'   98525835            1", 
                header=TRUE, colClasses = c('numeric', 'numeric', 'numeric', 'numeric', 'myDate', 'numeric', 'numeric'),
                stringsAsFactors = FALSE)    
    
    follow_up_encounters <- read.table(text="  VISIT_KEY PAT_KEY DICT_ENC_TYPE_KEY     APPT_CHECKIN_DT
                1  84273751 8979499               108 '2015-02-07 11:57:46'
                2  83999897 8979499               108 '2014-09-13 16:51:22'
                3  83881023 8979499               108 '2014-11-12 10:37:51'
                4  83999896 8979499               108 '2014-11-20 09:23:25'
                5  95164335 8979499               108 '2016-07-27 15:30:25'
                6  83922326 8979499               108 '2014-11-16 09:08:47'",
                header=TRUE, colClasses = c('numeric', 'numeric', 'numeric', 'numeric', 'myDate'),
                stringsAsFactors = FALSE)
    

    流程

    mdf <- subset(merge(hospital_encounters, follow_up_encounters[c("PAT_KEY", "APPT_CHECKIN_DT")], 
                  by=c("PAT_KEY")), APPT_CHECKIN_DT > HOSP_DISCHRG_DT)
    
    aggdf <- setNames(aggregate(APPT_CHECKIN_DT~ PAT_KEY + VISIT_KEY, mdf, FUN=min),
                      c("PAT_KEY", "VISIT_KEY", "FOLLOWUP_DT"))
    
    hospital_encounters <- merge(hospital_encounters, aggdf, c("PAT_KEY", "VISIT_KEY"))
    

    输出

    hospital_encounters
    
    #   PAT_KEY VISIT_KEY DICT_ENC_TYPE_KEY     HOSP_DISCHRG_DT MED_ORD_ID HAD_FOLLOWUP         FOLLOWUP_DT
    # 1 8979499  77312433                83 2015-02-01 09:33:00   98525833            1 2015-02-07 11:57:46
    # 2 8979499  77312433                83 2015-02-01 09:33:00   98525834            1 2015-02-07 11:57:46
    # 3 8979499  77312433                83 2015-02-01 09:33:00   98525835            1 2015-02-07 11:57:46
    # 4 8979499  82919395                83 2014-09-07 10:47:00   58826846            1 2014-09-13 16:51:22
    # 5 8979499  82919395                83 2014-09-07 10:47:00   58826847            1 2014-09-13 16:51:22
    # 6 8979499  82919395                83 2014-09-07 10:47:00   58826848            1 2014-09-13 16:51:22
    # 7 8979499  82919395                83 2014-09-07 10:47:00   58826845            1 2014-09-13 16:51:22
    

    【讨论】:

    • 这看起来像它的工作,但我不断收到此错误:Error in min.default(c(1420043124, 1420043124, 1420043124, 1420043124, : invalid 'type' (list) of argument 尝试获得最小值时
    • 在您的实际数据框中,日期是实际日期、字符、因素吗?尝试转换为 POSIXct 类型。如果您在此解决方案和代码中运行数据示例,您会看到解决方案有效。
    【解决方案2】:

    使用data.table 解决这个问题可能更容易更快

    library(data.table)
    
    #read in the data, convert to data.table using setDT, convert the datetime column into POSIX format, set up a joining key
    dt1 <- setDT(read.table(text="VISIT_KEY PAT_KEY DICT_ENC_TYPE_KEY     HOSP_DISCHRG_DT MED_ORD_ID HAD_FOLLOWUP
    82919395 8979499                83 '2014-09-07 10:47:00'   58826846            1
    82919395 8979499                83 '2014-09-07 10:47:00'   58826847            1
    82919395 8979499                83 '2014-09-07 10:47:00'   58826848            1
    82919395 8979499                83 '2014-09-07 10:47:00'   58826845            1
    77312433 8979499                83 '2015-02-01 09:33:00'   98525833            1
    77312433 8979499                83 '2015-02-01 09:33:00'   98525834            1
    77312433 8979499                83 '2015-02-01 09:33:00'   98525835            1", header=TRUE))[,
        HOSP_DISCHRG_DT:=strptime(HOSP_DISCHRG_DT, format="%Y-%m-%d %H:%M:%S")][,
            KEY_DATE:=HOSP_DISCHRG_DT]
    
    dt2 <- setDT(read.table(text="VISIT_KEY PAT_KEY DICT_ENC_TYPE_KEY APPT_CHECKIN_DT
    84273751 8979499               108 '2015-02-07 11:57:46'
    83999897 8979499               108 '2014-09-13 16:51:22'
    83881023 8979499               108 '2014-11-12 10:37:51'
    83999896 8979499               108 '2014-11-20 09:23:25'
    95164335 8979499               108 '2016-07-27 15:30:25'
    83922326 8979499               108 '2014-11-16 09:08:47'", header=TRUE))[,
        APPT_CHECKIN_DT:=strptime(APPT_CHECKIN_DT, format="%Y-%m-%d %H:%M:%S")][,
            list(APPT_CHECKIN_DT, KEY_DATE=APPT_CHECKIN_DT)]
    
    #do check out ?data.table to understand the meaning of roll
    dt2[dt1, on="KEY_DATE", roll=-Inf][, 
        KEY_DATE:=NULL]    #remove the joining key
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-17
      • 1970-01-01
      • 2022-08-19
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      • 2016-06-11
      • 1970-01-01
      相关资源
      最近更新 更多