3

I have a local.time column in my data frame of class character containing elements like this :

> a$local.time
 [1] "1:30 AM"  "6:29 AM"  "6:59 AM"  "9:54 AM"  "10:14 AM" "10:34 AM" "12:54 PM" "1:15 PM"  "1:20 PM" 
 [10] "1:20 PM"  "2:15 PM"  "2:15 PM"  "4:23 AM"  "6:28 AM"  "2:45 PM"  "3:08 PM"  "3:23 PM"  "3:58 PM" 

I wanted to convert them from class character to time variables. So I used:

> as.POSIXct(a$local.time, tz = "", format = "%I:%M %p", usetz = FALSE)

This resulted in :

[1] "2014-10-31 01:30:00 EDT" "2014-10-31 06:29:00 EDT" "2014-10-31 06:59:00 EDT" "2014-10-31       09:54:00 EDT"
[5] "2014-10-31 10:14:00 EDT" "2014-10-31 10:34:00 EDT" "2014-10-31 12:54:00 EDT" "2014-10-31 13:15:00 EDT"

I have a date variable in a different column and the intention is to provide the capability of filtering by date and zooming on time bands to the minute in a dynamic dashboard.

I want to remove the date and time zone from a$local.time but keep it in a time format so the chronology is maintained i.e. 18:57 is the 19th hour and 57th minute of the day etc.

If I use

a$local.time <- format(a$local.time, "%Y-%m-%d %H:%M:%S", usetz = FALSE) a$local.time <- strftime(a$local.time, format = "%H:%m") ,

the class changes to character ! What's the right approach?

3442
  • 8,248
  • 2
  • 19
  • 41
vagabond
  • 3,526
  • 5
  • 43
  • 76
  • What class are you expecting the result to be? – Rich Scriven Oct 31 '14 at 18:08
  • that's exactly the question ! I want time hierarchy without date. Within a 24 hour period, 00:00 should be first minute and 23:59 the last. IF i was to do range(a$local.time) i should get the minimum and max as the first and last minute of the day. Ultimately if my user wanted to zoom in on a specific ten minutes of the a date, they should be able to ! – vagabond Oct 31 '14 at 18:13

2 Answers2

5

The chron package has a "times" class that might be helpful for you. Starting with something similar to what you have so far:

x <- c("1:30 AM", "6:29 AM", "6:59 AM", "9:54 AM", "10:14 AM", "3:15 PM"))
a <- as.POSIXct(x, tz = "", format = "%I:%M %p", usetz = FALSE)

Then we can use the times function with format

library(chron)
(tms <- times(format(a, "%H:%M:%S")))
# [1] 01:30:00 06:29:00 06:59:00 09:54:00 10:14:00 15:15:00
attributes(tms)
# $format
# [1] "h:m:s"
#
# $class
# [1] "times"
Rich Scriven
  • 97,041
  • 11
  • 181
  • 245
1

You can use the hms (hour-minute-second) series of functions in the lubridate package.

library(lubridate)

times = c("1:30 AM",  "6:29 AM",  "6:59 AM",  "9:54 AM", "2:45 PM")

I was hoping you could just do:

hm(times)
[1] "1H 30M 0S" "6H 29M 0S" "6H 59M 0S" "9H 54M 0S" "2H 45M 0S"

But notice that hm doesn't recognize the AM/PM distinction. So here's a more convoluted method that requires first using strptime, which does recognize AM/PM, and then putting the result in a form hm recognizes.

hm(paste0(hour(strptime(times, "%I:%M %p")),":",
          minute(strptime(times, "%I:%M %p"))))
[1] "1H 30M 0S"  "6H 29M 0S"  "6H 59M 0S"  "9H 54M 0S"  "14H 45M 0S"

There's probably a better way, but this seems to work.

UPDATE: To address your comment, you can use the hour and minute functions to get the hours and minutes (although I like @RichardScriven's answer better). For example:

hour(times)
[1]  1  6  6  9 14

mean(hour(times) + minute(times)/60)
[1] 7.923333
eipi10
  • 91,525
  • 24
  • 209
  • 285
  • this is clever ! unfortunately the moment i take the data out of R or even outside of `lubridate` , the TIME aspect of things is lost ! try range(times) in the end. eccentricly enough, summary(times) gives the min, max mean, median correctly. But max(times), min(times), range(times) all return "0,0" – vagabond Oct 31 '14 at 18:26