代码之家  ›  专栏  ›  技术社区  ›  cimentadaj

将自行车停放在公共车站前的分钟数

r
  •  0
  • cimentadaj  · 技术社区  · 8 年前

    我有一个序列向量,在给定的公共车站,每分钟有#辆自行车。假设值如下:

        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排开始,自行车的数量就减少了,因此我需要计算分钟数,直到从第7排开始,自行车的数量增加为止,所以第12排是增加了至少一辆自行车。因为我们不知道什么时候会增加一辆新自行车,最后一排是NA。

    我需要的第二个参数是倒数,所以自行车 已拍摄 从车站。这就是专栏 mins_until_taken 从这里你可以看到,从第一分钟开始,骑自行车离开车站需要7分钟。当然,如果系列赛结束,一辆新自行车还没有推出,我不知道什么时候会推出一辆新自行车,所以像NA这样的车就可以了。

    我第一次尝试使用 rle 计算分钟数,直到有任何变化(无论是采取还是放置),并尝试确定增加或减少,但变得太复杂。我提供 rle公司 如果有帮助,尝试一下。

    考虑两件事:我将情况简化为一个站点,但我必须将其应用于近30 GB数据集上的N个站点,因此首选矢量化解决方案,尽管如果提供,我可以将任何循环转换为矢量化。

    有人能指出正确的方向吗?

    1 回复  |  直到 8 年前
        1
  •  3
  •   Jaap    8 年前

    一个可能的解决方案 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))