определить, вводился ли препарат в интервале - PullRequest
4 голосов
/ 28 мая 2020

не может этого понять, хотя и довольно близко (предположительно). Я хочу проверить, вводили ли лекарство в 4-часовом окне.

  drug start stop
1    A     1    3
2    A     7   10
3    A    11   17

лекарство A было начато во время 1 и вводилось до момента 3; затем снова начался в момент 7 и выдан до времени 10 et c.

  t1 t2
1  0  4
2  4  8
3  8 12
4 12 16
5 16 20
6 20 24

это windows, о которых идет речь

ДАННЫЕ:

t1 <- c(0,4,8,12,16,20)
t2 <- t1 + 4
chunks <- data.frame(t1=t1,t2=t2)

drug <- "A"
start <- c(1,7,11)
stop <- c(3,10,17)
times <- data.frame(drug,start,stop)

Ожидаемое решение

  t1 t2 lsg
1  0  4   1
2  4  8   1
3  8 12   1
4 12 16   1
5 16 20   1
6 20 24   0

Попытка решения

test <- function(){
  n <- 1
  for (row in times){
    result <-  (times$start[n] > chunks$t1 & times$stop[n] < chunks$t2) | ((times$start[n] > chunks$t1 & times$start[n] < chunks$t2) & (times$stop[n] > chunks$t2 | times$stop[n] < chunks$t2)) | (times$start[n] < chunks$t1 & times$stop[n] > chunks$t1)
    n <- n + 1 
    print(result)
  }
}

дает

[1]  TRUE FALSE FALSE FALSE FALSE FALSE
[1] FALSE  TRUE  TRUE FALSE FALSE FALSE
[1] FALSE FALSE  TRUE  TRUE  TRUE FALSE

, что правильно! Первое администрирование попало в первое временное окно. 2-я и 3-я администрация попали на 2-ю и 3-ю windows и c. Но как добраться до ожидаемого решения?

Как я уже сказал, я чувствую себя близким, но не знаю, как объединить результаты с chunks-df ...

1 Ответ

3 голосов
/ 28 мая 2020

Первая половина - это комментарий @ akrun, но он расширен за счет включения предварительных условий. (Если вы вернетесь и ответите, я с радостью предоставлю вам более подробную информацию.) Вторая половина новая (и часто упускается из виду).

data.table

data.table::foverlaps выполняет соединения на основе перекрытий / неравенств (в отличие от базовых merge и dplyr::*_join, которые работают только на строгих равенствах). Одним из предварительных условий для использования overlaps (в дополнение к классу data.table) является правильность key полей времени.

library(data.table)
setDT(times)
setDT(chunks)

# set the keys
setkey(times, start, stop)
setkey(chunks, t1, t2)

# the join

+(!is.na(foverlaps(chunks, times, which = TRUE, mult = 'first')))
# [1] 1 1 1 1 1 0

Функция фактически возвращает, какие строки в каждой строке times соответствует в chunks:

foverlaps(chunks, times, which = TRUE, mult = 'first')
# [1]  1  2  2  3  3 NA

sqldf

data.table - не единственный инструмент R, позволяющий это сделать. Это решение работает с любым вариантом data.frame (base, data.table или tbl_df).

Вот это:

library(sqldf)
sqldf("
  select  c.t1, c.t2,
    (case when drug is null then 0 else 1 end) > 0 as n
  from chunks c
    left join times t on
      (t.start between c.t1 and c.t2) or (t.stop between c.t1 and c.t2)
      or (c.t1 between t.start and t.stop) or (c.t2 between t.start and t.stop)
  group by c.t1, c.t2")
#   t1 t2 n
# 1  0  4 1
# 2  4  8 1
# 3  8 12 1
# 4 12 16 1
# 5 16 20 1
# 6 20 24 0

(я не знаю, возможно ли это чтобы уменьшить logi c этого соединения, а также если оно не будет вести себя неправильно с другими данными.)

Если вам нужно количество наркотиков, которые встречаются в каждом временном интервале, я думаю, вы можете использовать sum(case when ... end) as n.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...