我有一个序列向量的自行车#每分钟在一个给定的公共站。假设这些值如下:
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在第一栏中,0分钟有7辆自行车,1分钟有7辆自行车,2分钟有8辆自行车,等等。
我想计算两件事:直到一辆自行车被取出为止的分钟数,和直到一辆新自行车被放置在车站前的分钟数。
对于第一种情况,新列是mins_until_arrival,其中的每一行都显示了自行车在未来添加之前的分钟数。但是请注意,从病房的第7行开始,自行车的数量会减少,所以我需要计算出从病房到第12排自行车增加之前的分钟数,所以第12行是至少增加一辆自行车的时候。因为我们不知道什么时候会增加一辆新自行车,最后一行是NA。
第二个我需要的是相反的,所以距离自行车被从车站带走的分钟数。这是列mins_until_taken。在这里,你会看到,从第一分钟,它需要7分钟,直到自行车被从车站。当然,如果系列结束,一辆新的自行车还没有被拿出来,我不知道什么时候一辆新的自行车会被拿走,所以像NA这样的东西是好的。
我第一次尝试使用rle计算分钟,直到有任何变化(无论是采取或放置它们),并试图识别哪些是增加或减少,但它变得太复杂。我提供了我的rle尝试,以防有帮助。
考虑两件事:我将情况简化为一个站点,但我必须将其应用于近30 GB的数据集上的N个站点,因此最好采用向量化的解决方案,尽管如果提供,我可以将任何循环转换为向量化。
有人能指出正确的方向吗?
发布于 2018-05-06 13:16:21
使用data.table-package可能的解决方案:
# 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 15 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 2 2 9: 8 0 3 1 10: 7 -12 NA 2 11: 7 0 1 NA 1 12: 9 NA NA
使用的数据:
num_biks <- data.frame(num_bikes = c(7, 7, 8, 8, 9, 9, 10, 8, 8, 7, 7, 9))https://stackoverflow.com/questions/50199540
复制相似问题