R: время округления до ближайшего часа - PullRequest
0 голосов
/ 27 июня 2018

У меня есть вектор со временем (из файла Excel). Это читается как фактор. Это короткая версия / пример этого:

starttime <- factor(c("12:55:00", "13:45:00", "14:30:00", "10:00:00", "10:40:00", "12:00:00", "12:30:00"))

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

round_date(hms(starttime), unit= "hour")

hms, кажется, работает нормально сам по себе (я действительно получаю свои данные как класс Period), но затем использование их в сочетании с round_date дает мне ошибку

Error in as.POSIXct.numeric(x) : 'origin' must be supplied

Затем я попробовал следующее (1904, потому что это данные из файла Excel / csv на Mac)

round_date(hms(starttime, origin="1904-01-01"), unit="hour")

но это дало мне точно такую ​​же ошибку, поэтому я понял, что указал источник в неверной функции. Следующая попытка была

round_date(hms(starttime), unit="hour"), origin="1904-01-01")

который дал мне ошибку

Error in round_date(hms(starttime), unit = "hour", origin = "1904-01-01") : unused argument (origin = "1904-01-01")

Я также попробовал базу R:

round.Date(as.POSIXct(as.character(starttime), format="%H:%M:%S"), units="hours")

дал мне

Error in NextMethod() : generic function not specified

Также здесь работает преобразование вектора в даты, но проблема начинается с добавления функции округления.

Теперь я полностью понимаю, почему это не может работать с использованием lubridate, так как с временем нет никаких дат (поэтому таймер под капотом не может делать свое дело). Я немного сбит с толку насчет сообщения об ошибке, что источник нужен, но затем он игнорируется Я не могу использовать ymd_hms(), потому что нет данных в векторе для дат. И я не могу понять, что означает ошибка для базовой функции R - где на самом деле добавляются даты (текущая дата).

Я решил эту проблему вручную:

ifelse(minute(hms(starttime))>=30, hour(hms(starttime))+1, hour(hms(starttime)))

Есть ли способ сделать это с помощью функции lubridate или базы R? Если нет, то есть идеи, почему нет? Мне кажется, что-то, что должно быть возможно.

1 Ответ

0 голосов
/ 27 июня 2018

Попробуйте небольшую модификацию того, что у вас есть:

round(as.POSIXct(starttime, format="%H:%M:%S", tz="UTC"), units="hours")
#[1] "2018-06-27 13:00:00 UTC" "2018-06-27 14:00:00 UTC"
#[3] "2018-06-27 15:00:00 UTC" "2018-06-27 10:00:00 UTC"
#[5] "2018-06-27 11:00:00 UTC" "2018-06-27 12:00:00 UTC"
#[7] "2018-06-27 13:00:00 UTC"

R автоматически отправит на правильный round.POSIXt при вызове round с объектом as.POSIXct/as.POSIXlt. В исходном коде вы заставляете round пытаться работать с Date объектом, которого у вас нет - у вас есть POSIXct объект datetime.

A Date в R, как правило, представляет собой просто "год / месяц / день", без временной составляющей, в отличие от POSIXct, который представляет собой "год / месяц / день чч / мм / сс / доли секунды". Они не являются взаимозаменяемыми или сопоставимыми. E.g.:

> Sys.time() == Sys.Date()
#[1] FALSE
#Warning message:
#Incompatible methods ("Ops.POSIXt", "Ops.Date") for "==" 

(Если вы хотите получить техническую информацию, Date сохраняется как количество дней с 1970-01-01, включая дробные дни, а POSIXct - это количество секунд с 1970-01-01: 00:00:00 - включая доли секунды. POSIXlt снова отличается и представляет собой серию list объектов с частями для дня, месяца, года, минут и т. Д.).

...