Как преобразовать набор данных в R? - PullRequest
0 голосов
/ 12 января 2020

Для своей работы я пытаюсь написать код для расчета необходимого количества парковочных мест. У меня есть данные о количестве автомобилей, прибывающих каждый час, и о продолжительности парковки (генерируемой через rnorm) каждого автомобиля на парковке. Теперь я хотел бы посчитать в минуту, сколько парковочных мест требуется.

dataset

(переменные Hour & Attraction_intensity)

timeonparking <- round(rnorm(14, mean = 35, sd = 10))

Сначала я бы хотел генерировать числа X (равномерное распределение; представляющие минуты прибытия в течение данного часа) для каждой строки / часа в диапазоне от 0 до 59, где X равно значению Attra_intensity в этот час.

Новый фрейм данных должен выглядеть следующим образом:

new dataframe

Может кто-нибудь помочь мне, пожалуйста? Моей первой идеей было использовать для l oop. Но это не привело бы к таблице, показанной выше, и код содержит ошибки, которые я не могу найти (я новичок в R). Я не знаю, как преобразовать набор данных.

Первая попытка:

for (i in nrow(df) {
    df1 <- paste(df$ï..hour[i], list(runif(df$attraction_vehicles[i], min = 0, max = 59)))
}

1 Ответ

5 голосов
/ 12 января 2020

Есть несколько способов подойти к этому, но давайте начнем с известной точки:

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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...