Установите единицы разницы между объектами datetime

Команда diff возвращает различия между датами в векторе дат в формате даты R. Я хотел бы управлять возвращаемыми единицами, но кажется, что они автоматически определяются, без возможности управлять им с аргументом. Вот пример:

 > t = Sys.time() 
 > diff(c(t, t + 1))
 Time difference of 1 secs

И все же:

> diff(c(t, t+10000))
Time difference of 1.157407 days

Объект "временной дельты" имеет атрибут единиц, но кажется глупым писать кучу условных выражений, чтобы принуждать все к дням, секундам и т.д.

Ответ 1

Я не уверен, что вы подразумеваете под "связкой условных выражений", просто меняйте единицы вручную.

> 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

См. ?difftime. Если вам нужно использовать diff, чтобы получить разницу между двумя значениями (а не более длинным вектором), тогда, как предлагает Дирк, используйте функцию difftime с параметром units.

Ответ 2

Тип

A POSIXct (который вы создали при вызове Sys.time()) всегда использует дробные секунды с эпохи.

Функции difftime() просто форматируют это по-другому для удовольствия от чтения. Если вы действительно указываете формат, вы получаете то, что вы указали:

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> 

Ответ 3

Я думаю, вам нужно difftime, в котором вы можете указать нужные единицы. См:

> 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

Ответ 4

Не уверен, насколько точно вы хотите быть, но вы можете очень точно узнать о датах с пакетом lubridate. Увлекательная вещь о единицах времени заключается в том, что их длина зависит от того, когда они происходят из-за прыжков секунд, прыжков и других конвенций.

После загрузки lubridate вычитание даты автоматически создает объект временного интервала.

library(lubridate)
int <- Sys.time() - (Sys.time() + 10000) 

Затем вы можете изменить его на длительность, которая измеряет точное время. Длительность отображается в секундах, потому что секунды являются единственной единицей, которая имеет согласованную длину. Если вы хотите получить свой ответ в определенном блоке, просто разделите его на объект продолжительности, который имеет длину одного из этих единиц.

as.duration(int)
int / dseconds(1)
int / ddays(1)
int / dminutes(5) #to use "5 minutes" as a unit

Или вы можете просто изменить int на период. В отличие от продолжительности, периоды не имеют точной и согласованной длины. Но они точно отображают часы. Вы можете делать математику, добавляя и вычитая оба периода и длительности до дат.

as.period(int)
Sys.time() + dseconds(5) + dhours(2) - ddays(1)
Sys.time() + hours(2) + months(5) - weeks(1) #these are periods

Ответ 5

Если вам нужно использовать функцию diff() (например, как я делаю внутри функции ddply), вы также можете повернуть входные данные в числовой формат, чтобы всегда получать разницу в секундах, например:

> t = Sys.time() 
> diff(as.numeric(c(t, t+1)))
[1] 1
> diff(as.numeric(c(t, t+10000)))
[1] 10000

С этой точки вы можете использовать интервалы diff для вычисления различий в других единицах.