Количество минут, пока велосипед не будет взят / размещен на общественной станции - PullRequest
0 голосов
/ 06 мая 2018

У меня есть вектор последовательности # байков за каждую минуту на данной общественной станции.Предположим, что эти значения следующие:

    num_biks <- data.frame(num_bikes = c(7, 7, 8, 8, 9, 9, 10, 8, 8, 7, 7, 9),
mins_until_arrival = c(2, 
      1, 2, 1, 2, 1, 5, 4, 3, 2, 1, NA), mins_until_taken = c(7, 6, 5, 4, 3, 2, 
      1, 1, 1, NA, NA, NA))


num_biks <- cbind(num_biks, any_change = unlist(lapply(rle(num_biks$num_bikes)$lengths, 
  seq, by = -1)))
num_biks
#>    num_bikes mins_until_arrival mins_until_taken any_change
#> 1          7                  2                7          2
#> 2          7                  1                6          1
#> 3          8                  2                5          2
#> 4          8                  1                4          1
#> 5          9                  2                3          2
#> 6          9                  1                2          1
#> 7         10                  5                1          1
#> 8          8                  4                1          2
#> 9          8                  3                1          1
#> 10         7                  2               NA          2
#> 11         7                  1               NA          1
#> 12         9                 NA               NA          1

Итак, в первом столбце есть 7 велосипедов в минуту 0, 7 велосипедов в минуту 1, 8 велосипедов в минуту 2 и т. Д.

IВы хотите рассчитать две вещи: количество минут, которое проходит, пока велосипед не будет снят , и количество минут, которое проходит, пока новый велосипед не будет помещен на станцию.

Для первогов этом случае новый столбец будет mins_until_arrival, где в каждой строке указано количество минут, пока велосипед не будет добавлен в будущем.Но обратите внимание, что с 7-го ряда на палатах количество велосипедов уменьшается, поэтому мне нужно рассчитать количество минут, пока не будет увеличено количество на палатах, поэтому 12-й ряд - это когда увеличился хотя бы один велосипед.Поскольку мы не знаем, когда будет добавлен новый велосипед, последний ряд - NA.

Второй мне нужен обратный, так что количество минут, пока велосипед не будет взят со станции.Это столбец mins_until_taken.Здесь вы увидите, что с первой минуты до станции берут велосипед за 7 минут.Естественно, если серия заканчивается, и новый велосипед не был снят, я не знаю, когда новый велосипед будет взят, так что что-то вроде NA хорошо.

Сначала я попытался использовать rle, чтобывычислите минуты до тех пор, пока не произойдут какие-либо изменения (взятые или внесенные), и попытайтесь определить, какие из них увеличиваются или уменьшаются, но они становятся слишком запутанными.Я предоставляю свою попытку rle на случай, если это поможет.

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

Может ли кто-нибудь указывать в правильном направлении?

1 Ответ

0 голосов
/ 06 мая 2018

Возможное решение с пакетом data.table:

# load package and convert to a 'data.table'
library(data.table)
setDT(num_biks)

# create 'minutes' and 'change in number of bikes' columns
num_biks[, diff_num_bikes := c(0,diff(num_bikes))]

# calulate the minutes to an increase of the number of bikes
num_biks[, mins_to_increase := .N:1, by = cumsum(diff_num_bikes > 0)]

# calulate the minutes to a decrease of the number of bikes
num_biks[, mins_to_decrease := .N:1, by = cumsum(diff_num_bikes < 0)]

# calulate the minutes to any change in the number of bikes
num_biks[, any_change := .N:1, by = cumsum(diff_num_bikes != 0)][]
# set the last row of the increase column to 'NA'
num_biks[nrow(num_biks), mins_to_increase := NA]

# set the observations after the last decrease to 'NA'
num_biks[num_biks[, last(.I[diff_num_bikes < 0])]:nrow(num_biks), mins_to_decrease := NA]

Все вместе:

num_biks[, diff_num_bikes := c(0,diff(num_bikes))
         ][, mins_to_increase := .N:1, by = cumsum(diff_num_bikes > 0)
           ][, mins_to_decrease := .N:1, by = cumsum(diff_num_bikes < 0)
             ][, any_change := .N:1, by = cumsum(diff_num_bikes != 0)
               ][nrow(num_biks), `:=` (mins_to_increase = NA, any_change = NA)
                 ][num_biks[, last(.I[diff_num_bikes < 0])]:nrow(num_biks), mins_to_decrease := NA][]

это дает:

> num_biks
    num_bikes diff_num_bikes mins_to_increase mins_to_decrease any_change
 1:         7              0                2                7          2
 2:         7              0                1                6          1
 3:         8              1                2                5          2
 4:         8              0                1                4          1
 5:         9              1                2                3          2
 6:         9              0                1                2          1
 7:        10              1                5                1          1
 8:         8             -2                4                2          2
 9:         8              0                3                1          1
10:         7             -1                2               NA          2
11:         7              0                1               NA          1
12:         9              2               NA               NA         NA

Использованные данные:

num_biks <- data.frame(num_bikes = c(7, 7, 8, 8, 9, 9, 10, 8, 8, 7, 7, 9))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...