Reputation: 5719
I have my time and date as
tt <- structure(list(Date = structure(c(1L, 1L, 1L, 1L, 3L, 3L), .Label = c("2018-10-27",
"2018-10-28", "2018-11-15"), class = "factor"), Time = c("21:07:30.004",
"21:07:31.000", "21:07:32.998", "21:07:32.000", "21:07:33.989",
"21:08:33.989")), row.names = c(NA, 6L), class = "data.frame")
I would like to get the smallest to largest time range for each date as:
Date Time
2018-10-27 21:07:30 to 21:07:32
2018-11-15 21:07:33 to 21:08:33
Code I tried:
time.range <- function(field_or_seed){
paste0(gsub(".* ", "", range(strptime(field_or_seed$Time, format = "%H:%M:%S", tz = 'UTC'))[[1]]), " to ",
gsub(".* ", "", range(strptime(field_or_seed$Time, format = "%H:%M:%S", tz = 'UTC'))[[2]]))
}
aggregate(Time~Date, data = tt, FUN = time.range)
I would really appreciate any suggestion I could use to fix this. Thanks!
Upvotes: 1
Views: 104
Reputation: 43354
A more robust approach is to use appropriate objects, e.g. Date
and hms
:
library(tidyverse)
tt <- tibble(
Date = c("2018-10-27", "2018-10-27", "2018-10-27", "2018-10-27", "2018-11-15", "2018-11-15"),
Time = c("21:07:30.004", "21:07:31.000", "21:07:32.998", "21:07:32.000", "21:07:33.989", "21:08:33.989")
)
tt %>%
mutate(Date = as.Date(Date),
Time = hms::as_hms(Time)) %>%
group_by(Date) %>%
summarise(start = Time[which.min(Time)], # which.min instead of min to avoid dropping class
end = Time[which.max(Time)])
#> # A tibble: 2 x 3
#> Date start end
#> <date> <time> <time>
#> 1 2018-10-27 21:07:30.004 21:07:32.998
#> 2 2018-11-15 21:07:33.989 21:08:33.989
If you like you could use lubridate::interval
to represent the interval, but you'd have to use POSIXct.
Upvotes: 2
Reputation: 4505
Also:
aggregate(
data.frame(Time = strptime(do.call(paste, tt), '%F %R:%OS', tz = 'GMT')),
by = list(Date = tt$Date),
function(Time){
paste(
format(min(Time), '%T'),
format(max(Time), '%T'),
sep = ' to '
)
}
)
# Date Time
#1 2018-10-27 21:07:30 to 21:07:32
#2 2018-11-15 21:07:33 to 21:08:33
Upvotes: 0
Reputation: 669
Try:
tt$date_time <- as.POSIXct(paste(tt$Date, tt$Time))
do.call(rbind, by(
tt,
tt$Date,
FUN = function(x) {
within(x, Time <-
paste(strftime(min(date_time), "%H:%M:%S"),
"to",
strftime(max(date_time), "%H:%M:%S")))[1, -3]
}
))
Upvotes: 1