Here are a few solutions.
1) ave This uses chron times
as well as subset
and ave
from the base of R:
library(chron)
delta <- as.vector(times(df$time1) - times(df$time2))
df2 <- subset(df, delta > 0)
df2[ave(delta, df2$id, FUN = function(delta) delta == min(delta)) == 1, ]
2) dplyr This uses chron times
and the dplyr package:
library(chron)
library(dplyr)
df %.%
mutate(delta = as.vector(times(time1) - times(time2))) %.%
filter(delta > 0) %.%
group_by(id) %.%
filter(delta == min(delta)) %.%
select(- delta)
3) sqldf
library(sqldf)
sqldf("select *, min(strftime('%s', time1) - strftime('%s', time2)) delta
from (select * from df where strftime('%s', time1) > strftime('%s', time2))
group by id")[seq_along(df)]
or perhaps this variation where we calculate delta
in R and then use sqldf
:
library(sqldf)
library(chron)
df2 = transform(df, delta = as.vector(times(time1) - times(time2)))
sqldf("select *, min(delta) delta
from (select * from df2 where delta > 0)
group by id")[-ncol(df2)]
4) data.table
library(data.table)
library(chron)
DT <- data.table(df)
DT[, delta := times(time1) - times(time2)
][delta > 0
][, .SD[delta == min(delta)], by = id
][, seq_along(df), with = FALSE]
ADDED additional solutions. Corrected library
and subset
statements. Minor improvements.