2015-06-29 10 views
11

Değişik şeylere göre ve siparişe göre (zaman) saymak istiyorum. Örneğin ile :R veri tablosu - Geçerli satırdan önce tüm satırları kullanan her satırın hesaplanması

Ben saymak isteyen
dt = data.table(id=c(1,1,1,2,2,2,3,3,3), hour=c(1,5,5,6,7,8,23,23,23), ip=c(1,1,45,2,2,2,3,1,1), target=c(1,0,0,1,1,1,1,1,0), day=c(1,1,1,1,1,1,3,2,1)) 

    id hour ip target day 
1: 1 1 1  1 1 
2: 1 5 1  0 1 
3: 1 5 45  0 1 
4: 2 6 2  1 1 
5: 2 7 2  1 1 
6: 2 8 2  1 1 
7: 3 23 3  1 3 
8: 3 23 1  1 2 
9: 3 23 1  0 1 

, her satır için her id, etkin gün sayısı ve aktif saat bugüne kadar için.

id hour ip target day nb_active_hours_so_far 
1: 1 1 1  1 1 0 (first occurence of id when ordered by hour) 
2: 1 5 1  0 1 1 (has been active in hour "1") 
3: 1 5 45  0 1 2 (has been active in hour "1" and "5") 
4: 2 6 2  1 1 0 (first occurence) 
5: 2 7 2  1 1 1 (has been active in hour "6") 
6: 2 8 2  1 1 2 (has been active in hour "6" and "7") 
7: 3 23 3  1 3 0 (first occurence) 
8: 3 23 1  1 2 1 (has been active in hour "23") 
9: 3 23 1  0 1 1 (has been active in hour "23" only) 

ben yapardım aktif saatlik toplam sayısını almak için:

dt[, nb_active_hours := length(unique(hour)), by=id] 

ama ben de bugüne kadar bölümünü istiyorum ben şu çıktıyı almak isteyen demektir . Bunu nasıl yapacağımı bilmiyorum ... Herhangi bir yardım mutluluk duyacaktır.

+0

Yani istemiyoruz (teşekkürler shift için @Frank için)? –

+2

'Etkin 'kısmı açık değil. – akrun

+0

Üzgünüz, sorun değil. Şimdiye kadar görülen benzersiz 'saat' değerlerinin sayısını saymak istiyorum (tüm satırlar için anlam, * geçerli satırın kullanılmaması *). – tucson

cevap

7

Bu (havn't farklı durumlarda üzerinde test gerçi)

dt[, nb_active_hours_so_far := cumsum(c(0:1, diff(hour[-.N]))>0), by = id] 
# id hour ip target day temp nb_active_hours_so_far 
# 1: 1 1 1  1 1 0      0 
# 2: 1 5 1  0 1 1      1 
# 3: 1 5 45  0 1 1      2 
# 4: 2 6 2  1 1 0      0 
# 5: 2 7 2  1 1 1      1 
# 6: 2 8 2  1 1 2      2 
# 7: 3 23 3  1 3 0      0 
# 8: 3 23 1  1 2 0      1 
# 9: 3 23 1  0 1 0      1 
+1

@akrun umut verici görünüyor, neden rleid'i düşünmediğimi merak ediyorum. Göndermelisin. –

+1

Teşekkürler, bunu ayrı bir çözüm olarak gönderdim. @Frank 'shift' versiyonunu aldım, umursamıyorsun umarım. – akrun

7

Yerk çalışmıyor gibi görünüyor olduğunu. yani v1.9.5,

library(data.table) 
dt[ ,nb_active_hours_so_far:=c(0,head(cumsum(c(1,diff(hour)>0)), -1)),id][] 

# id hour ip target day nb_active_hours_so_far 
#1: 1 1 1  1 1      0 
#2: 1 5 1  0 1      1 
#3: 1 5 45  0 1      2 
#4: 2 6 2  1 1      0 
#5: 2 7 2  1 1      1 
#6: 2 8 2  1 1      2 
#7: 3 23 3  1 3      0 
#8: 3 23 1  1 2      1 
#9: 3 23 1  0 1      1 
7

Yoksa data.table devel versiyonundan işlevlerin kullanılmasına rleid/shift yapabiliriz: Bu çirkin bir çözümüm var. Devel versiyonunu kurma talimatları here'dur. == 2` id `in 8``

library(data.table) 
dt[,nb_active_hours_so_far := shift(rleid(hour),fill=0L), id] 
# id hour ip target day nb_active_hours_so_far 
#1: 1 1 1  1 1      0 
#2: 1 5 1  0 1      1 
#3: 1 5 45  0 1      2 
#4: 2 6 2  1 1      0 
#5: 2 7 2  1 1      1 
#6: 2 8 2  1 1      2 
#7: 3 23 3  1 3      0 
#8: 3 23 1  1 2      1 
#9: 3 23 1  0 1      1 
+0

Eğer 'shift' basit bir' c' –

+0

@ DavidArenburg’dan daha iyi olursa, sanırım her ikisi de aynı performansa sahip olacaktı. – akrun

İlgili konular