2017-06-11 52 views
2

我有以下佈局的數據幀:行明智的操作R中有多個條件

id |conv |diff 
---- 
1 | 0 | 0 
1 | 0 | 3 
1 | 0 | 45 
1 | 1 | 9 
1 | 0 | 40 
1 | 1 |34 
1 | 0 | 43 
1 | 0 | 7 
2 | 0 | 0 
2 | 1 | 5 
2 | 0 |0 
2 | 1 |45 
2 | 1 |40 

我需要在這樣一個添加計數器的方式:

  1. 當ID改變或當前值爲conv = 1時,計數器應重置爲1
  2. 當id相同且差值小​​於10時,計數器應給出前面的計數器值。
  3. 當id相同且diff大於10時,計數器應加1。

我要找的輸出是:

id |conv |diff | counter 
---- 
1 | 0 | 0 | 1 
1 | 0 | 3 | 1 
1 | 0 | 45 | 2 
1 | 1 | 9 | 2 
1 | 0 | 40 | 1 
1 | 1 | 34 | 2 
1 | 0 | 43 | 1 
1 | 0 | 7 | 1 
2 | 0 | 0 | 1 
2 | 1 | 5 | 1 
2 | 0 | 0 | 1 
2 | 1 | 45 | 2 
2 | 1 | 40 | 1 

for循環的解決方案是:

for(i in 2:nrow(raw_data)){ 
    raw_data$counter[i]<- ifelse(raw_data$id[i]==raw_data$id[i-1] & conv==0, 
     ifelse(raw_data$diff> 10 & conv == 0,raw_data$counter[i-1] +1,raw_data$counter[i-1]) 
      ,1)} 

我知道時間的增加引起的 'for' 循環。尋找更快的方式。

回答

1

我們可以做

library(data.table) 
setDT(df1)[, counter := cumsum(c(TRUE, (diff > 10)[-1])), 
     by = .(id, grp = cumsum(shift(conv, fill = conv[1L])))] 
df1 
# id conv diff counter 
# 1: 1 0 0  1 
# 2: 1 0 3  1 
# 3: 1 0 45  2 
# 4: 1 1 9  2 
# 5: 1 0 40  1 
# 6: 1 1 34  2 
# 7: 1 0 43  1 
# 8: 1 0 7  1 
# 9: 2 0 0  1 
#10: 2 1 5  1 
#11: 2 0 0  1 
#12: 2 1 45  2 
#13: 2 1 40  1 
+0

感謝您的答覆。 '1L'代表什麼? –

+0

@AbhishekKumar它只是一個整數表示,即'class(1L)vs'class(1)' – akrun

+0

Ohk ...如果不是1作爲conv列中的標記,那麼會出現一個字符串'salecomplete' –