-1

Working in R, I need to calculate daily infusion volume (mL) given a variable infusion rate (mL/hour).

My dataframe has two columns: date (year, month, day, hours, mins, sec) when the infusion rate was changed, and the new infusion rate (ml/hr). From these data I have calculated cumulative infusion volume for the entire study (~ 3 weeks duration). I now need to calculate infusion volume for every 24 hours, midnight to midnight. The first and last study days are less than 24 hours duration and are excluded.

I don't know how to approach my problem with infusion rates spanning across 24 hour time periods at midnight.

One thought was to generate a new data frame consisting of time in secs (from zero to end of study) and volume infused per second, then sum infusion volume every day. This of course will generate a large (unnecessary) dataframe (>1 million rows).

I am looking for direction on how to approach in R.

No code to share at this time. My dataframe is shared:https://drive.google.com/file/d/1YfZkuOStOxWIXrxklWEo1r46hjFQPIXM/view

DF <- structure(list(`date&time` = structure(c(1519043251, 1519047111, 
1519049877, 1519050201, 1519053454, 1519054180, 1519060742, 1519062334, 
1519083584, 1519108892, 1519114732, 1519118888, 1519127198, 1519140960, 
1519142031, 1519150508, 1519161027, 1519167167, 1519206508, 1519206877, 
1519222879, 1519278875, 1519290863, 1519293411, 1519314864, 1519317665, 
1519334695, 1519364934, 1519364996, 1519378625, 1519384577, 1519428049, 
1519495090, 1519541667, 1519544091, 1519551993, 1519594678, 1519626216, 
1519650059, 1519658045, 1519712871, 1519722853, 1519726863, 1519744270, 
1519786071, 1519787755, 1519788820, 1519789685, 1519791798, 1519801303, 
1519801380, 1519809813, 1519815924, 1519826260, 1519830433, 1519833629, 
1519841284, 1519857415, 1519885051, 1519885120, 1519885141, 1519887091, 
1519939049, 1519939482, 1519945740, 1519971397, 1519975527, 1519987363, 
1519988481, 1520004464, 1520033974, 1520093329, 1520179994, 1520204550, 
1520233073, 1520237983, 1520238103, 1520241519, 1520241904, 1520263216, 
1520290670, 1520349278, 1520370509, 1520406514, 1520436434, 1520447318, 
1520456518, 1520461383, 1520501027, 1520522600, 1520542062, 1520590191, 
1520618693, 1520621059, 1520626341, 1520627226, 1520630596, 1520637370, 
1520664044, 1520676143, 1520689466, 1520717079, 1520724147, 1520754787, 
1520788241, 1520806426, 1520818840, 1520829807, 1520839843, 1520839936, 
1520891100, 1520897458, 1520921676, 1520933752), class = c("POSIXct", 
"POSIXt"), tzone = "UTC"), `infusion rate` = c(25.75, 30.75, 
25.75, 25.81, 25.81, 25.75, 25.65, 25.65, 27.55, 18.47, 18.25, 
16.25, 15.25, 13.25, 13.25, 15.25, 16.25, 15.25, 15.45, 12.45, 
12.25, 12.45, 11.45, 11.5, 11.57, 13.57, 11.57, 10.57, 10.55, 
11.55, 13.55, 13.52, 13.56, 13.64, 13.7, 13.67, 13.67, 13.65, 
14.65, 14.61, 14.67, 14.69, 13.69, 13.67, 16.67, 21.67, 24.67, 
29.67, 34.67, 29.67, 29.65, 24.65, 22.65, 19.65, 19.65, 17.65, 
14.65, 14.63, 14.65, 15.65, 14.65, 15.65, 16.65, 15.65, 15.68, 
15.71, 15.74, 15.81, 15.92, 15.89, 15.9, 15.94, 15.93, 14.94, 
15.92, 16.03, 15.03, 15, 15.02, 14.96, 14.91, 14.93, 14.94, 14.94, 
14.91, 14.92, 14.92, 14.92, 14.94, 14.95, 15.95, 14.95, 16.95, 
19.95, 22.95, 25.95, 26.95, 26.93, 26.89, 23.89, 20.89, 18.89, 
18.87, 16.87, 15.87, 15.87, 14.87, 17.87, 16.87, 16.98, 17.98, 
16.98, 15.98, 0)), row.names = 2:115, class = "data.frame")

