Как рассчитать скользящую сумму с переменными уровнями истощения в R? - PullRequest
0 голосов
/ 27 декабря 2018

Я пытаюсь использовать R, чтобы измерить, сколько дней отпуска рецепта у человека уже есть под рукой, когда он делает пополнение, принимая во внимание все предыдущие рецепты.Например, если бы у меня была эта таблица ...

  member rx_id  fill_date    to_date days_supply
1      A     1 2018-10-01 2018-10-02           2
2      B     1 2016-11-07 2016-11-10           4
3      B     2 2016-11-07 2016-12-04          28
4      B     3 2016-11-08 2016-11-09           2
5      B     4 2016-11-10 2016-12-03          24

Я бы ожидал следующий вывод

  member rx_id  fill_date    to_date days_supply_on_hand
1      A     1 2018-10-01 2018-10-02                   0
2      B     1 2016-11-07 2016-11-10                   0
3      B     2 2016-11-07 2016-12-04                   4
4      B     3 2016-11-08 2016-11-09                  30
5      B     4 2016-11-10 2016-12-03                  26

Для элемента B, когда второй сценарий заполнен в тот же деньВ качестве первого сценария у человека уже есть RX на 4 дня.Когда третий сценарий заполнен, у человека остается 3 дня от первого сценария и 27 дней от второго (всего 30).Когда четвертый сценарий заполнен, третий сценарий исчерпан, но от первого сценария осталось 1 день и от третьего сценария 25 (всего 26).

Я знаю, как выполнить промежуточные итоги в обоих dplyrи data.table, но я не могу понять, как принять во внимание переменные уровни истощения на основе предыдущих записей по отдельным лицам.Ниже приведен код для переделки оригинальной таблицы, заранее спасибо за любые предложения!

structure(list(member = structure(c(1L, 2L, 2L, 2L, 2L), .Label = 
c("A", 
"B"), class = "factor"), rx_id = c(1, 1, 2, 3, 4), fill_date = 
structure(c(17805, 
17112, 17112, 17113, 17115), class = "Date"), to_date = 
structure(c(17806, 
17115, 17139, 17114, 17138), class = "Date"), days_supply = c(2, 
4, 28, 2, 24)), .Names = c("member", "rx_id", "fill_date", 
"to_date", 
"days_supply"), row.names = c(NA, -5L), class = "data.frame")

Ответы [ 2 ]

0 голосов
/ 27 декабря 2018
library(data.table)
dt = as.data.table(your_df) # or setDT to convert in place

# merge on relevant days, then compute sum of supply - days elapsed
dt[dt, on = .(member, fill_date <= fill_date, to_date >= fill_date, rx_id < rx_id), by = .EACHI,
   sum(days_supply, na.rm = T) - sum(i.fill_date - x.fill_date, na.rm = T)]
#   member  fill_date    to_date rx_id      V1
#1:      A 2018-10-01 2018-10-01     1  0 days
#2:      B 2016-11-07 2016-11-07     1  0 days
#3:      B 2016-11-07 2016-11-07     2  4 days
#4:      B 2016-11-08 2016-11-08     3 30 days
#5:      B 2016-11-10 2016-11-10     4 26 days
0 голосов
/ 27 декабря 2018

Используя простой цикл

dt$days_supply_on_hand <- 0
for (a in unique(dt$member)) {
  I <- which(.subset2(dt,1) == a)
  flDate <- as.integer(.subset2(dt,3)[I])
  toDate <- as.integer(.subset2(dt,4)[I])
  V <- vapply(seq_along(I), function (k) sum(toDate[1:(k-1)] - flDate[k] + 1), numeric(1))
  dt$days_supply_on_hand[I] <- c(0,V[-1])
}
dt
  member rx_id  fill_date    to_date days_supply days_supply_on_hand
1      A     1 2018-10-01 2018-10-02           2                   0
2      B     1 2016-11-07 2016-11-10           4                   0
3      B     2 2016-11-07 2016-12-04          28                   4
4      B     3 2016-11-08 2016-11-09           2                  30
5      B     4 2016-11-10 2016-12-03          24                  26

, где dt - кадр данных, представленный выше.(Обратите внимание, что использование .subset2 или as.integer предназначено для повышения эффективности - их можно изменить для большей читабельности).

...