UPDATE
This is a clear update that shows a neat way of using data.table::as.ITime
. It pretty much combines dickoa 's answer, Frank's comment and my answer for a best result.
library(data.table)
#example vector
vec <- c('09:00 PM', '11:00 PM', '09:00 AM')
#format can be used in the same way as in POSIXct
as.ITime(vec, format = "%I:%M %p") < as.ITime('10:00')
[1] FALSE FALSE TRUE
#notice that as.ITime does not create dates (alongside the times) as POSIX** does
#It only deals with times
#> as.ITime(vec, format = "%I:%M %p")
#[1] "21:00:00" "23:00:00" "09:00:00"
Or by using a data.table as per Frank's comment below:
ivec <- as.ITime(vec)
setDT(list(ivec))[, V1 := as.ITime(vec, "%I:%M %p")]
Original Answer
#using safe.ifelse to keep attributes
#function borrowed from here:
#http://stackoverflow.com/questions/6668963/how-to-prevent-ifelse-from-turning-date-objects-into-numeric-objects
safe.ifelse <- function(cond, yes, no){ class.y <- class(yes)
X <- ifelse(cond,yes,no)
class(X) <-class.y; return(X)}
library(data.table)
#example vec
vec <- c('09:00 PM', '11:00 PM', '09:00 AM')
#convert them to time using as.ITime from data.table and safe.ifelse
#basically I use safe.ifelse to detect PM in the vec
#if there is a PM then I convert that to an 24-hour time by adding 12 hours
new_vec <- safe.ifelse(grepl('PM', vec), as.ITime(vec) + 12*3600, as.ITime(vec))
> new_vec
[1] "21:00:00" "23:00:00" "09:00:00"
Finally comparing with 10:00 AM
> new_vec < as.ITime('10:00')
[1] FALSE FALSE TRUE
Or as mentioned by @Frank in the comments, since vec is a column in your data.frame this would probably be a better approach (and you wouldn't need to use safe.ifelse
):
ivec <- as.ITime(vec)
setDT(list(ivec))[grepl('PM', vec), V1 := V1 + 12L*3600L ]
After seeing @dickoa 's answer, it seems that his answer with a format, works with as.ITime
too:
vec <- c('09:00 PM', '11:00 PM', '09:00 AM')
> as.ITime(vec, "%I:%M %p")
[1] "21:00:00" "23:00:00" "09:00:00"
Which means that a simple:
ivec <- as.ITime(vec)
setDT(list(ivec))[, V1 := as.ITime(vec, "%I:%M %p")]
Would be enough. So, IMO a combination of our answers (and @Frank 's comment) would probably be the best solution (as.ITime
will not create the dates that strptime
does).