The diff
command returns the differences between dates in a vector of dates in the R date format. I'd like to control the units that are returned, but it seems like they are automatically determined, with no way to control it w/ an argument. Here's an example:
> t = Sys.time()
> diff(c(t, t + 1))
Tim开发者_StackOverflow社区e difference of 1 secs
And yet:
> diff(c(t, t+10000))
Time difference of 1.157407 days
The "time delta" object has a units attribute, but it seems silly to write a bunch of conditionals to coerce everything into days, seconds etc.
I'm not sure what you mean by "a bunch of conditionals," just change the units manually.
> t = Sys.time()
> a <- diff(c(t,t+1))
> b <- diff(c(t, t+10000))
> units(a) <- "mins"
> units(b) <- "mins"
> a
Time difference of 0.01666667 mins
> b
Time difference of 166.6667 mins
See ?difftime
. If you only need to use diff
to get the difference between two times (rather than a longer vector), then, as Dirk suggests, use the difftime
function with the units
parameter.
A POSIXct
type (which you created by calling Sys.time()
) always use fractional seconds since the epoch.
The difftime()
functions merely formats this differently for your reading pleasure. If you actually specify the format, you get what you specified:
R> difftime(t+ 10000,t,unit="secs")
Time difference of 10000 secs
R> difftime(t+ 10000,t,unit="days")
Time difference of 0.115741 days
R>
I think you need difftime
in which you can specify the desired units. See:
> difftime(Sys.time(), Sys.time()+10000)
Time difference of -2.777778 hours
> difftime(Sys.time(), Sys.time()+10000, units="secs")
Time difference of -10000 secs
Not sure how precise you care to be, but you can get very specific about date-times with the lubridate package. A wonky thing about time units is that their length depends on when they occur because of leap seconds, leap days, and other conventions.
After you load lubridate, subtracting date times automatically creates a time interval object.
library(lubridate)
int <- Sys.time() - (Sys.time() + 10000)
You can then change it to a duration, which measures the exact length of time. Durations display in seconds because seconds are the only unit that has a consistent length. If you want your answer in a specific unit, just divide by a duration object that has the length of one of those units.
as.duration(int)
int / dseconds(1)
int / ddays(1)
int / dminutes(5) #to use "5 minutes" as a unit
Or you could just change the int to a period. Unlike durations, periods don't have an exact and consistent length. But they faithfully map clock times. You can do math by adding and subtracting both periods and durations to date-times.
as.period(int)
Sys.time() + dseconds(5) + dhours(2) - ddays(1)
Sys.time() + hours(2) + months(5) - weeks(1) #these are periods
If yon need to use the diff() function (e.g. as I do in within a ddply function), you can also turn the input data into numeric format to always receive differences in seconds like this:
> t = Sys.time()
> diff(as.numeric(c(t, t+1)))
[1] 1
> diff(as.numeric(c(t, t+10000)))
[1] 10000
From that point on you can use the diff seconds to calculate differences in other units.
精彩评论