0

How do I format time independent of a date in R? I have a time vector that I would like to add and subtract; however, when I format the vector as POSIXct(), POSIXlt(), or strptime() R attaches a date to it:

> sample
     V1
1  1:23
2  5:20
3  2:28
4  1:38
5  6:27
6  2:19
7  0:22
8  6:25
9  5:07
10 2:28
11 2:33
12 0:03
13 3:58
>       str(sample)
'data.frame':   13 obs. of  1 variable:
 $ V1: Factor w/ 12 levels "0:03","0:22",..: 3 10 6 4 12 5 2 11 9 6 ...
>       sample.1 = strptime(sample$V1, format = "%M:%S")
>       sample.1
 [1] "2017-03-18 00:01:23 PDT" "2017-03-18 00:05:20 PDT" "2017-03-18 00:02:28 PDT"
 [4] "2017-03-18 00:01:38 PDT" "2017-03-18 00:06:27 PDT" "2017-03-18 00:02:19 PDT"
 [7] "2017-03-18 00:00:22 PDT" "2017-03-18 00:06:25 PDT" "2017-03-18 00:05:07 PDT"
[10] "2017-03-18 00:02:28 PDT" "2017-03-18 00:02:33 PDT" "2017-03-18 00:00:03 PDT"
[13] "2017-03-18 00:03:58 PDT"
>       str(sample.1)
 POSIXlt[1:13], format: "2017-03-18 00:01:23" "2017-03-18 00:05:20" "2017-03-18 00:02:28" ...
>       sample.2  = as.POSIXct(sample$V1, format = "%M:%S")
>       sample.2
 [1] "2017-03-18 00:01:23 PDT" "2017-03-18 00:05:20 PDT" "2017-03-18 00:02:28 PDT"
 [4] "2017-03-18 00:01:38 PDT" "2017-03-18 00:06:27 PDT" "2017-03-18 00:02:19 PDT"
 [7] "2017-03-18 00:00:22 PDT" "2017-03-18 00:06:25 PDT" "2017-03-18 00:05:07 PDT"
[10] "2017-03-18 00:02:28 PDT" "2017-03-18 00:02:33 PDT" "2017-03-18 00:00:03 PDT"
[13] "2017-03-18 00:03:58 PDT"
>       str(sample.2)
 POSIXct[1:13], format: "2017-03-18 00:01:23" "2017-03-18 00:05:20" "2017-03-18 00:02:28" ...
>       sample.3  = as.POSIXlt(sample$V1, format = "%M:%S")
>       sample.3
 [1] "2017-03-18 00:01:23 PDT" "2017-03-18 00:05:20 PDT" "2017-03-18 00:02:28 PDT"
 [4] "2017-03-18 00:01:38 PDT" "2017-03-18 00:06:27 PDT" "2017-03-18 00:02:19 PDT"
 [7] "2017-03-18 00:00:22 PDT" "2017-03-18 00:06:25 PDT" "2017-03-18 00:05:07 PDT"
[10] "2017-03-18 00:02:28 PDT" "2017-03-18 00:02:33 PDT" "2017-03-18 00:00:03 PDT"
[13] "2017-03-18 00:03:58 PDT"
>       str(sample.3)
 POSIXlt[1:13], format: "2017-03-18 00:01:23" "2017-03-18 00:05:20" "2017-03-18 00:02:28" ...

I asked this before, and it got marked as a duplicate. However, the question it was marked as a duplicate of was not answered. I tried to explain that in an edit, but that edit was ignored. Indeed, I've found this question asked a plethora of times on SO and other sites; but, I've never seen it satisfactorily answered. The closest thing I've found is:

> library(chron)
>       sample.4 = ms(sample$V1)
>       sample.4
 [1] "1M 23S" "5M 20S" "2M 28S" "1M 38S" "6M 27S" "2M 19S" "22S"    "6M 25S" "5M 7S"  "2M 28S"
[11] "2M 33S" "3S"     "3M 58S"
>       str(sample.4)
Formal class 'Period' [package "lubridate"] with 6 slots
  ..@ .Data : num [1:13] 23 20 28 38 27 19 22 25 7 28 ...
  ..@ year  : num [1:13] 0 0 0 0 0 0 0 0 0 0 ...
  ..@ month : num [1:13] 0 0 0 0 0 0 0 0 0 0 ...
  ..@ day   : num [1:13] 0 0 0 0 0 0 0 0 0 0 ...
  ..@ hour  : num [1:13] 0 0 0 0 0 0 0 0 0 0 ...
  ..@ minute: num [1:13] 1 5 2 1 6 2 0 6 5 2 ...

chron::ms() allows me to format sample$V1 as a "period", without inserting an unwanted date; however, I run into problems when I try to add or subtract:

> a = sample.4[1] + sample.4[2] + sample.4[13]
>       b = sample.4[2] - sample.4[3]
>       a
[1] "9M 101S"
>       b
[1] "3M -8S"

Clearly "a" SHOULD equal "10:41" and not "9M 101S" and "b" should equal "2:52" instead of "3M -8S". The opperation is accurate, but its display defeats the purpose. Is there a way to simply get these results to display in a way that makes sense? Or, is there some other function that can format time without a date? Thanks for your help.

neilfws
  • 32,751
  • 5
  • 50
  • 63
DataProphets
  • 156
  • 3
  • 17
  • 1
    Feels like there is some confusion here between "time" as in hours and minutes on a clock, versus "time", measurements of duration in hours and minutes. I can see that 2 hours duration could be added to midday to equal 2 pm, but that's not the same as adding "12 pm + 2 pm + 5 pm", which does not quite make sense. So to start: by "time vector", you mean times on a 24 hr clock? – neilfws Mar 20 '17 at 02:08
  • 2
    If you intend to group/bin data based on time-of-day (or time-in-session or something else), here's a suggestion: deal with it as seconds-of-day, meaning a `numeric` ranging from 0 to 86400. If you need to pretty-print it, you can temporarily accept the date being added internally, and force the print format to something like `"%H:%M"`. Otherwise, I've also found no way to deal with time-of-day irrespective of date. – r2evans Mar 20 '17 at 03:04
  • There is `as.difftime` for representing a unit of time that can be added to dates / datetimes etc - e.g. `as.difftime("1:23", format="%M:%S")`. If your times run >60 minutes, you can also split and recombine to a `difftime` object like this: http://stackoverflow.com/questions/41250253/subtracting-times-that-exceed-60-minutes/41252058 – thelatemail Mar 20 '17 at 03:06
  • neilfws, I hadn't considered the difference between time on a clock versus time as a measurement. I suppose I had hoped for some sort of a hybrid-format where I could subtract 2PM from 3PM and get 1 hour (3:00 - 2:00 = 1 hour). It sounds like there's probably another way to deal with this variable better, like how r2evans suggests. – DataProphets Mar 21 '17 at 16:44

0 Answers0