如何计算R中行之间经过的时间

时间:2019-07-17 22:40:40

标签: r datetime

我将日期和时间作为单独的列,我使用library(lubridate)将其合并为一个列 现在,我想创建一个新列,该列将为每个唯一ID计算连续两行之间的经过时间

我尝试了diff,但是我得到的错误是与原始数据集相比,新列具有+1行

const memo = function () {
  let cache = [];
  return function (n) {
    if (cache.includes(n)) { console.log("already in memory") }
    else { console.log("first"); cache.push(n); }
  }
}();

memo(7) //first
memo(7) //already in memory
memo(7) //already in memory
memo(1) //first
memo(1) //already in memory
s1$DT<-with(s1, mdy(Date.of.Collection) + hm(MILITARY.TIME))#this worked - #needs the library lubridate
s1$ElapsedTime<-difff(s1$DT)
units(s1$ElapsedTime)<-"hours"

1 个答案:

答案 0 :(得分:1)

从您的评论中,您不需要“ diff”;在传统的R口语中,“差异”是 T 1 -T 0 T 2 -T 1 T 3 -T 2 ,..., T n -T n-1

对于您来说,其中之一将为您提供 T 1,2,...,n -T 0 。< / p>

基本R

do.call(
  rbind,
  by(patients, patients$Subject.ID, function(x) {
    x$elapsed <- x$realDT - x$realDT[1]
    units(x$elapsed) <- "hours"
    x
  })
)
#     Subject.ID       time1        DT  Time          elapsed              realDT
# 1.1          1        Dose  8/1/2018  8:15   0.000000 hours 2018-08-01 08:15:00
# 1.2          1 time_point1  8/1/2018  9:56   1.683333 hours 2018-08-01 09:56:00
# 1.3          1 time_point2  8/2/2018  9:56  25.683333 hours 2018-08-02 09:56:00
# 2.4          2        Dose  9/4/2018 10:50   0.000000 hours 2018-09-04 10:50:00
# 2.5          2 time_point1 9/11/2018 11:00 168.166667 hours 2018-09-11 11:00:00
# 3.6          3        Dose 10/1/2018 10:20   0.000000 hours 2018-10-01 10:20:00
# 3.7          3 time_point1 10/2/2018 14:22  28.033333 hours 2018-10-02 14:22:00
# 3.8          3 time_point2 10/3/2018 12:15  49.916667 hours 2018-10-03 12:15:00

dplyr

library(dplyr)
patients %>%
  group_by(Subject.ID) %>%
  mutate(elapsed = `units<-`(realDT - realDT[1], "hours")) %>%
  ungroup()

data.table

library(data.table)
patDT <- copy(patients)
setDT(patDT)
patDT[, elapsed := `units<-`(realDT - realDT[1], "hours"), by = "Subject.ID"]

注意:

  • $elapsed列中的“小时数”只是处理时差问题的产物,它不应该影响大多数操作。要摆脱它,请确保您使用的单位正确(“小时”,“秒”,...,请参见?units)并使用as.numeric
  • 我如上所述使用as.POSIXct的唯一原因是我不是lubridate用户,并且提供的数据不是时间格式。如果您的Time是正确的时间格式,则无需使用该字段,在这种情况下,您将使用该字段而不是我的hacky realDT
  • 在相似的行上,如果您确实计算了realDT并使用了它,则确实不需要realDT以及一对DTTime

我使用的数据:

patients <- read.table(header=TRUE, stringsAsFactors=FALSE, text="
Subject.ID  time1    DT  Time elapsed
1   Dose    8/1/2018 8:15   0
1   time_point1 8/1/2018 9:56   0.070138889
1   time_point2 8/2/2018 9:56   1.070138889
2   Dose    9/4/2018 10:50  0
2   time_point1 9/11/2018 11:00 7.006944444
3   Dose    10/1/2018 10:20 0
3   time_point1 10/2/2018 14:22 1.168055556
3   time_point2 10/3/2018 12:15 2.079861111")
# this is necessary for me because DT/Time here are not POSIXt (they're just strings)
patients$realDT <- as.POSIXct(paste(patients$DT, patients$Time), format = "%m/%d/%Y %H:%M")