Katherine
Katherine

Reputation: 107

Divide two difftime objects

I have three time (POSIXct) objects t1, t2, t3 which specify the time duration to complete a task.

I found t1, t2, t3 by doing the following:

t1 <- as.POSIXct("2016-10-30 13:53:34") - as.POSIXct("2016-10-30 13:35:34")
t2 <- as.POSIXct("2016-10-30 14:53:34") - as.POSIXct("2016-10-30 14:35:34")
t3 <- as.POSIXct("2016-10-30 15:50:34") - as.POSIXct("2016-10-30 15:40:34")

I want to find the ratios t1/t3 and t2/t3. However, I get the following error:

t1/t3
# Error in `/.difftime`(t1, t3) : 
#   second argument of / cannot be a "difftime" object

I understood that two difftime objects cannot be divided. Is there any way that I could find the result of dividing two difftime objects?

Upvotes: 9

Views: 4425

Answers (3)

Matthew Lundberg
Matthew Lundberg

Reputation: 42659

To divide by a difftime you must convert it to numeric. If, as you stated in a comment, you would like the answer to be expressed in seconds, you can specify the 'secs' units. For example:

t1/as.double(t3, units='secs')

As @JonathanLisic notes, as.double does not generally take a units parameter, and this won't work for generic time classes. It is the S3 method for difftime which takes the parameter.

Upvotes: 10

obewanjacobi
obewanjacobi

Reputation: 468

As of today's date (9/2018), you can use as.numeric() to turn your difftime values into numeric values. ie, if you were to take

as.numeric(t3)

R will return 10 as desired.

Upvotes: 4

MichaelChirico
MichaelChirico

Reputation: 34703

@MatthewLundberg's answer is more correct, but I'll suggest an alternative just to help illustrate the underlying structures of time-based objects in R are always just numbers:

unclass(t1)/unclass(t3)
# [1] 1.8
# attr(,"units")
# [1] "mins"

Note that, in terms of units, the approach of t1/as.double(t3, units = 'secs') doesn't make much sense, since the units of the output are min/sec, whereas this answer is unit-free.

Note further that this approach is a bit dangerous, since by default, -.POSIXt (which is ultimately called when you define t1, t2, and t3) automatically chooses the units of the output (at core, -.POSIXt here will call difftime with the default units = "auto"). In this case, we are (maybe) lucky that all 3 are given units, but consider t4:

t4 = as.POSIXct('2017-10-21 12:00:35') - as.POSIXct('2017-10-21 12:00:00')
t4
# Time difference of 35 secs

Again, if we use t4 in a ratio, we'll probably get the wrong units.

We can avoid this by explicitly calling difftime and declaring the units upfront:

t1 = difftime("2016-10-30 13:53:34", "2016-10-30 13:35:34", units = 'mins')
t2 = difftime("2016-10-30 14:53:34", "2016-10-30 14:35:34", units = 'mins')
t3 = difftime("2016-10-30 15:50:34", "2016-10-30 15:40:34", units = 'mins')
t4 = difftime('2017-10-21 12:00:35', '2017-10-21 12:00:00', units = 'mins')
t4
# Time difference of 0.5833333 mins

Upvotes: 3

Related Questions