我有大量的车祸数据,下面提供了一些样本。
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或矢量化解决方案会更好,因为我有大量的数据需要处理。
答案 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
函数。