I need the output to be two columns of data; time in days and daily infusion volume.

Uwe
  • 41,420
  • 11
  • 90
  • 134
  • 1
    Please provide a reproducible example. https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – bbiasi May 05 '19 at 21:44
  • Hey bbiasi - I don't believe I can provide a repex without code (correct me if I am wrong, very new to this forum & coding in general) - I'm looking for direction on how to tackle my problem. Please point me in best direction for initial code and I'll do my best to research and problem solve by myself before posting to back to forum for further help. Thanks! – Marcus3107 May 05 '19 at 23:51
  • Hi @Marcus3107 and welcome to SO. You could show us a sample of your data (using `dput`)...maybe the first week. That would help and give us something to work with. – c1au61o_HH May 06 '19 at 01:05
  • Hi c1au61o_HH. As requested, please find my dataframe at : https://drive.google.com/file/d/1YfZkuOStOxWIXrxklWEo1r46hjFQPIXM/view?usp=sharing. Format is time at which infusion rate was changed (year-month-day hour:min:seconds) and the new infusion rate. – Marcus3107 May 06 '19 at 12:23

1 Answers1

0

One possible solution is to use the foverlaps() function from the data.table package. foverlaps() finds all overlapping intervals (ranges, periods) by an overlap join:

library(data.table)
# coerce to data.table
setDT(DF)
# rename column names (syntactically correct)
setnames(DF, names(DF) %>% make.names())
DF
# create intervals (ranges) of infusion periods
DF_ranges <- DF[, .(start = head(date.time, -1L), 
                    end = tail(date.time, -1L),
                    inf.rate = head(infusion.rate, -1L))]
setkey(DF_ranges, start, end)
# create sequence of calendar days (starting at midnight)
day_seq <- DF[, seq(lubridate::floor_date(min(date.time), "day"), 
                    max(date.time), "1 day")]
# create intervals of days (from midnight to midnight)
day_ranges <- data.table(start = day_seq, end = day_seq + as.difftime(1, units = "days"))
# find all overlapping intervals (overlap join )
ovl <- foverlaps(day_ranges, DF_ranges)
# compute duration of infusion periods within each day
ovl[, inf.hours := difftime(pmin(end, i.end), pmax(start, i.start), units = "hours")]
# compute infusion volume for each period
ovl[, inf.vol := inf.rate * as.double(inf.hours)]
# aggregate by day
ovl[, .(inf.vol.per.day = sum(inf.vol)), by = .(day = as.Date(i.start))][
  # drop first and last day 
  -c(1L, .N)]
           day inf.vol.per.day
 1: 2018-02-20        455.7107
 2: 2018-02-21        324.6403
 3: 2018-02-22        293.5880
 4: 2018-02-23        298.9512
 5: 2018-02-24        324.7212
 6: 2018-02-25        327.3658
 7: 2018-02-26        338.3609
 8: 2018-02-27        338.1620
 9: 2018-02-28        507.9508
10: 2018-03-01        368.7672
11: 2018-03-02        379.4539
12: 2018-03-03        381.9141
13: 2018-03-04        381.5335
14: 2018-03-05        360.6198
15: 2018-03-06        358.0437
16: 2018-03-07        358.3588
17: 2018-03-08        361.6632
18: 2018-03-09        421.2107
19: 2018-03-10        567.7771
20: 2018-03-11        413.8286
21: 2018-03-12        403.4742
           day inf.vol.per.day

The intermediate results are

DF_ranges
                   start                 end inf.rate
  1: 2018-02-19 12:27:31 2018-02-19 13:31:51    25.75
  2: 2018-02-19 13:31:51 2018-02-19 14:17:57    30.75
  3: 2018-02-19 14:17:57 2018-02-19 14:23:21    25.75
  4: 2018-02-19 14:23:21 2018-02-19 15:17:34    25.81
  5: 2018-02-19 15:17:34 2018-02-19 15:29:40    25.81
 ---                                                 
