根据r中的某些限制,cumsum

时间:2017-09-21 06:17:16

标签: r cumsum

我有大量的车祸数据,下面提供了一些样本。

  • accident是事故是否发生的二进制变量 不。
  • shift_number是班次的数字,0表示司机是 休息而不是轮班。
  • time_diff是每次观察的时间量。

    df <- data.frame(
    accident     = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1),
    shift_number = c(1, 1, 0, 0, 0, 2, 2, 2, 0, 0, 3, 3, 3, 3, 3),
    time_diff    =   3:17
    )
    

我的问题是测量自驾驶员为每次事故开始此班次以来的总工作时间。

wanted <- data.frame
(
  accident     = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1),
  shift_number = c(1, 1, 0, 0, 0, 2, 2, 2, 0, 0, 3, 3, 3, 3, 3),
  time_diff    = 3:17,
  cum_time     = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 75)
)

有没有人有关于用R解决这个问题的想法?拥有data.table或矢量化解决方案会更好,因为我有大量的数据需要处理。

2 个答案:

答案 0 :(得分:3)

df$cum_time = 0
accident = which(df$accident == 1)

df$cum_time[accident] <- sapply(accident, function(x) {
    sum(df$time_diff[(which.max(cumsum(df$shift_number[1:x] == 0)) + 1): x])
})

df

#   accident shift_number time_diff cum_time
#1         0            1         3        0
#2         0            1         4        0
#3         0            0         5        0
#4         0            0         6        0
#5         0            0         7        0
#6         0            2         8        0
#7         0            2         9        0
#8         0            2        10        0
#9         0            0        11        0
#10        0            0        12        0
#11        0            3        13        0
#12        1            3        14       27
#13        0            3        15        0
#14        0            3        16        0
#15        1            3        17       75

我们首先将cum_time变量中的所有值设为0.我们找到accident已发生的索引。对于每个索引,我们在shift_number中找到最新的0,并计算time_diff从最新的0到x的值的总和,并将其分配给各自的索引。

答案 1 :(得分:0)

使用ave函数按time_diff计算shift_number的累计总和:

cumsum_by_shift <- ave(df$time_diff, df$shift_number, FUN=cumsum)
#[1]  3  7  5 11 18  8 17 27 29 41 13 27 42 58 75

挑选发生意外的cumsum_by_shift元素:

cum_time <- ifelse(df$accident == 1, cumsum_by_shift, 0)
#[1]  0  0  0  0  0  0  0  0  0  0  0 27  0  0 75

请注意使用矢量化ifelse函数。