2017-01-04 53 views
2

修改的數據:累積總和忽略場所

structure(list(hour = c(0L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 
1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 1L, 1L, 1L, 0L, 1L, 1L, 0L, 0L), cs = c(0L, 0L, 0L, 0L, 
0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 
1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L 
), cs_acum = c(0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 1L, 2L, 0L, 0L), cs_wanted = c(0L, 0L, 0L, 0L, 
0L, 1L, 2L, 3L, 0L, 0L, 4L, 5L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 
3L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 0L, 0L 
), cs_acum2 = c(0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 0L, 4L, 5L, 
0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
1L, 2L, 3L, 0L, 4L, 5L, 0L, 0L)), .Names = c("hour", "cs", "cs_acum", 
"cs_wanted", "cs_acum2"), class = c("data.table", "data.frame" 
), row.names = c(NA, -36L), .internal.selfref = <pointer: 0x00000000001f0788>) 

cs_acumcs與重啓累計總和爲0。

df1$cs_acum <- with(df1, ave(df1$cs, cumsum(df1$cs == 0), FUN = cumsum)) 

我需要這個累積繼續,如果在5行的1值的hour積分後1從cs已停止
所需輸出在col cs_wanted

進一步說明:çs_acum是符合某些標準的小時數(行f cs)的累積量。在此之後,它與cs無關,因此與col:hour有關。如果在停止後的5小時窗口中有1個值,則積累應繼續。

cs_acum中的位置檢查hour中的五行的一個新函數可能會變爲0,以便從cs_acum中停止的位置繼續累積。
可能採取的步驟:
找到位置,積累停止
看看未來五年排在小時
如果有值1,繼續爲該行積累,
在5個小時再看看,
如果有沒有值1,什麼都不做。


新的數據:

df3 <- structure(list(hour = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), 
         cs = c(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), 
         cs_acum = c(0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), 
         cs_acum2 = c(0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28)), 
       .Names = c("hour", "cs", "cs_acum", "cs_acum2"), class = "data.frame", row.names = c(NA, -68L)) 
+0

我真的不知道該如何解釋好。請參閱cs_wanted中的示例積累,它應該很清楚。如果沒有,我會再給它一次。 –

+0

不,我需要符合特定標準的小時數。 –

回答

1

我們可以通過 data.table方法

library(data.table) 
setDT(df1)[, grp := shift(cumsum(hour == 1 & (Reduce(`+`, 
    shift(hour, 1:5, fill = 1, type = "lead"))==0)), fill=0) 
    ][hour ==1, cs_acum1 := cumsum(hour) , grp 
     ][is.na(cs_acum1), cs_acum1 := 0][, grp := NULL][] 
#  hour cs cs_acum cs_wanted cs_acum1 
# 1: 1 1  1   1  1 
# 2: 1 1  2   2  2 
# 3: 1 1  3   3  3 
# 4: 0 0  0   0  0 
# 5: 0 0  0   0  0 
# 6: 1 0  0   4  4 
# 7: 1 0  0   5  5 
# 8: 0 0  0   0  0 
# 9: 0 0  0   0  0 
#10: 0 0  0   0  0 
#11: 0 0  0   0  0 
#12: 0 0  0   0  0 
#13: 0 0  0   0  0 
#14: 1 1  1   1  1 
#15: 1 1  2   2  2 
#16: 1 1  3   3  3 
#17: 0 0  0   0  0 

說明

試試這個我們轉換「data.frame '到'data.tabl e'(setDT(df1)),使用'hour'的lead值創建一個分組變量,以在OP的帖子中創建條件,指定'''按'grp'分組的'i'(hour==1),並指定cumsum'小時'作爲 'cs_acum1',改變NA元件ITO 0,最後刪除 '由分配給它的GRP' 至NULL

+3

我不明白這個重複的問題是如何鏈接的? –

+0

我設法在更廣泛的範圍內運行它,發現它並沒有給我我想要的東西。只有當它已經在'cs_acum'中啓動時,我才需要繼續積累。 –

+0

@m_c感謝您的更新。我看到另一個海報在每個更新中都努力工作。所以,我不想破壞他的努力:-) – akrun

6

使用:

library(data.table) 

rl <- rle(df1$hour) 

setDT(df1)[, grp := rleid(rep(rl$lengths >5 & rl$values == 0, rl$lengths)) 
      ][hour == 1, cs_acum2 := cumsum(hour), grp 
      ][is.na(cs_acum2), cs_acum2 := 0][] 

給出:

hour cs cs_acum cs_wanted grp cs_acum2 
1: 1 1  1   1 1  1 
2: 1 1  2   2 1  2 
3: 1 1  3   3 1  3 
4: 0 0  0   0 1  0 
5: 0 0  0   0 1  0 
6: 1 0  0   4 1  4 
7: 1 0  0   5 1  5 
8: 0 0  0   0 2  0 
9: 0 0  0   0 2  0 
10: 0 0  0   0 2  0 
11: 0 0  0   0 2  0 
12: 0 0  0   0 2  0 
13: 0 0  0   0 2  0 
14: 1 1  1   1 3  1 
15: 1 1  2   2 3  2 
16: 1 1  3   3 3  3 
17: 0 0  0   0 3  0 

說明:

  • 使用setDT(df1)將數據幀轉換爲數據表。
  • rl <- rle(d1$hour)grp := rleid(rep(rl$lengths >5 & rl$values == 0, rl$lengths))您創建了一個分組變量,只有當零個數超過5個時纔會更改。
  • 接下來你按hour == 1過濾,並創建一個獲得與cumsum(hour)累計總和。如果您的hour中的值僅爲10,您也可以使用seq_along1:.N創建一個計數器,它將給出相同的結果。
  • 最後,使用is.na(cs_acum2), cs_acum2 := 0將NA更改爲零。

