Есть несколько способов подойти к этому, но давайте начнем с известной точки:
dat <- data.frame(
hour = c("5:00:00", "6:00:00", "7:00:00"),
attraction = c(1, 3, 6)
)
dat$hour <- as.POSIXct(dat$hour, format = "%H:%M:%S")
dat
# hour attraction
# 1 2020-01-12 05:00:00 1
# 2 2020-01-12 06:00:00 3
# 3 2020-01-12 07:00:00 6
Так как вы хотите выполнять расчеты по времени, я установил hour
как POSIXt
тип. (Если у вас также есть компонент «дата» в ваших данных, вы захотите включить его в преобразование, но если это всегда в один и тот же день, то это не имеет большого значения.)
Отсюда мы можем вводить случайные минуты для каждого прибытия:
set.seed(42)
dat2 <- do.call(
"rbind.data.frame",
Map(function(hr, n) data.frame(hour = hr, min = round(runif(n, min = 0, max = 59))),
dat$hour, dat$attraction)
)
dat2
# hour min
# 1 2020-01-12 05:00:00 54
# 2 2020-01-12 06:00:00 55
# 3 2020-01-12 06:00:00 17
# 4 2020-01-12 06:00:00 49
# 5 2020-01-12 07:00:00 38
# 6 2020-01-12 07:00:00 31
# 7 2020-01-12 07:00:00 43
# 8 2020-01-12 07:00:00 8
# 9 2020-01-12 07:00:00 39
# 10 2020-01-12 07:00:00 42
Я не знаю, нужна ли вам минута отдельно или в реальном времени, поэтому, возможно,
dat2$arrival_time <- dat2$hour + (60 * dat2$min)
dat2
# hour min arrival_time
# 1 2020-01-12 05:00:00 54 2020-01-12 05:54:00
# 2 2020-01-12 06:00:00 55 2020-01-12 06:55:00
# 3 2020-01-12 06:00:00 17 2020-01-12 06:17:00
# 4 2020-01-12 06:00:00 49 2020-01-12 06:49:00
# 5 2020-01-12 07:00:00 38 2020-01-12 07:38:00
# 6 2020-01-12 07:00:00 31 2020-01-12 07:31:00
# 7 2020-01-12 07:00:00 43 2020-01-12 07:43:00
# 8 2020-01-12 07:00:00 8 2020-01-12 07:08:00
# 9 2020-01-12 07:00:00 39 2020-01-12 07:39:00
# 10 2020-01-12 07:00:00 42 2020-01-12 07:42:00
Я должен отметить, что использование rnorm
"может" привести к отрицательным минутам, поскольку оно асимптотически бесконечно; использование sd=10
, конечно, снижает вероятность, но если вам нужно, чтобы случайное время прибытия «всегда» находилось в пределах указанного часа, то либо использование runif
лучше, либо вы можете рассмотреть усеченно-нормальное распределение, например пакетом truncnorm
.
Примечание: я использую Map
, который является многопараметрической версией lapply
. Часто есть преимущества (иногда в производительности, иногда в удобочитаемости) использования функций из семейства R apply
, и хотя преимущества в производительности были в основном смягчены (исторически for
часто медленнее, чем sapply
), некоторые все еще находят *apply
лучше. В случае Map
я написал несколько ответов, объясняющих («разворачивая» его), как это работает: { ссылка } и { ссылка }.
Чтобы получить показатели заполняемости (сколько автомобилей за определенный период), я предлагаю вам использовать cut
, чтобы указать время прибытия. Мы можем создать границы бина с помощью чего-то вроде:
myseq <- round(range(dat2$arrival_time) + c(-1800,1800), "hour")
myseq
# [1] "2020-01-12 05:00:00 PST" "2020-01-12 08:00:00 PST"
myseq <- seq.POSIXt(myseq[1], myseq[2], by = "min")
length(myseq)
# [1] 181
myseq <- myseq[seq_along(myseq) %% 10 == 1]
myseq
# [1] "2020-01-12 05:00:00 PST" "2020-01-12 05:10:00 PST" "2020-01-12 05:20:00 PST"
# [4] "2020-01-12 05:30:00 PST" "2020-01-12 05:40:00 PST" "2020-01-12 05:50:00 PST"
# [7] "2020-01-12 06:00:00 PST" "2020-01-12 06:10:00 PST" "2020-01-12 06:20:00 PST"
# [10] "2020-01-12 06:30:00 PST" "2020-01-12 06:40:00 PST" "2020-01-12 06:50:00 PST"
# [13] "2020-01-12 07:00:00 PST" "2020-01-12 07:10:00 PST" "2020-01-12 07:20:00 PST"
# [16] "2020-01-12 07:30:00 PST" "2020-01-12 07:40:00 PST" "2020-01-12 07:50:00 PST"
# [19] "2020-01-12 08:00:00 PST"
Первая команда находит интервал времени и округляет его из до следующего часа. (Использование +c(-1800,1800)
гарантирует, что раунд даст нам пол и потолок соответственно. Это может найти угловые случаи, которые несовершенны, но это должно работать большую часть времени.) вторая команда создает поминутная последовательность, здесь 181 (три часа). Третья команда сокращает это значение до одного каждые 10 минут.
Вы сможете легко настроить эти три команды в соответствии со своими потребностями.
Здесь вы можете использовать
cut(dat2$arrival_time, myseq)
# [1] 2020-01-12 05:50:00 2020-01-12 06:50:00 2020-01-12 06:10:00 2020-01-12 06:40:00
# [5] 2020-01-12 07:30:00 2020-01-12 07:30:00 2020-01-12 07:40:00 2020-01-12 07:00:00
# [9] 2020-01-12 07:30:00 2020-01-12 07:40:00
# 18 Levels: 2020-01-12 05:00:00 2020-01-12 05:10:00 2020-01-12 05:20:00 ... 2020-01-12 07:50:00
, который дает вам 10-минутный интервал прибытие принадлежит. Краткое резюме можно сделать с помощью
table(cut(dat2$arrival_time, myseq))
# 2020-01-12 05:00:00 2020-01-12 05:10:00 2020-01-12 05:20:00 2020-01-12 05:30:00
# 0 0 0 0
# 2020-01-12 05:40:00 2020-01-12 05:50:00 2020-01-12 06:00:00 2020-01-12 06:10:00
# 0 1 0 1
# 2020-01-12 06:20:00 2020-01-12 06:30:00 2020-01-12 06:40:00 2020-01-12 06:50:00
# 0 0 1 1
# 2020-01-12 07:00:00 2020-01-12 07:10:00 2020-01-12 07:20:00 2020-01-12 07:30:00
# 1 0 0 3
# 2020-01-12 07:40:00 2020-01-12 07:50:00
# 2 0