R 在患者中查找事件和入院之间的时间

R Finding times between events and admissions, within patients

我有一系列患者入院(下面的数据框 'admissions')和一系列事件(第二个数据框称为 'events')。 我想知道事件是否发生在入院后 5 天内。显然必须在患者 ID ('id') 内进行匹配。

在现实生活中,录取数据框包含超过 50 万的录取和 10 万分。一名患者可能有多次入院和多次事件。并非所有患者都会发生事件。

admissions <- structure(list(id = c(1L, 1L, 1L, 2L, 2L, 2L), date = structure(c(16436, 
16443, 16574, 16468, 16481, 16494), class = "Date")), .Names = c("id", 
"date"), row.names = c(NA, 6L), class = "data.frame")

> admissions
  id       date
1  1 2015-01-01
2  1 2015-01-08
3  1 2015-05-19
4  2 2015-02-02
5  2 2015-02-15
6  2 2015-02-28




events <- structure(list(id = c(1L, 1L, 2L), date = structure(c(16453, 
16578, 16467), class = "Date")), .Names = c("id", "date"), row.names = 7:9, class = "data.frame")

> events
  id       date
7  1 2015-01-18
8  1 2015-05-23
9  2 2015-02-01

我想我只需要每个事件相对于入院的最小天数差异(仅考虑正值),在患者中匹配。

Event 1 (id ==1): +10 days (10 days after 08/01/2015)
Event 2 (id ==1): +4 days
Event 3 (id ==2): -1 days

然后我可以 select 我的 window 范围内的那些事件(可能是 5 天)。

我的猜测是涉及 lapply(),但出于某种原因,应用程序对我来说并不是很自然(但是!)。

使用dplyr:

library(dplyr)

mutate(events, event_id=row_number()) %>% # Add event id
    right_join(admissions, by="id") %>% # Join with admissions
    rename(adm_date = date.y, ev_date = date.x) %>% # Clean names
    mutate(diff = ev_date - adm_date) %>% # Compute diffrence
    filter(diff >= 0) %>% # Filter 
    group_by(event_id) %>%
    arrange(diff) %>% # Sort ascending by diff by event_id
    summarise_each(funs(first), ev_date, adm_date, diff) # Get nearest

Source: local data frame [2 x 4]

  event_id    ev_date   adm_date    diff
1        1 2015-01-18 2015-01-08 10 days
2        2 2015-05-23 2015-05-19  4 days

使用 data.table 滚动连接:

keycols <- c("id", "date")

admissions_dt <- admissions %>% mutate(adm_date = date) %>% as.data.table()
setkeyv(admissions_dt, keycols)

events_dt <- mutate(events, event_id=row_number()) %>% as.data.table()
setkeyv(events_dt, keycols)

admissions_dt[events_dt, roll=10][order(event_id)]

   id       date   adm_date event_id
1:  1 2015-01-18 2015-01-08        1
2:  1 2015-05-23 2015-05-19        2
3:  2 2015-02-01       <NA>        3

使用 data.table 1.9.5 作为其 on= 功能。

  1. 对于event中的每一行,找到最接近日期<= admissions$date.

    对应的索引
    idx = setDT(admissions)[events, which=TRUE, roll=TRUE, on=c("id", "date")]
    idx
    # [1]  2  3 NA
    

    如果您已经知道自己只喜欢 5 天 window,那么您可以使用 roll=5 而不是 roll=TRUEroll=<positive number> 执行 LOCF 滚动连接。

  2. 对于 event 的每一行,索引对应于 admission 中的匹配行。所以我们现在可以提取日期如下:

    setDT(events)[, adm_date := admission$date[idx]]
    #    id       date   adm_date
    # 1:  1 2015-01-18 2015-01-08
    # 2:  1 2015-05-23 2015-05-19
    # 3:  2 2015-02-01       <NA>