更新1:對於新的示例數據(df2):

rl2 <- rle(df2$hour) 

setDT(df2)[, `:=` (rn = .I, grp = rleid(rep(rl2$lengths >5 & rl2$values == 0, rl2$lengths))) 
      ][hour == 1 & rn >= df2[, .I[cs == 1]][1], cs_acum2 := cumsum(hour), grp 
      ][is.na(cs_acum2), cs_acum2 := 0][, c('rn','grp') := NULL][] 

其給出:

hour cs cs_acum cs_wanted cs_acum2 
1: 0 0  0   0  0 
2: 1 0  0   0  0 
3: 1 0  0   0  0 
4: 1 0  0   0  0 
5: 0 0  0   0  0 
6: 1 1  1   1  1 
7: 1 1  2   2  2 
8: 1 1  3   3  3 
9: 0 0  0   0  0 
10: 0 0  0   0  0 
11: 1 0  0   4  4 
12: 1 0  0   5  5 
13: 0 0  0   0  0 
14: 0 0  0   0  0 
15: 0 0  0   0  0 
16: 0 0  0   0  0 
17: 0 0  0   0  0 
18: 0 0  0   0  0 
19: 1 1  1   1  1 
20: 1 1  2   2  2 
21: 1 1  3   3  3 
22: 0 0  0   0  0 

我理解它是該cumsum的方式hour只允許在第一次出現之後開始。

附加說明:

  • 隨着rn = .I您創造一個rowindexnumber。
  • df2[, .I[cs == 1]][1]給你的第一次cs == 1 rownumber。
  • With rn >= df2[, .I[cs == 1]][1]您只選擇從該點開始的行。

更新2:關於最新(第四)的數據集,你可以這樣做:

rl4 <- rle(df4$hour) 

setDT(df4)[, grp := rleid(rep(rl4$lengths >5 & rl4$values == 0, rl4$lengths))] 

i1 <- df4[, .I[cs == 1][1], grp][!is.na(V1)]$V1 
i2 <- df4[, .I[1:.N==5], rleid(cs)]$V1[-1] + 1 

df4[i1, cs.inc := 1 
    ][i2, cs.inc := -1 
     ][is.na(cs.inc), cs.inc := 0 
     ][, cs.inc := cumsum(cs.inc) 
      ][hour == 1 & cs.inc == 1, cs_acum3 := cumsum(hour), grp 
      ][is.na(cs_acum3), cs_acum3 := 0][, c('grp','cs.inc') := NULL][] 

這給:

hour cs cs_acum cs_wanted cs_acum2 cs_acum3 
1: 0 0  0   0  0  0 
2: 1 0  0   0  0  0 
3: 1 0  0   0  0  0 
4: 1 0  0   0  0  0 
5: 0 0  0   0  0  0 
6: 1 1  1   1  1  1 
7: 1 1  2   2  2  2 
8: 1 1  3   3  3  3 
9: 0 0  0   0  0  0 
10: 0 0  0   0  0  0 
11: 1 0  0   4  4  4 
12: 1 0  0   5  5  5 
13: 0 0  0   0  0  0 
14: 0 0  0   0  0  0 
15: 0 0  0   0  0  0 
16: 0 0  0   0  0  0 
17: 0 0  0   0  0  0 
18: 0 0  0   0  0  0 
19: 1 1  1   1  1  1 
20: 1 1  2   2  2  2 
21: 1 1  3   3  3  3 
22: 0 0  0   0  0  0 
23: 0 0  0   0  0  0 
24: 0 0  0   0  0  0 
25: 0 0  0   0  0  0 
26: 0 0  0   0  0  0 
27: 0 0  0   0  0  0 
28: 0 0  0   0  0  0 
29: 1 0  0   0  1  0 
30: 1 0  0   0  2  0 
31: 1 0  0   0  3  0 
32: 0 0  0   0  0  0 
33: 1 1  1   1  4  1 
34: 1 1  2   2  5  2 
35: 0 0  0   0  0  0 
36: 0 0  0   0  0  0 

使用數據

第一個例子數據集:

df1 <- structure(list(hour = c(1L, 1L, 1L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L), 
         cs = c(1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L), 
         cs_acum = c(1L, 2L, 3L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L), 
         cs_wanted = c(1L, 2L, 3L, 0L, 0L, 4L, 5L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L)), 
       .Names = c("hour", "cs", "cs_acum", "cs_wanted"), class = "data.frame", row.names = c(NA, -17L)) 

第二個數據集:

df2 <- structure(list(hour = c(0L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L), 
         cs = c(0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L), 
         cs_acum = c(0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L), 
         cs_wanted = c(0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 0L, 4L, 5L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L)), 
       .Names = c("hour", "cs", "cs_acum", "cs_wanted"), class = "data.frame", row.names = c(NA, -22L)) 

四集:

df4 <- structure(list(hour = c(0L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 1L, 1L, 0L, 0L), 
         cs = c(0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L), 
         cs_acum = c(0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 0L, 0L), 
         cs_wanted = c(0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 0L, 4L, 5L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 0L, 0L), 
         cs_acum2 = c(0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 0L, 4L, 5L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 0L, 4L, 5L, 0L, 0L)), 
       .Names = c("hour", "cs", "cs_acum", "cs_wanted", "cs_acum2"), class = "data.frame", row.names = c(NA, -36L)) 
+0

同樣的問題發生在這個數據集上,但看看第48行。 –

+0

看到修改的數據集,在第29行積累,運行你的代碼後 –

+0

恐怕再次,我們有同樣的問題。它不適用於其他數據集。非常感謝你的努力。 –