109: 2018-03-12 07:30:43 2018-03-12 07:32:16    16.87
110: 2018-03-12 07:32:16 2018-03-12 21:45:00    16.98
111: 2018-03-12 21:45:00 2018-03-12 23:30:58    17.98
112: 2018-03-12 23:30:58 2018-03-13 06:14:36    16.98
113: 2018-03-13 06:14:36 2018-03-13 09:35:52    15.98
day_ranges
         start        end
 1: 2018-02-19 2018-02-20
 2: 2018-02-20 2018-02-21
 3: 2018-02-21 2018-02-22
 4: 2018-02-22 2018-02-23
 5: 2018-02-23 2018-02-24
 6: 2018-02-24 2018-02-25
 7: 2018-02-25 2018-02-26
 8: 2018-02-26 2018-02-27
 9: 2018-02-27 2018-02-28
10: 2018-02-28 2018-03-01
11: 2018-03-01 2018-03-02
12: 2018-03-02 2018-03-03
13: 2018-03-03 2018-03-04
14: 2018-03-04 2018-03-05
15: 2018-03-05 2018-03-06
16: 2018-03-06 2018-03-07
17: 2018-03-07 2018-03-08
18: 2018-03-08 2018-03-09
19: 2018-03-09 2018-03-10
20: 2018-03-10 2018-03-11
21: 2018-03-11 2018-03-12
22: 2018-03-12 2018-03-13
23: 2018-03-13 2018-03-14
         start        end
foverlaps(day_ranges, DF_ranges)
                   start                 end inf.rate    i.start      i.end
  1: 2018-02-19 12:27:31 2018-02-19 13:31:51    25.75 2018-02-19 2018-02-20
  2: 2018-02-19 13:31:51 2018-02-19 14:17:57    30.75 2018-02-19 2018-02-20
  3: 2018-02-19 14:17:57 2018-02-19 14:23:21    25.75 2018-02-19 2018-02-20
  4: 2018-02-19 14:23:21 2018-02-19 15:17:34    25.81 2018-02-19 2018-02-20
  5: 2018-02-19 15:17:34 2018-02-19 15:29:40    25.81 2018-02-19 2018-02-20
 ---                                                                       
131: 2018-03-12 07:32:16 2018-03-12 21:45:00    16.98 2018-03-12 2018-03-13
132: 2018-03-12 21:45:00 2018-03-12 23:30:58    17.98 2018-03-12 2018-03-13
133: 2018-03-12 23:30:58 2018-03-13 06:14:36    16.98 2018-03-12 2018-03-13
134: 2018-03-12 23:30:58 2018-03-13 06:14:36    16.98 2018-03-13 2018-03-14
135: 2018-03-13 06:14:36 2018-03-13 09:35:52    15.98 2018-03-13 2018-03-14
ovl
                   start                 end inf.rate    i.start      i.end        inf.hours    inf.vol
  1: 2018-02-19 12:27:31 2018-02-19 13:31:51    25.75 2018-02-19 2018-02-20  1.0722222 hours  27.609722
  2: 2018-02-19 13:31:51 2018-02-19 14:17:57    30.75 2018-02-19 2018-02-20  0.7683333 hours  23.626250
  3: 2018-02-19 14:17:57 2018-02-19 14:23:21    25.75 2018-02-19 2018-02-20  0.0900000 hours   2.317500
  4: 2018-02-19 14:23:21 2018-02-19 15:17:34    25.81 2018-02-19 2018-02-20  0.9036111 hours  23.322203
  5: 2018-02-19 15:17:34 2018-02-19 15:29:40    25.81 2018-02-19 2018-02-20  0.2016667 hours   5.205017
 ---                                                                                                   
131: 2018-03-12 07:32:16 2018-03-12 21:45:00    16.98 2018-03-12 2018-03-13 14.2122222 hours 241.323533
132: 2018-03-12 21:45:00 2018-03-12 23:30:58    17.98 2018-03-12 2018-03-13  1.7661111 hours  31.754678
133: 2018-03-12 23:30:58 2018-03-13 06:14:36    16.98 2018-03-12 2018-03-13  0.4838889 hours   8.216433
134: 2018-03-12 23:30:58 2018-03-13 06:14:36    16.98 2018-03-13 2018-03-14  6.2433333 hours 106.011800
135: 2018-03-13 06:14:36 2018-03-13 09:35:52    15.98 2018-03-13 2018-03-14  3.3544444 hours  53.604022
Uwe
  • 41,420
  • 11
  • 90
  • 134