2017-09-21 83 views
1

我有一個大量的車禍數據,它的一個樣本提供如下。cumsum根據某些限制在r

  • 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或vectorised解決方案。

+0

我不清楚'cum_time'是如何計算的。 –

+0

@Ronak Shah cum_time每次事故都是在該班次開始時的「time_diff」cumsum,事故實際發生的地點 –

回答

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並且計算從最近的0到xtime_diff的值的總和,並將其分配給其各自的指數。

0

使用ave功能通過shift_number計算的time_diff累計總和:

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功能。

+0

好的想法,但我認爲你在這裏錯過了一些東西。嘗試做'df $ shift_number [14] < - 0'並重新計算'cum_time'。 –

+0

@RonakShah此代碼的工作原理是每次休息後移位數增加,即如果'df $ shift_number [14]'爲'0',則下一個非零移位數應該爲'4'。 –